DBGridのセルをクリックしたときのエベントで、
同時にCtrlキーが押されていれば 処理A
そうでなければ 処理B
のようにするにはどうしたらよいのでしょうか。
if (GetAsyncKeyState(VK_CONTROL) and $8000) <> 0 then begin
{処理A}
end else begin
{処理B}
end;
でしょうか。
ありがとうございました。
思った操作ができました。
ところで、「$8000」は、何のためのコードなのか教えていただけますでしょうか。
GetAsyncKeyStateを検索すれば、戻り値の意味は分かると思うけど。
同時押しの判定ならGetKeyStateの方がいいのではないでしょうか。
Asyncの方だと、クリックイベントがキューに入ったタイミングと
キーを判定するタイミングが同じではないため、処理が重くなった時など
「たまに一緒に押したつもりでも同時押しと判定されないことがある」
という微妙に操作性の悪いアプリケーションになる可能性があります。
そうでしょうか? 逆なのでは?
GetKeyState の MSDN の解説を読むと
スレッドがメッセージキューからキーメッセージを読み出すたびに、この関数が返すキーの状態は変化します。
キーの状態は、ハードウェアによる割り込みレベルの状態を反映しません。割り込みレベルの情報を取得する
には、GetAsyncKeyState 関数を使ってください。
と、あります。関数が呼ばれた時点で特定のキーが押されているかどうかを、メッセージに関係なく取得するには
GetKeyState より GetAsyncKeyState の方がよいと思います。
キーやマウスのイベントというのは一度キューに入って、それから処理されます。
たとえばディスクスワップなどが起こって処理が重くなると、
ボタンをクリックしてから少したってようやくボタンが反応したり、
たたいた文字が少し遅れて入力されたりすることとかよくありますよね。
このような場合、反応があるまでずっとボタンを押していなくてもちゃんと反応したり、
文字が抜け落ちたりせず正しく入力されるのは、メッセージがキューに入っているからです。
GetKeyStateだと「今処理しているメッセージがキューに入った時点」、つまりボタンをクリックした瞬間のキーの状態がとれます。
これに対してGetAsyncKeyStateだと、メッセージを処理している今この瞬間のキーの状態になります。
ボタンをクリックしてもすぐに反応がなくて、たとえば0.5秒ほどたってからようやく処理された場合
Asyncの方を使っていると「Ctrlキーと一緒にクリックしたつもりなのに、
普通にクリックしたかのように処理されてしまった」ということが起こりうるわけです。
キー入力にたとえれば「"Delphi" と入力したかったのに 2delPHi2 になってしまった」という感じです。
>GetKeyStateだと「今処理しているメッセージがキューに入った時点」、つまりボタンをクリックした瞬間のキーの状態がとれます。
なるほど。そうですね。納得しました。
逆に、ゲームやなにかでループでユーザのキー入力を監視しているような場合は、Async の方を使うべきなんですね。
ありがとうございました。
みなさんどうもありがとうございました。
プロクラムは解決、そして勉強になりました。
ツイート | ![]() |