第313章 IE様メニューの試作 その3−1


今回はIE様メニューでショートカットキーが有効になるようにします。

ALTキーを押すと最初のメニュー項目(ファイル(F))がアクチベートされます。 次に、たとえば「O」キーを押すと「オプション(O)」をクリックしたのと同じ効果が 得られます。この状態で下矢印キーを押すと「ツールチップ(T)」が強調表示 されます。
また、ALTキーを押して「ファイル(F)」をアクチベートした後、右矢印キーを 押すと「編集(E)」がアクチベートされます。
このような機能は、どのようにプログラムすればよいのでしょうか。実はこれは メッセージフックなのです。メッセージフックについては 第160章を参照してください。



では、具体的にどうするかというと、メインウィンドウのプロシージャに WM_CREATEメッセージが来たら、WH_KEYBOARDタイプのフックを開始します。 ヘルプでは、WM_MSGFILTERでフックするような説明になっていますが、 WH_KEYBOARDの方が簡単です。

たとえばフックプロシージャを

LRESULT CALLBACK KbdHook(int code, WPARAM wp, LPARAM lp)

とすると、ALTキーまたはF10キーが押された時、最初のメニュー項目が アクチベートされなくてはいけません。

codeがHC_ACTIONでwpがVK_MENU(ALTキー)または、VK_F10の時IE様メニューバーに TB_SETHOTITEMメッセージを送ります。

TB_SETHOTITEM wParam = (WPARAM)(INT)iHot; lParam = 0;

wParamには、ホットにしたいアイテムのインデックスを指定します。
-1を指定すると、どのアイテムもホットになりません。

戻り値は以前のホットアイテムのインデックスです。前回ホットアイテムが なかったときは-1が返ります。

ホットアイテムが存在する状態で、F,E,Iなどのショーカットキーが 押されたときは、そのメニュー項目のポップアップを表示します。 これは、以前(第312章)に作ったShowMyPopMenu関数を使うと便利です。

ホットアイテムが存在する状態で、何かキーが押された時、それがショートカットキーであるかどうかは いちいち、調べてもよいのですが、TB_MAPACCELERATORメッセージを使うとスマート(?)です。

TB_MAPACCELERATOR wParam = (WPARAM)(TCHAR) chAccel; lParam = (LPARAM)(LPUINT) pIDBtn;

chAccelには押されたキーを指定します。すると、pIDBtnにそのショートカットキーの idのポインタが入ります。

そもそも、押されたキーがショートカットキーでない時は、 戻り値が0になります。

左右のカーソルキーが押されたときは、TB_SETHOTITEMメッセージを使って ホットアイテムを左右に移動させます。

さて、左キーを押すと、そのキーが押されたときと、離したときの2回フックが起こります。 これでは、一度左キーを押すと2つ分ホットアイテムが移動してしまいます。 そこで、キーが押された時のみ(または離された時)にホットアイテムが移動するように工夫します。

このプロシージャのlpには、キーストロークメッセージの付加情報が格納されています。 キーが押されているのかどうかはlpの第31ビット(最上位ビット)が1かどうかでわかります。 よく使う手は

HIWORD(lp) & 0x8000

または、 HIWORD(lp) & KF_UP

です。KF_UPはwinuser.hで0x8000と定義されています。 0x8000は2進法で書くと

1000000000000000

となます(16ビット)。そこで、lpの上位16ビットを取ってきて ビット演算をすればよいことがわかります。

こう書くと、簡単そうに思われますが実際にプログラムを書くときは、かなり面倒なことが起こります。 ちょっとしたミスで、深みにはまり堂々巡りが起こってしまいます。そんな時は、 あっさり休憩を取るなり、翌日にやり直すつもりで眠ってしまいましょう。

今回の部分を含め、かなり長いプログラムとなってしまったので、サンプルは 次章で示します。


[SDK第4部 Index] [総合Index] [Previous Chapter] [Next Chapter]

Update 05/Aug/2001 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。