2016-12-03 1 views
0

A. Créez une application Fiches VCL.La gestion des clés avec KeyPreview dans TForm.OnKeyDown ne fonctionne pas avec TListBox

B. Mettez un TListBox sur la forme et remplir quelques articles à temps de conception, par exemple:

enter image description here

C. Définir la propriété KeyPreview de formulaire à True:

enter image description here

D. Dans le gestionnaire d'événements OnKeyDown du formulaire, écrivez le code suivant:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 
begin 
    if Key = VK_BACK then 
    begin 
    if ListBox1.Focused then 
    begin 
     Key := 0; 
     CodeSite.Send('ListBox1 is focused!'); 
    end; 
    end; 
end; 

E. Exécutez le programme et sélectionnez item5 en cliquant dessus:

enter image description here

Maintenant ListBox1 a le focus.

F. Appuyez maintenant sur la touche RETOUR ARRIÈRE. Supposément, définissant Key := 0; dans le gestionnaire d'événements OnKeyDown du formulaire doit empêcher la clé BACKSPACE d'être traitée par le contrôle ListBox1. Mais cela ne fonctionne pas, comme vous pouvez le voir: la touche Retour arrière fait pour changer la sélection de item5 à Item1:

enter image description here

Alors, comment puis-je empêcher BACKSPACE d'être traitées dans le contrôle ListBox ciblé et changer la sélection de la ListBox?

Delphi 10.1 Update Berlin 2
Windows 7 x64 SP1

+0

En savoir plus sur WM_GETDLGCODE –

+1

@DavidHeffernan: Et quelle valeur proposeriez-vous de renvoyer de ce message? Il n'y a pas de drapeau qui dit d'ignorer les frappes de retour arrière. Envisagez-vous de désactiver les drapeaux 'DLGC_WANTALLKEYS' et/ou' DLGC_WANTCHARS' ou d'activer le drapeau 'DLGC_WANTMESSAGE'? Vous allez devoir être plus précis. –

+1

TranslateMessage est appelé avant DispatchMessage dans la boucle de message, par conséquent vous n'avez pas empêché WM_CHAR (qui est traduit de WM_KEYDOWN) d'être publié dans la zone de liste. D'où la réponse de Remy .... –

Répondre

2

Utilisez le événement OnKeyPress à la place:

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char); 
begin 
    if Key = #8 then 
    begin 
    if ListBox1.Focused then 
    begin 
     Key := #0; 
     CodeSite.Send('ListBox1 is focused!'); 
    end; 
    end; 
end; 

Vous ne pouvez pas toujours bloquer tout OnKeyDown.

+0

Merci, ça marche. Mais c'est incroyable, car 'OnKeyDown' se produit ** BEFORE **' OnKeyPress', et bien que 'Key' soit explicitement mis à zéro dans' OnKeyDown', l'événement 'OnKeyPress' est toujours appelé! J'ai toujours été convaincu que les touches comme BACKSPACE ne déclenchent pas OnKeyPress. – user1580348

+0

Normalement 'OnKeyPress' n'est pas appelé si' OnKeyDown' rejette une clé. Notez ma réponse a dit d'utiliser 'OnKeyPress' ** au lieu de **' OnKeyDown', pas avec elle. En tout cas, 'Key' dans' OnKeyDown/Up' est un * code de clé virtuelle *, mais 'Key' dans' OnKeyPress' est un * caractère * traduit, donc ils ne sont pas toujours la même valeur (dans ce cas, ils sont). –

+0

Etrangement, le fait de bloquer la touche 'HOME' et la touche' END' avec 'Key: = 0;' dans 'OnKeyDown' FONCTIONNE et aucun événement' OnKeyPress' n'est déclenché avec ces touches. Pourquoi? Pourquoi cette manipulation différente de ces clés? – user1580348