我希望我的表單處理箭頭鍵,我可以這樣做 - 只要表單上沒有按鈕。爲什麼是這樣?Delphi XE和陷印箭頭鍵與OnKeyDown
回答
箭頭鍵用於在窗體上的按鈕之間導航。這是標準的Windows行爲。雖然您可以禁用此標準行爲,但在與平臺標準相違背之前,您應該考慮三次。箭頭鍵用於導航。
如果您想充分了解按鍵在消息循環中的位置,我建議您閱讀A Key's Odyssey。如果您想在成爲導航鍵之前攔截按鍵,則需要在IsKeyMsg
或更早版本中進行。例如,Sertac的answer給出了這樣一種可能性。
彼得下面(該密鑰的奧德賽的作者)是一個重要的德爾福社區人員(TeamB),也是一個偉大的JVCL貢獻者。好文章。 – 2011-12-24 20:37:54
因爲他們被搶先處理將重點放在下一個可用的WinControl上。
(我敢肯定,如果你把一個編輯而不是一個按鈕,你會看到同樣的東西)。
如果你想自己處理它們,你可以給應用程序提供一個OnMessage事件,它將在它們被處理之前對它們進行過濾,並在那裏自己處理它們。
關鍵消息由接收這些消息的控件自己處理,這就是爲什麼當您在按鈕上時表單沒有收到消息。因此,一般來說,你將不得不繼承這些控件,但VCL是一種足以讓育兒形式做什麼,如果形式感興趣:
type
TForm1 = class(TForm)
..
private
procedure DialogKey(var Msg: TWMKey); message CM_DIALOGKEY;
..
procedure TForm1.DialogKey(var Msg: TWMKey);
begin
if not (Msg.CharCode in [VK_DOWN, VK_UP, VK_RIGHT, VK_LEFT]) then
inherited;
end;
弗朗索瓦編輯:回答OP原來的問題,你需要以某種方式調用onKeyDown,以便他的事件代碼可以工作(隨意編輯;評論太長)。
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
private
{ Private declarations }
procedure DialogKey(var Msg: TWMKey); message CM_DIALOGKEY;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.DialogKey(var Msg: TWMKey);
begin
case Msg.CharCode of
VK_DOWN, VK_UP, VK_RIGHT, VK_LEFT:
if Assigned(onKeyDown) then
onKeyDown(Self, Msg.CharCode, KeyDataToShiftState(Msg.KeyData));
else
inherited
end;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
case Key of
VK_DOWN: Top := Top + 5;
VK_UP: Top := Top - 5;
VK_LEFT: Left := Left - 5;
VK_RIGHT: Left := Left + 5;
end;
end;
我想你需要更多的解釋來說明一下'CM_DIALOGKEY'的特殊之處。這當然是改變行爲的狡猾方式。隨意與我的答案重疊,我會刪除它,因爲這個代碼的全面答案勝過我所做的。 – 2011-12-23 22:06:37
@大衛 - 恐怕你將無法刪除你的帖子:)。關於CM_DIALOGKEY我沒有太多的解釋,這是一個VCL組成的消息,用於廣播關鍵消息。這是我的幫助文件所說的:*「這是常數Controls.CM_DIALOGKEY」* :)。更新:[文檔](http://docwiki.embarcadero.com/VCL/2010/en/Controls.CM_DIALOGKEY)已得到改進:*「CM_DIALOGKEY表示控制消息,由VCL框架在內部使用。」* – 2011-12-23 22:16:13
嗯,我認爲這聽起來好像與「TApplication.IsDlgMsg」有關。事實上,'TApplication.IsDlgMsg'在這裏甚至是相關的,或者VCL是否處理這些導航鍵而不是Windows對話框? – 2011-12-23 22:24:38
只有具有焦點的對象才能接收鍵盤事件。
爲了讓表單有權訪問箭頭鍵事件, 在表單的公共部分聲明MsgHandler
。 在表單create構造函數中,將Application.OnMessage
指定給此MsgHandler。
下面的代碼僅在它們來自TButton後代時攔截箭頭鍵。可以根據需要添加更多控件。
procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMessage := Self.MsgHandler;
end;
procedure TForm1.MsgHandler(var Msg: TMsg; var Handled: Boolean);
var
ActiveControl: TWinControl;
key : word;
begin
if (Msg.message = WM_KEYDOWN) then
begin
ActiveControl := Screen.ActiveControl;
// if the active control inherits from TButton, intercept the key.
// add other controls as fit your needs
if not ActiveControl.InheritsFrom(TButton)
then Exit;
key := Msg.wParam;
Handled := true;
case Key of // intercept the wanted keys
VK_DOWN : ; // doStuff
VK_UP : ; // doStuff
VK_LEFT : ; // doStuff
VK_RIGHT : ; // doStuff
else Handled := false;
end;
end;
end;
var
KBHook: HHook; {this intercepts keyboard input}
implementation
{$R *.dfm}
function KeyboardHookProc(Code: Integer; WordParam: Word; LongParam: LongInt): LongInt; stdcall;
begin
case WordParam of
vk_Space: ShowMessage ('space') ;
vk_Right:ShowMessage ('rgt') ;
vk_Left:ShowMessage ('lft') ;
vk_Up: ShowMessage ('up') ;
vk_Down: ShowMessage ('down') ;
end; {case}
end;
procedure TForm4.FormCreate(Sender: TObject);
begin
KBHook:=SetWindowsHookEx(WH_KEYBOARD,@KeyboardHookProc,HInstance,GetCurrentThreadId());
end;
此代碼將工作,即使控制的重點是(按鈕,列表框),所以要小心一些控制可能會失去他們的鍵盤事件(閱讀David haffernans答案)。
與聚焦控制
鍵盤事件例如:如果你在你的應用程序的文本框,並希望recive文本(如果聚焦)也,然後
添加applicationevent1
procedure TForm4.ApplicationEvents1Message(var Msg: tagMSG;var Handled: Boolean);
begin
if Msg.message = WM_KEYFIRST then
KBHook:=SetWindowsHookEx(WH_KEYBOARD,@KeyboardHookProc,HInstance,GetCurrentThreadId());
end;
在function KeyboardHookProc
的底部添加以下代碼
UnhookWindowsHookEx(KBHook);
,並從OnCreate事件刪除
KBHook:=SetWindowsHookEx(WH_KEYBOARD,@KeyboardHookProc, HInstance,
GetCurrentThreadId());
。
- 1. Firebird和Delphi XE
- 2. C#和箭頭鍵
- 3. Jedi Library和Delphi XE
- 4. Delphi XE和Winrunner(QTP)
- 5. 在DLL中傳遞箭頭和Tab鍵到Delphi窗體
- 6. WPF FocusNavigationDirection,MoveFocus和箭頭鍵
- 7. 箭頭鍵與JQuery的鍵盤導航
- 8. 分頁與按鍵時(右箭頭鍵)
- 9. 箭頭鍵
- 10. shift +箭頭鍵
- 11. Rad Studio Delphi XE和PostgreSQL
- 12. input()::使用退格鍵和箭頭鍵
- 13. Delphi XE Jedi 3.45
- 14. Delphi XE + SOAP + SSL
- 15. Delphi XE圖標
- 16. 如何與我有麻煩我的烏龜能跟隨箭頭鍵箭頭鍵
- 17. 捕獲箭頭鍵
- 18. 8向圖動畫與箭頭鍵
- 19. PictureBox選擇switchnig與箭頭鍵
- 20. 與jQuery一起使用箭頭鍵scrollTo
- 21. 如何處理delphi自定義組件中的箭頭鍵?
- 22. c#Listbox控件(箭頭和輸入鍵)
- 23. C#重點形式和箭頭鍵
- 24. 同時使用WASD和箭頭鍵
- 25. (Python3)Linux和Windows箭頭鍵按下
- 26. python外殼,箭頭鍵和anaconda環境
- 27. 與箭頭式的
- 28. 用於箭頭鍵的unicode?
- 29. jQuery的箭頭鍵導航
- 30. 用箭頭鍵移動JFrame?
偉大的問題。深入挖掘像這樣的事物的複雜性,將專家與遊客分開。保持! – 2011-12-24 20:40:47