2010-05-12 19 views
5

J'ai construit un contrôle personnalisé auquel j'essaye d'envoyer des données. Il acceptera l'entrée de la souris et signalera correctement MouseDown, MouseMove et MouseUp, mais pour une raison quelconque, il n'acceptera pas d'entrée au clavier. Quand je clique dessus, il ne reçoit pas le focus, et toutes les touches que j'appuie sont interprétées par n'importe quel contrôle qui avait déjà le focus.Pourquoi mon contrôle n'accepte-t-il pas l'entrée au clavier?

Ceci est probablement quelque chose de vraiment simple. Le premier endroit que je pensais regarder était dans la propriété ControlStyle, mais la seule chose que je peux voir dans le fichier d'aide à propos de l'entrée au clavier est csNoStdEvents, qui le désactive, et mon contrôle ne l'a pas. Alors, que dois-je faire pour que mon contrôle puisse recevoir le focus d'entrée?

+0

Pouvez-vous montrer du code? Je pense peut-être que vous avez hérité de TControl, pas TCustomControl ... (TControl n'est pas un TWinControl, n'a pas de handle de fenêtre et ne peut pas prendre le focus d'entrée - think: TLabel) –

+0

Il hérite de TCustomControl. –

Répondre

7

Quelques choses à essayer:

  • Sur MouseDown, appelez Windows.SetFocus(Handle). Dans mon expérience, la fonction WinAPI SetFocus fonctionne souvent mieux que la méthode SetFocus de la VCL.
  • En réponse au message WM_GETDLGCODE, répondez par Message.Result := Message.Result or DLGC_WANTCHARS or DLGC_WANTARROWS or DLGC_WANTTAB or DLGC_WANTALLKEYS;
+0

Merci. C'était soit accepter le vôtre, soit celui de Lars, parce que vous aviez tous deux la réponse à SetFocus dans MouseDown, et cela a fonctionné. J'ai choisi le vôtre en raison de la chose WM_GETDLGCODE, dont j'ai également eu besoin puisque j'ai besoin de piéger les touches fléchées spécifiquement. –

+0

N'est-ce pas suffisant de demander seulement 'DLGC_WANTALLKEYS'? –

+0

@David: Non, ce n'est pas le cas. –

0

La séquence de touches est-elle disponible au niveau du formulaire? En d'autres termes, KeyPreview est-il activé et pouvez-vous voir la séquence de touches dans l'événement OnKeypress du formulaire? Vous pouvez le suivre à partir de là dans le débogueur. Le contrôle (comme indiqué par Dan) est-il adapté à la saisie au clavier? Par exemple, un TLabel, bien qu'il affiche du texte, est un contrôle graphique.

1

J'ai vérifié le code pour mon contrôle et je ne vois rien qui pourrait arrêter ce fonctionnement. Appelez-vous "inherited" dans la procédure Create?

-je gérer ce qui suit, mais rien de spécial:

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

Avez-vous WS_TABSTOP ensemble? Vous n'avez pas d'objectif d'entrée sans cela, je crois. Mais ceci est basé sur un souvenir d'il y a près de 10 ans, lorsque j'écrivais mon propre éditeur de code syntaxique, dont j'ai depuis longtemps perdu la source.

{TWinControl.}TabStop := True; devrait faire. Une application de test rapide avec un composant «do-nothing» dérivé de TWinControl et affichant une boîte de dialogue pour les événements clés semble montrer que cela fait toute la différence.

+0

Juste essayé cela, et cela ne semble rien changer. Je n'arrive toujours pas à me concentrer sur le clavier. –

4

Se pourrait-il que ce soit aussi simple que d'appeler SetFocus avec la souris?

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

    if CanFocus then 
    SetFocus; 
end; 
+0

Je crois fermement que c'est le problème. –