2016-12-03 1 views
0

A. Erstellen Sie eine VCL-Formularanwendung.Schlüsselhandling mit KeyPreview in TForm.OnKeyDown funktioniert nicht mit TListBox

B. Setzen Sie ein TListBox auf dem Formular und füllen Sie einige Elemente zur Entwurfszeit, zum Beispiel:

enter image description here

C. Stellen Sie die KeyPreview Formblatt Eigenschaft True:

enter image description here

D. Schreiben Sie im Ereignishandler des Formulars OnKeyDown diesen Code:

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. Führen Sie das Programm und wählen Sie Item5 durch Anklicken aus:

enter image description here

Jetzt hat ListBox1 den Fokus.

F. Drücken Sie nun die RÜCKTASTE. Angeblich sollte die Einstellung Key := 0; im Ereignishandler OnKeyDown des Formulars die BACKSPACE-Taste von der ListBox1-Steuerelement verarbeitet werden. Aber das funktioniert nicht, wie man sehen kann: die Rücktaste verursacht die Auswahl von Item5 zu element1 ändern:

enter image description here

So wie kann ich die RÜCK Schlüssel verhindern, in dem fokussierten Steuerelement List-Box verarbeitet und um die Auswahl der ListBox zu ändern?

Delphi 10.1 Berlin Update 2
Windows 7 x64 SP1

+0

Lesen Sie über WM_GETDLGCODE –

+1

@DavidHeffernan: Und welchen Wert würden Sie vorschlagen, von dieser Nachricht zurückzukehren? Es gibt kein Flag, das besagt, dass Rücktaste-Tastenanschläge ignoriert werden sollen. Denken Sie daran, die Flags "DLGC_WANTALLKEYS" und/oder "DLGC_WANTCHARS" zu deaktivieren oder das Flag "DLGC_WANTMESSAGE" zu aktivieren? Sie müssen genauer sein. –

+1

TranslateMessage wird vor DispatchMessage in der Nachrichtenschleife aufgerufen. Daher haben Sie nicht verhindert, dass WM_CHAR (das aus dem WM_KEYDOWN übersetzt wird) in das Listenfeld gestellt wird. Daher Remys Antwort .... –

Antwort

2

Verwenden Sie das OnKeyPress Ereignis statt:

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; 

Man kann nicht immer alles in OnKeyDown blockieren.

+0

Danke, es funktioniert. Aber das ist erstaunlich, da 'OnKeyDown' vor ** 'OnKeyPress' auftritt und ALTHOUGH 'Key' in' OnKeyDown' explizit auf Null gesetzt ist, wird das Ereignis 'OnKeyPress' noch aufgerufen! Ich war immer davon überzeugt, dass Tasten wie 'BACKSPACE' nicht' OnKeyPress' auslösen. – user1580348

+0

Normalerweise wird 'OnKeyPress' nicht aufgerufen, wenn' OnKeyDown' einen Schlüssel ablehnt. Beachten Sie, dass meine Antwort "OnKeyPress" ** anstelle von "OnKeyDown" und nicht "OnKeyDown" verwendet. In jedem Fall ist 'Key' in' OnKeyDown/Up' ein * virtueller Tastencode *, aber 'Key' in' OnKeyPress' ist ein * übersetztes Zeichen *, so dass sie nicht immer den gleichen Wert haben (in diesem Fall sie sind). –

+0

Seltsamerweise funktioniert das Blockieren der "HOME" -Taste und der "END" -Taste mit 'Key: = 0;' in 'OnKeyDown', und es wird kein' OnKeyPress'-Ereignis mit diesen Schlüsseln ausgelöst. Warum? Warum diese unterschiedliche Handhabung dieser Schlüssel? – user1580348

Verwandte Themen