DBGridのクリックをCtrltが押されているかどうかで変更したい

解決


久美子  2009-03-03 21:30:46  No: 33536  IP: 192.*.*.*

DBGridのセルをクリックしたときのエベントで、
同時にCtrlキーが押されていれば  処理A 
そうでなければ 処理B
のようにするにはどうしたらよいのでしょうか。

編集 削除
New Monkey  2009-03-04 21:40:50  No: 33537  IP: 192.*.*.*

if (GetAsyncKeyState(VK_CONTROL) and $8000) <> 0 then begin
  {処理A}
end else begin
  {処理B}
end;

でしょうか。

編集 削除
久美子  2009-03-05 04:44:26  No: 33538  IP: 192.*.*.*

ありがとうございました。
思った操作ができました。
ところで、「$8000」は、何のためのコードなのか教えていただけますでしょうか。

編集 削除
それは  2009-03-05 09:17:53  No: 33539  IP: 192.*.*.*

GetAsyncKeyStateを検索すれば、戻り値の意味は分かると思うけど。

編集 削除
ついでに  2009-03-06 01:26:04  No: 33540  IP: 192.*.*.*

同時押しの判定ならGetKeyStateの方がいいのではないでしょうか。
Asyncの方だと、クリックイベントがキューに入ったタイミングと
キーを判定するタイミングが同じではないため、処理が重くなった時など
「たまに一緒に押したつもりでも同時押しと判定されないことがある」
という微妙に操作性の悪いアプリケーションになる可能性があります。

編集 削除
うんと  2009-03-06 11:35:29  No: 33541  IP: 192.*.*.*

そうでしょうか? 逆なのでは?

GetKeyState の MSDN の解説を読むと

スレッドがメッセージキューからキーメッセージを読み出すたびに、この関数が返すキーの状態は変化します。
キーの状態は、ハードウェアによる割り込みレベルの状態を反映しません。割り込みレベルの情報を取得する
には、GetAsyncKeyState 関数を使ってください。

と、あります。関数が呼ばれた時点で特定のキーが押されているかどうかを、メッセージに関係なく取得するには
GetKeyState より GetAsyncKeyState の方がよいと思います。

編集 削除
えーと  2009-03-06 15:45:39  No: 33542  IP: 192.*.*.*

キーやマウスのイベントというのは一度キューに入って、それから処理されます。
たとえばディスクスワップなどが起こって処理が重くなると、
ボタンをクリックしてから少したってようやくボタンが反応したり、
たたいた文字が少し遅れて入力されたりすることとかよくありますよね。
このような場合、反応があるまでずっとボタンを押していなくてもちゃんと反応したり、
文字が抜け落ちたりせず正しく入力されるのは、メッセージがキューに入っているからです。

GetKeyStateだと「今処理しているメッセージがキューに入った時点」、つまりボタンをクリックした瞬間のキーの状態がとれます。
これに対してGetAsyncKeyStateだと、メッセージを処理している今この瞬間のキーの状態になります。

ボタンをクリックしてもすぐに反応がなくて、たとえば0.5秒ほどたってからようやく処理された場合
Asyncの方を使っていると「Ctrlキーと一緒にクリックしたつもりなのに、
普通にクリックしたかのように処理されてしまった」ということが起こりうるわけです。
キー入力にたとえれば「"Delphi" と入力したかったのに 2delPHi2 になってしまった」という感じです。

編集 削除
うんと  2009-03-06 17:44:10  No: 33543  IP: 192.*.*.*

>GetKeyStateだと「今処理しているメッセージがキューに入った時点」、つまりボタンをクリックした瞬間のキーの状態がとれます。

なるほど。そうですね。納得しました。

逆に、ゲームやなにかでループでユーザのキー入力を監視しているような場合は、Async の方を使うべきなんですね。

ありがとうございました。

編集 削除
久美子  2009-03-08 06:25:48  No: 33544  IP: 192.*.*.*

みなさんどうもありがとうございました。
プロクラムは解決、そして勉強になりました。

編集 削除