フォームに矢印キーを処理するようにしたいのですが、フォームにボタンがない限り、できます。どうしてこれなの?Delphi XEとトラップ矢印キー(OnKeyDownを使用)
答えて
矢印キーは、フォーム上のボタン間を移動するために使用します。これは標準的なWindowsの動作です。この標準的な動作を無効にすることはできますが、プラットフォームの標準に逆行する前に2度考える必要があります。矢印キーはナビゲーションのためのものです。
キー・プレスがメッセージ・ループをどのように見つけているかを完全に把握したい場合は、A Key's Odysseyを読むことをお勧めします。ナビゲーションキーになる前にキープレスを傍受したい場合は、IsKeyMsg
またはそれ以前のバージョンで行う必要があります。例えば、Sertacのanswerはそのような可能性を与えます。
Peter Below(そのKey's Odysseyの著者)は、Delphiの重要なコミュニティの男(TeamB)であり、JVCLの偉大な貢献者です。素敵な記事。 –
次の使用可能な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'について特別なことについてもう少し説明が必要だと思います。これは確かに行動を変えるための滑らかな方法です。私の答えと重なり合うように自由に感じてください。このコードを使った包括的な答えが私がやったことに勝つので、私はそれを削除します。 –
@David - あなたの投稿を削除することはできません。私がCM_DIALOGKEYについて説明することはあまりありません。主要なメッセージをブロードキャストするために使用されるVCLメッセージです。これは、私のヘルプファイルが言っていることです:* "これは一定のControls.CM_DIALOGKEY" * :)です。アップデート:[documentation](http://docwiki.embarcadero.com/VCL/2010/en/Controls.CM_DIALOGKEY)が改善されました:* "CM_DIALOGKEYはコントロールメッセージを表し、VCLフレームワークで内部的に使用されます" * –
うーん、私はTApplication.IsDlgMsgに関連しているように聞こえたと思った。実際、ここではTApplication.IsDlgMsgも関連していますか、VCLはWindowsのダイアログではなくこれらのナビゲーションキーを処理していますか? –
フォーカスのあるオブジェクトだけがキーボードイベントを受け取ることができます。
フォームが矢印キーイベントにアクセスできるようにするには、 はフォームのパブリック部分にMsgHandler
と宣言します。 フォーム作成コンストラクタで、Application.OnMessage
をこのMsgHandlerに割り当てます。
以下のコードは、矢印キーの子孫からのものである場合にのみ、矢印キーを傍受します。必要に応じて、より多くのコントロールを追加することができます。
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;
このコードは、コントロールが(ボタン、リストボックス)に重点を置いている場合でも動作しますので、いくつかのコントロールが自分のキーボードイベントを(デビッドhaffernans答えを読む)ゆるくなることに注意してください。集束コントロール
と
キーボードイベントなど:あなたのアプリでテキストボックスを持つと(集中している場合)も、その後、
がapplicationevent1を追加したテキストをreciveしたい場合
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);
012の下に次のコードを追加します とOnCreateのイベントから
KBHook:=SetWindowsHookEx(WH_KEYBOARD,@KeyboardHookProc, HInstance,
GetCurrentThreadId());
を削除します。
- 1. C#と矢印キー
- 2. Delphi XEとWinsock
- 3. 矢印キーを使用したAngular2ナビゲーション
- 4. JScrollPane矢印キーを使用したスクロール
- 5. JComboBoxのヌルIn矢印キーの使用
- 6. Delphi XE 2でTurbopower XMLパートナーを使用
- 7. Eclipseの右矢印キーと左矢印キーを使用してツリーノードを展開します。
- 8. Selectizeで右矢印キーと左矢印キーを有効にする方法
- 9. ページネーション(右矢印キー)
- 10. 矢印キーでナビゲートサムネイルギャラリー
- 11. 矢印キーのユニコード?
- 12. SpriteKitの矢印キー
- 13. AIX - デフォルトシェル - 矢印キー
- 14. アングルでキーアップを使用して矢印キーを使用する
- 15. Delphi XEの 'VarToStr'?
- 16. Delphi XEのテーマアプリケーション
- 17. Delphi XE Reportman
- 18. BDE with Delphi XE
- 19. Delphi、ショートカットを使用しないTActionToolBar(Delphi XE)
- 20. リマップ矢印キーをvimの
- 21. マウスホイールと矢印キーで `wx.ScrolledPanel`をスクロール
- 22. Delphi 2010-XEのTWordApplication
- 23. DELPHI XE wpf like GUI
- 24. WPF移動矢印キー
- 25. のVim - キー右矢印
- 26. OS Xの矢印キー
- 27. Autohotkey:矢印キーの再マップ
- 28. 矢印キー付きAngular2スクロールドロップダウンメニュー
- 29. Javascript:Keydownイベント:矢印キーのキーダウンイベントを防ぐ「上向き」矢印キー? (回答:キーボードゴースト)
- 30. フォームと矢印キーのC#フォーカス
大きな質問です。このようなものの根本的な複雑さを掘り起こすことは、観光客と専門家を分けるものです。がんばり続ける! –