キーフックについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
...

キーフックについて

#1

投稿記事 by ... » 16年前

キーフックでアルファベットを検出すると、大文字小文字関係なしに0x41~0x5Aになりますょね。
これってフックプロシージャの中で大文字と小文字を区別しようとしてもできないってことなんでしょうか??
シフトが押されている場合とかで分けようと思ったのですが、フックプロシージャにおける同時に押されている場合の処理の方法もわかりません。。。
例えば小文字の場合-32(大文字に変換)して返す、大文字の場合+32(小文字に変換)して返す。
といった処理をする場合どのように書けばよろしいのでしょうか??
無知で申し訳ありません。お願いします。

Justy

Re:キーフックについて

#2

投稿記事 by Justy » 16年前

 GetKeyboardStateで調べれば Caps/Shiftの押下状態がわかるので、
そこから判定してはどうでしょうか。

...

Re:キーフックについて

#3

投稿記事 by ... » 16年前

>>Justyサン
回答ありがとうございます。
確かにShift+アルファベットならそれでわかりますが、Caps Lockが付いているかはどうかってどうやって判断したらよいのですか??
あと中で文字を加工して返すというのはどうやればよいのですか??

Justy

Re:キーフックについて

#4

投稿記事 by Justy » 16年前


>Caps Lock

 VK_CAPITAL



>文字を加工して返すというのはどうやればよいのですか

 大文字・小文字変換であれば標準関数の toupper/tolowerで
変換して、受け渡し用の変数か関数に引き渡せばいいかと思います。

...

Re:キーフックについて

#5

投稿記事 by ... » 16年前

プログラムが始まる前にCaps Lockがついている場合も同じようにキーが押されている状態になっているのですか??

フックプロシージャ内で得られる情報は仮想キーコード(0x41~0x5A)だけなのでその辺の関数は意味がないのですが。。。。。
ASCIIコードで取得できますか??

Justy

Re:キーフックについて

#6

投稿記事 by Justy » 16年前


>プログラムが始まる前にCaps Lockがついている場合も同じように
>キーが押されている状態になっているのですか

 フックプロシージャの WPARAMの仮想キーコードではなく、
GetKeyboardStateとか GetKeyStateの方から VK_CAPITALの情報を拾えば
取得できるはずですよ。

 あと、0-9の数字、A-Zのアルファベットに対応する仮想キーコードと ASCIIコードは
一致します。

仮想キーコード
ttp://yokohama.cool.ne.jp/chokuto/urawaza/prm/virtual_key_code.html

 仮に一致しなかったとしても、変換テーブルを書くなり、if/switchで判定すれば
変換することは容易でしょう。

...

Re:キーフックについて

#7

投稿記事 by ... » 16年前

取得するときはプロシージャ内でShiftが押されているかどうかを判断して
押されていれば大文字というふうに、こちら側が判断して取得できますが、
文字をCallNextHookEx()に渡すときは結局仮想キーコードのみをWPARAMとして渡すわけなので
パソコンがどのようにして大文字と小文字を判断しているのかに合わせて処理をしなければいけないと思うのですが。。。
ついでにAは0x41で一致していますが、aは0x61。これはテンキーの1あたりに来ます。toupper()などを使うとそうなると思います。

Justy

Re:キーフックについて

#8

投稿記事 by Justy » 16年前


>文字をCallNextHookEx()に渡すときは結局仮想キーコードのみを
>WPARAMとして渡すわけなのでパソコンがどのようにして大文字と小文字を
>判断しているのかに合わせて処理をしなければいけないと思うのですが

 どういう状態を想定して、最終的に何をしたいのでしょうか。
 意味がよくわかりません。

 送られてきた WPARAMの仮想キーコードがアルファベットの時、
それが大文字になるか小文字になるかをプロシージャ内で判定できればいいのですよね?

 CAPS/SHIFTの状態からでは大文字と小文字を判断出来ないということでしょうか?
(IMEがオンだとそちらの状態に引きずられるので、100%の判定はこの方法では無理ですが)

...

Re:キーフックについて

#9

投稿記事 by ... » 16年前

大文字小文字の判定だけでなく、最初に書いてあるとおり大文字が入力されたら小文字を返し、大文字が入力されたら小文字を返す。
といったことがしたいのです。

Justy

Re:キーフックについて

#10

投稿記事 by Justy » 16年前


>大文字が入力されたら小文字を返し、大文字が入力されたら小文字を返す

 えーと、判らないのは「どこへ返すか」です。
 普通に考えれば、関数の呼び出し元に戻り値か何かで返したいかなということになりますが、
プロシージャではそういうことではないでしょうし……。

 ひょっとしてやりたいことは「返す」というか、
Windowsアプリが受け取る文字を偽装(この場合は 大文字小文字)したい、
ということだったりしませんか?

...

Re:キーフックについて

#11

投稿記事 by ... » 16年前

あぁ、そういうことです!!

Justy

Re:キーフックについて

#12

投稿記事 by Justy » 16年前

 理解できました。

 ということはこんな感じでしょうか。
[color=#d0d0ff" face="monospace]

LRESULT CALLBACK KeyboardHookProc(int code, WPARAM wp, LPARAM lp)
{
if(code >= 0 && code != HC_NOREMOVE)
{
if(wp >= 'A' && wp <= 'Z')
{
int invCase = GetKeyState(VK_SHIFT) < 0? 1: 0;
if(GetKeyState(VK_CAPITAL) & 1)
invCase = !invCase;

PostMessageA(hWnd, WM_CHAR, (WPARAM)(invCase? tolower(wp): wp), lp);
return -1;
}
}
return CallNextHookEx(hHook, code, wp, lp);
}
[/color]

 A-Zなら Caps/Shiftの判定を行い、反転させたものを PostMessageで送信し、
それ以外なら何もしません。

 これで押したキーがアルファベットなら WM_CHARメッセージに反転された情報が送られます。

...

Re:キーフックについて

#13

投稿記事 by ... » 16年前

ありがとうございますw
C言語なので自分なりに少し改良しましたが、もうひとつ問題ができました。

LRESULT CALLBACK HookProc
(int nCode, WPARAM wp, LPARAM lp)
{
BOOL invCase;
if (nCode<0) return CallNextHookEx(hHook,nCode,wp,lp);
if (wp>='A' && wp<='Z') {
invCase=(GetKeyState(VK_SHIFT)&0x80)?TRUE:FALSE;
if (GetKeyState(VK_CAPITAL)&0x80) invCase=(invCase)?FALSE:TRUE;
PostMessage(ghEdit,WM_CHAR,(WPARAM)((invCase)?tolower(wp):wp),lp);
return TRUE;
}
return CallNextHookEx(hHook,nCode,wp,lp);
}

これを実行するとキー入力が二回拾われてしまうのです。
つまりWM_KEYUPとWM_KEYDOWN。これをWM_KEYDOWNのみ回避するとかってできますか??
二回に一回キーを拾うという方法だと押しっぱなしの時の動作が少しおかしくなりそうなので↑の方針でお願いします。

Justy

Re:キーフックについて

#14

投稿記事 by Justy » 16年前

 じゃぁ、lpの最終ビットをチェックしてみてはどうでしょう。

KeyboardProc 関数
ttp://msdn.microsoft.com/ja-jp/library/cc430012.aspx

...

Re:キーフックについて

#15

投稿記事 by ... » 16年前

(lp&(1<<31))?'1':'0'で判定してみたところ
キーダウンのときが0で、押され続けている間も0、キーアップだけが1みたいですね。
ありがとうございましたw
本当に助かりました!!

閉鎖

“C言語何でも質問掲示板” へ戻る