[index] [詰め合わせ] [ダイアログボックス] [メニュー] [アクセラレータ] [String Table] [その他]

 

アクセラレータ(accelerator)
リソーススクリプトでの。

 

 アクセラレータは、通常のアルファベットキーのほか、[F1] のようなファンクションキーなどが押されたときに、特定のメッセージに結びつけるようにしたいとき使います。

 

 


            
#include <windows.h>
// #include <commctrl.h>
// #include "myprog.h"

#define IDM_ACTF1       100
#define IDM_CTRLF1      101
#define IDM_SHIFTF1     102
#define IDM_CTRLUP      103
#define IDM_CTRLDOWN    104
#define IDM_NEXT        105
#define IDM_NKEY        106

MYACCEL ACCELERATORS DISCARDABLE 
BEGIN
    VK_F1  , IDM_ACTF1  , VIRTKEY, NOINVERT
    VK_F1  , IDM_CTRLF1 , VIRTKEY, CONTROL , NOINVERT
    VK_F1  , IDM_SHIFTF1, VIRTKEY, SHIFT   , NOINVERT
    VK_UP   ,IDM_CTRLUP     , VIRTKEY, CONTROL, NOINVERT
    VK_DOWN ,IDM_CTRLDOWN   , VIRTKEY, CONTROL, NOINVERT
    VK_DOWN ,IDM_NEXT       , VIRTKEY, SHIFT, CONTROL, NOINVERT
    "N" , IDM_NKEY , VIRTKEY , NOINVERT
END

 


 VK_F1 は [F1] キーを表しています。VK_UP VK_DOWN はそれぞれ、キーボードの [↑]キー、[↓]キーです。

 VK_F1 が3つもあるのは、それぞれ、[SHIFT] キーを同時に押したとき、[CTRL] キーを同時に押したとき、なにも押してないとき、の3種類を定義しているからです。

 通常のアルファベットキーもショートカットキーに指定することが可能です。例えば [N] キーなら上の例のようになります。

 上記では使用していませんがほかに、ASCII キーワードなどがあります。

 

 [仮想キー]
 VK は、Virtual Key の略です。日本語では 「仮想キー」。ほかに VK_ のどのようなものがあるかは、ヘッダファイル <winuser.h> をあたってみるか、仮想キーや、仮想キーコード などを調べてください。結構たくさんあります。

 

 [ [SHIFT] キー[CTRL] キー ]
 上記リソーススクリプト例を参照してください。
CONTROL 及び SHIFT が指定の際のキーワードです。さらに [ALT] キーの場合は、ALT キーワード を使います。これらの指定では VIRTKEY キーワードを併せて指定する必要があります。SHIFT+CTRL も指定できます(例参照)。

 

 [ WM_COMMAND と メッセージID]
 アクセラレータとして定義されたキーが押された場合には、(以下で述べるようにショートカットキーの仕組みが組み込まれていれば)、対象のウィンドウに WM_COMMAND メッセージが送られ、wParam※ の 下位ワード(LOWORD) に メッセージID を持っています。(※ ウィンドウプロシージャやダイアログプロシージャの第3引数のことを言っています)

 つまり、この メッセージID の扱いは、ダイアログボックスのコントロールの コントロールID 及び、メニューにおけるメニューアイテムのID とまったく同様です。

 

 さて、ショートカットキーを有効にするには、リソースのリンク ( brc32.exe ) はこのさいもちろんとして、以下で述べるように メッセージループの部分を少々書き換える必要があります。

 ウィンドウズのアプリケーションに慣れてしまうと、エディットボックス以外はキーなんかほとんど使うことなく、なんだかんだでマウス主体で動かしていることに気づくはずです。そして、キーボードの UI (ユーザ・インターフェース) を介した重要性も意識しなくなります。

 キーボードは UI の主要な要素に違いありません。アクセラレータに頼らずとも、キーのイベントを知るには、原始的には、直接メッセージループの部分の MSG 構造体のパラメータに渡されるキー情報を見ることで可能です。アクセラレータはその手間を軽減してくれる便利な方法、つまり WM_COMMAND メッセージに変換してしまうという方法 (のための対応テーブル表) です。※ keybd_event() 関数はキーボードイベントを「発生」させることができます。

 

 すなわち、アクセラレータを有効にするには、あるいは 「その変換を行うため」 には、具体的に TranslateAccelerator() という関数を用い、メッセージループの部分を以下のように少し変える(組み込む)必要があります。

[ 関数 WinMain() 内.......]

HACCEL hAccel = LoadAccelerator( GetModuleHandle(NULL), "MYACCEL" ) ; while ( 0 != ( ret = GetMessage( &msg, NULL, 0, 0 ))) { if ( ret != -1 ) { if( ! TranslateAccelerator( msg.hwnd , hAccel, &msg )) { TranslateMessage( &msg ) ; DispatchMessage( &msg ) ; } } } // msg.hwnd の部分は一時的です。このようにすると全てのウィンドウに対してアクセラレータが有効になります。特定のウィンドウ(メインウィンドウなど)だけ有効にしたい場合はよくあります。そのときは、そのウィンドウのハンドルを指定するようにします。 // GetModuleHandle(NULL) も一時的です。ここは WinMain() 関数内だから、WinMain() 関数の第一引数(インスタンスハンドル : 変数名 hInstance 等)をそのまま使ってもいいでしょう。 // MSG 構造体の説明 .のところで、おもしろいものを紹介しました。これを活用するとメッセージループがこれ以上煩雑にならないで済みます。

 

 TranslateAccelerator() 関数により、メッセージループの部分で、キーボードのイベントが、 「アクセラレータ」 で定義しておいたメッセージID を wParamパラメータ の下位ワードに持つような、WM_COMMAND メッセージに、変換されます(つまり親のウィンドウに送られます)。

 WM_COMMAND のメッセージ処理の仕方はここで述べることではありません。ただ非常に定番のやりかたです。 [メニュー] での説明などを見てキーワードを得て、少し調べてみてください。WM_COMMAND 自体が有力キーワードです。

 ※ LoadAccelerator() 関数でロードしたリソースの開放はする必要はありません。hAccel はアクセラレータリソースのハンドルです。

 

 アプリケーションへのすべてのメッセージ(イベント)は、メッセージループを経ます。キー入力もイベントだからほかでもないわけです。

 

 

[トップ] [level4:言葉] [index]