Windowsプログラム
ウィンドウの管理とかフックの仕方とかよくわからず,なかなか難航.
今日は会社休んだので,半日くらいフックと格闘してました.
で,キーボードフックして,1キーが押されたら,追加でもうひとつ1キーを入力するサンプルまで.
あとは,キーのスキャンコード調べて,IMEとかの状態取得をやって,SHIFTキーとかの状態見る部分とか作って...かなあ.先は長い.
最初は WH_KEYBOARD でやっていて,DLL 周りでなやんだり.
その後,WH_KEYBOARD_LL に直してみて,ドキュメントを再度見直すと,DLL 化する必要がなかったり.
この部分に早く気づいていたら無駄な時間書けなくて済んだかも(涙
(やり方は同じだと思っていたので,後から変えるつもりだったのに...)
この辺は資料があまりないので苦戦しそう.
菱がソース公開しているので,結構参考にさせてもらってます.
The comments to this entry are closed.
Comments
> その後,WH_KEYBOARD_LL に直してみて,
> ドキュメントを再度見直すと,DLL 化する必
> 要がなかったり.
本当ですか?!
読んでもそういう意味に取れなかったので、どの部分でそう解釈できるのか教えてもらえるとありがたいです。
Posted by: 鈴見咲君高 | Sunday, July 31, 2005 05:02 AM
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/lowlevelkeyboardproc.asp
に
However, the WH_KEYBOARD_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.
とあります.
実際テストしてますが,そのように動作しています.
ただ,IMEの状態を他のプロセスから知る方法が無いようなので,IMEの状態で変換ルールを変える必要がある場合,これ以外のフックとも兼用する必要があるようです.
キーボードイベントは,
WH_KEYBOARD_LL → WH_KEYBOARD のローカルフック → WH_KEYBOARD のグローバルフック
の順で処理されるようなので,この方法なら対応アプリも増えるはずです.
手元では,姫踊子草が使えなかった goo RSS リーダーやコマンドプロンプトでもキー変換が出来ることを確認しました.
キーボードイベントは WH_KEYBOARD_LL で処理して,WH_CALLWNDPROC のフックを各アプリケーションに埋め込み.
そこで,DLL_ATTACH時と VK_KANJI キーイベントが来たときに IME 状態を取得して,メインアプリに知らせるような方法を試験中です.
Posted by: みかげ | Sunday, July 31, 2005 12:20 PM
WH_CALLWNDPROC や WH_CALLWNDPROCRET では,どうやってもIME状態が取得できないようです.
ImmGetContext が失敗してしまう...
WH_KEYBOARD ではうまくいくので,フック関数が実行される場所(?)が違うからなのかなあ...
色々やってみたけど解決出来なかったので,あきらめ.
なんか他にIME状態を取得出来る方法があればいいのだけど...
Posted by: みかげ | Sunday, July 31, 2005 10:25 PM
ありがとうございます。後ほどトラックバックで書きますが、その部分の直前にある文章(Howeverの前の"injected"まで)に影響されて正しく理解できてませんでした。
お礼と言ってはなんですが、繭姫などはWH_GETMESSAGEとWH_CALLWNDPROCでImmGetContextが成功しているはずなので、みかげさんとこで動かないのは何か原因があるのだと思います。
これらのフック内ではImmGetContextに渡す引数がGetFocus()だとダメとかあるかもしれません。繭姫の場合はCWPRETSTRUCT構造体やMSG構造体から得られるhwndを使っています。
Posted by: 鈴見咲君高 | Monday, August 01, 2005 02:30 AM
なるほど.
GetFocusでは取れなかったので,GetGUIThreadInfo を使っていました.
CWPRETSTRUCTで再度やってみます.
Posted by: みかげ | Monday, August 01, 2005 09:37 PM
なんとか取れるようになりました.
ただ,WH_CALLWNDPROCには,WM_KEYUPやWM_KEYDOWNはこないのですね...
ちょっと頻度が多くて負荷が心配ですが,WM_IME_NOTIFYのタイミングで調べるようにしたら動きました.
とりあえず今日はここまで...
Posted by: みかげ | Monday, August 01, 2005 11:29 PM