2011-11-10 9 views
8

Estoy usando una herramienta de traducción propia. (La próxima vez usaré una de las bibliotecas, como se describe aquí: delphi translation tool.)Haga clic con el mouse en cualquier componente VCL y determine su valor .Tag

Mis traductores se quejan de que traducir una larga lista de cadenas es difícil porque no las ven en contexto (en la pantalla en la que aparecen.)

Un traductor hizo una gran sugerencia de que debería poder hacer clic en un componente para cambiar su texto. Puedo implementar esto si puedo encontrar una forma de enlazar todo el programa, un evento para que cuando un usuario haga clic en un componente mientras mantiene presionada la tecla CTRL, se llame a un controlador de eventos. El controlador de eventos determinará si el componente tiene una propiedad .Caption y, de ser así, obtendrá el valor del componente Tag (y luego permitirá la entrada de algún usuario).

(Cada componente traducible tiene un entero único en su etiqueta correctamente, que utilizo para buscar el componente .Caption)

¿Alguna sugerencia sobre cómo hacerlo? Está por encima de mi cabeza. Necesito algo así como KeyPreview de un formulario, pero para los clics del mouse que averiguarían en qué componente de VCL se hizo clic y determinar su valor .Tag.

Tom

EDIT:

El uso de la sugerencia de David H., los únicos eventos que recibo son cuando la aplicación obtiene el enfoque o la pierde. ¿Qué he hecho mal?

function TForm1.AppHookFunc(var Message : TMessage) : Boolean; 
    begin 
     Result := FALSE; 
     inc(i); outputdebugstring(Pchar(inttostr(i) + ': ' + IntTostr(Message.msg))); 
     if Message.Msg = WM_MBUTTONDOWN then 
     begin  Beep; 
     //...DoSomething... 
     //Result := True; 
     end; 
    end; 

    procedure TForm1.FormCreate( Sender: TObject); 
    begin 
     Application.HookMainWindow(AppHookFunc); 
    end; 

    procedure TForm1.FormDestroy(
     Sender: TObject); 
    begin 
     Application.UnHookMainWindow(AppHookFunc); 
    end; 

EDIT 2

casi estoy allí! Pero FindDragTarget rara vez devuelve nada más que nada. Si hago un botón enorme que cubre la mayor parte del control, a veces puedo hacer que funcione. Las coordenadas X, Y en tagMSG recibidas son relativas al control. Hubiera pensado que tenían relación con el formulario. ¿Todavía utilizo un gancho de evento diferente del que debería? Cualquier sugerencia:

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; 
               var Handled: Boolean); 
    var 
    Target: TControl; 
    Point: TPoint; 
    begin 
    Handled := FALSE; 
    if (Msg.Message = WM_LBUTTONDOWN) And isAltDown then 
     begin 
     Point.X := LongRec(Msg.lParam).Lo; 
     Point.Y := LongRec(Msg.lParam).Hi; 
     Target := FindDragTarget(Point, {AllowDisabled=}TRUE); 
     if Assigned(Target) then 
      begin 
      if Target Is TButton then 
       outputdebugString(Pchar(TButton(Target).Caption)); 
      end 
     else 
      outputdebugstring(Pchar(IntToStr(Point.X) + ', ' + IntToStr(Point.Y))); 
     end; 
    end; 

edición final:

me cambiaron el código anterior para usar en lugar de GetCursorPos Msg.lParam. Está funcionando ahora. ¡Muy genial! SO Rocks!

¡MUCHAS GRACIAS POR SU AYUDA!

+0

Si le basta realizar las traducciones para los descendientes 'TWinControl', puede intentar usar [WindowFromPoint] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633558% 28v = vs.85% 29.aspx) función para determinar qué control se encuentra debajo del mouse y obtener/establecer su texto por 'WM_GETTEXT' y' WM_SETTEXT' desde fuera de su aplicación. – TLama

+0

No enganche la ventana principal. Asignar aplicación.enMensaje. O use TApplicationEvents. –

Respuesta

9

Supongo que es una aplicación de VCL. Para FireMonkey esto no funcionaría.

  1. Agregue un controlador de evento Application.OnMessage.
  2. En el controlador de eventos, busque WM_LBUTTONDOWN o quizás WM_LBUTTONUP y compruebe que el estado de la tecla modificadora sea el que desee, p. CTRL está abajo.
  3. Llama al FindDragTarget pasando la posición asociada con el evento del mouse. Esto le dará el control con el mouse, si es que hay uno (es decir, verifique nil).
  4. Haga lo que sea que desee para ese control.
+7

El soporte de controles que no sean TWinControl es muy fácil, no es necesario cambiar a 'TStaticText'. Use 'FindDragTarget()' en lugar de 'FindVCLWindow()'. 'FindDragTarget()' llama 'FindVCLWindow()' internamente y luego, si se encuentra, llama al método 'ControlAtPos()' de ese control para buscar un elemento secundario que no sea TWinControl. –

+0

@remy gracias. Estoy un poco indispuesto en este momento. Estaría encantado de que agregue esa información como una edición o incluso como una respuesta separada. –

+0

@remy He quedado eliminado una vez más y actualicé la pregunta. Gracias por enseñarme algo que no sabía. De nuevo. ¡Me gusta tanto! –

Cuestiones relacionadas