2010-05-12 17 views
5

He creado un control personalizado al que estoy tratando de enviar entradas. Aceptará la entrada del mouse e informará MouseDown, MouseMove y MouseUp correctamente, pero por cualquier razón, no aceptará la entrada del teclado. Cuando hago clic en él, no recibe el foco, y las teclas que presiono se interpretan por el control que ya tenía el foco.¿Por qué mi control no acepta la entrada del teclado?

Esto es probablemente algo realmente simple. El primer lugar que pensé que debía buscar era en la propiedad ControlStyle, pero lo único que puedo ver en el archivo de ayuda sobre la entrada del teclado es csNoStdEvents, que lo desactiva, y mi control no tiene eso. Entonces, ¿qué debo hacer para que mi control pueda recibir el foco de entrada?

+0

¿Puede mostrar el código? Estoy pensando que tal vez heredó de TControl, no de TCustomControl ... (TControl no es un TWinControl, no tiene un identificador de ventana y no puede tomar el foco de entrada - piense: TLabel) –

+0

Hereda de TCustomControl. –

Respuesta

7

Algunas cosas para probar:

  • En MouseDown, llame Windows.SetFocus(Handle). En mi experiencia, la función WinAPI SetFocus a menudo funciona mejor que el método SetFocus de la VCL.
  • En respuesta al mensaje WM_GETDLGCODE, responda con Message.Result := Message.Result or DLGC_WANTCHARS or DLGC_WANTARROWS or DLGC_WANTTAB or DLGC_WANTALLKEYS;
+0

Gracias. O bien aceptaste el tuyo o el de Lars, porque ambos tenían la respuesta para poner SetFocus dentro de MouseDown, y eso funcionó. Escogí el suyo por WM_GETDLGCODE, que también terminé necesitando porque necesito atrapar las teclas de flecha específicamente. –

+0

¿No es suficiente pedir simplemente 'DLGC_WANTALLKEYS'? –

+0

@David: No, no lo es. –

0

¿La pulsación de tecla está disponible a nivel de formulario? Es decir, ¿está activado KeyPreview y puede ver la pulsación de tecla en el evento OnKeypress del formulario? Puedes seguirlo desde allí en el depurador. ¿El control (como indica Dan) es adecuado para la entrada de teclado? Por ejemplo, un TLabel, aunque muestra texto, es un control gráfico.

1

He comprobado el código de mi control y no puedo ver nada que pueda detener el funcionamiento. ¿Estás llamando "heredado" en el procedimiento Create?

hago manejar la siguiente, pero nada especial:

procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS; 
procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS; 
procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE; 

procedure KeyDown(var Key: Word; Shift: TShiftState); override; 
2

¿Tiene WS_TABSTOP conjunto? Usted no tiene un enfoque de entrada sin eso, creo. Pero esto se basa en un recuerdo de hace casi 10 años, cuando estaba escribiendo mi propio editor de código de resaltado de sintaxis, para el cual hace tiempo que perdí la fuente.

{TWinControl.}TabStop := True; debe hacer. Una aplicación de prueba rápida con un componente "no hacer nada" derivado de TWinControl y que muestra un cuadro de diálogo para eventos clave parece mostrar que marca la diferencia.

+0

Acabo de probar eso, y no parece cambiar nada. Todavía no puedo enfocar el teclado. –

4

¿Podría ser tan simple como llamar a SetFocus con el mouse hacia abajo?

procedure TYourCustomControl.MouseDown(Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer); 
begin 
    inherited; 

    if CanFocus then 
    SetFocus; 
end; 
+0

Creo firmemente que este es el problema. –

Cuestiones relacionadas