OnKeyPress
ユーザーがキーを押したときにイベントを受け取りたいTab。
procedure TForm1.Edit1(Sender: TObject; var Key: Char);
begin
case Key of
#09:
begin
//Snip - Stuff i want to do
end;
end;
end;
Edit
ボックスのサブクラス化を試み、WM_GETDLGCODE
メッセージを処理します。
procedure TfrmEnableVIPMode.AccountNumberWindowProc(var Message: TMessage);
begin
case Message.Msg of
WM_GETDLGCODE: Message.Result := DLGC_WANTTAB;
else
FOldAccountNumberWindowProc(Message);
end;
end;
Tab そして、 KeyPressイベントを受け取るようになりましたが(希望どおり)、LeftまたはRightカーソルキーを押すと、フォーカスがタブオーダーの前または次のコントロールに移動します。
Tab Key Pressイベントを受け取る正しい方法は何ですか?
ボーナスリーディング
私はMSDNのドキュメントが言うことをやってみました:
wParam
ユーザーが押した仮想キーで、Windows にこの通知を発行するよう促したものです。ハンドラーは、これらのキーを選択的に処理する必要があります。たとえば、ハンドラーは VK_RETURN を受け入れて処理しますが、VK_TAB はオーナー ウィンドウに委譲します。値のリストについては、Virtual-Key Codes を参照してください。lParam MSG 構造体 (システムがクエリを実行している場合は NULL) へのポインター。
しかしwParam
、 とwParam
はどちらもゼロです。
アップデート 2
この回答と同じバグがあることに気付きました:
if Message.Msg = WM_GETDLGCODE then
Message.Result:= Message.Result or DLGC_WANTTAB
else
if Assigned(FOldWndProc) then FOldWndProc(Message);
同じ回答の他の場所にリストされている正しいコードの概念を実際に使用する必要がある場合:
if Assigned(FOldWndProc) then FOldWndProc(Message);
if Message.Msg = WM_GETDLGCODE then
Message.Result:= Message.Result or DLGC_WANTTAB;
これは、元のコードが間違っている理由を説明するのに役立ちます。Message.Result
への設定DLGC_WANTTAB
が間違っています:
procedure TfrmEnableVIPMode.AccountNumberWindowProc(var Message: TMessage);
begin
case Message.Msg of
WM_GETDLGCODE: Message.Result := DLGC_WANTTAB;
else
FOldAccountNumberWindowProc(Message);
end;
end;
にはまだ値がないためbitwise or
、フラグDLGC_WANTTAB
をにしようとするのも間違っています。Message.Result
Message.Result
procedure TfrmEnableVIPMode.AccountNumberWindowProc(var Message: TMessage);
begin
case Message.Msg of
WM_GETDLGCODE: Message.Result := Message.Result or DLGC_WANTTAB;
else
FOldAccountNumberWindowProc(Message);
end;
end;
EDIT
Windows のコントロール セットの正しい値を取得するには、最初に元のウィンドウ プロシージャを呼び出す必要がありますMessage.Result
。次に、ビットごとに組み合わせることができますDLGC_WANTTAB
:
procedure TfrmEnableVIPMode.AccountNumberWindowProc(var Message: TMessage);
begin
FOldAccountNumberWindowProc(Message);
case Message.Msg of
WM_GETDLGCODE: Message.Result := Message.Result or DLGC_WANTTAB;
end;
end;
Raymond Chen のブログ エントリを言い換えると、必要に応じて強調が追加されます。
元のコントロールに必要な動作を尋ねた後、DLGC_WANTTAB フラグをオンにします。
だから、これは良いです。カーソル キーは、(フォーカスを移動するのではなく) エディット コントロール内のテキストをナビゲートし続け、キーのOnKeyPress
(およびOnKeyDown
およびOnKeyUp
) イベントを受け取りTabます。
残りの問題は、ユーザーが押してTabもフォーカスが移動しないことです。
私は自分自身を変更するフォーカスで手動でハッキングを開始しようとしました:
procedure TfrmEnableVIPMode.edAccountNumberKeyPress(Sender: TObject; var Key: Char);
begin
case Key of
#09:
begin
//Snip - Stuff i want to do
{
The DLGC_WANTTAB technique broke Windows focus change.
Keep throwing in hacks until it's no longer obviously broken
}
//Perform(CM_DialogKey, VK_TAB, 0); //doesn't work
Self.ActiveControl := Self.FindNextControl(edAccountNumber, True, True, False);
end;
end;
end;
上記のコードは機能します - ユーザーがTabキーを押した場合。しかし、Raymond Chen が 6 年前に指摘したように、コードは壊れています。
このアプローチには多くの問題があります。このコードがダイアログ ボックスに適切にフォーカスを設定できない方法、ネストされたダイアログを考慮に入れていない方法、Shift+Tab ナビゲーション キーの処理に失敗した方法など、細かい部分を掘り下げるのにかなりの時間を費やすことができます。
私の場合、私はShift+を壊しTabました。そして、誰が他に何を知っていますか。
だから、私の質問:
エディットボックスでTABキー押下を受け取るには?
私はそれらを食べたくありません。ユーザーがキーを押したことを知りTabたいだけです。