FAQ7-2

Q. カーソルキーで斜めに移動するには

 キーボードのカーソルキーで上下左右に移動するものを作りたいのですが,WM_KEYDOWNメッセージに応答するだけでは,上と左を押したときに斜めに移動することができません.いったいどうしたらいいのでしょう.
 あとカーソルキーを押しながらスペースキーが押されているのをチェックしたいのですが,どうしたらいいのでしょう.


A. GetKeyState()を使う

 キーボードの状態を問い合わせるには,GetKeyState()を使います.引数に仮想キーコードを指定すると,復帰値の最上位ビットに押し下げ状態が返されます.
 仮想キーコードとは,キーボードのキーを表す値のことで,VK_で始まるデファイン値が定義されています.
 カーソルキーの上下左右の仮想キーコードはそれぞれ,VK_UP,VK_DOWN,VK_LEFT,VK_RIGHTです.
 たとえば,上が押されているかを判断するには,
 GetKeyState( VK_UP ) & 0x8000;
を判断してやればできます.0x8000は,最上位ビットを表す値で,Win16APIでもWin32APIでも16ビットの値が返されるので共通して0x8000をandすれば押し下げ状態を判断できます.
 たとえば,リスト7-1のように使用すれば,上と左を同時に押しても斜めに動かすことができるようになります.

[リスト7-1] :

static int xPos, yPos;

switch( message ) {
    case WM_CREATE:
        xPos = 0;
        yPos = 0;
        SetTimer( hwnd, 1, 100, NULL );
        return 0;
        
    case WM_TIMER:
        if( GetKeyState( VK_LEFT ) & 0x8000 ) {
            xPos -= 10;
        }
        if( GetKeyState( VK_RIGHT ) & 0x8000 ) {
            xPos += 10;
        }
        if( GetKeyState( VK_UP ) & 0x8000 ) {
            yPos -= 10;
        }
        if( GetKeyState( VK_DOWN ) & 0x8000 ) {
            yPos += 10;
        }
        DrawPosition( xPos, yPos );	//←自分で作る関数
        return 0;
}

GetAsyncKeySatate()

 GetKeySatate()に似た関数で,GetAsyncKeySatate()というのがあります.これは,常に関数が呼ばれた時点でのキーボード状態を問い合わせるものです.
 実は,GetKeyState()のほうは関数が呼ばれた時点でのキーボード状態がわかるのではなく,メッセージを拾った時点でのシステムが覚えておいたキーボードの状態がわかるのです.状況によって使い分けるといいでしょう.
 キーボードによって(?),左と下と他のキーを同時に押したりすると,マトリクスの状態によりうまく押せない場合もあるようなので,親切なアプリケーションでは上下左右のキーを他のキーにも割り当てられるようにしておくといいかもしれません.

GetKeyboardState()

 このほかにも,GetKeyboardState()というAPIがあり,256個のBYTE配列にすべてのキーボード状態をコピーするというもので,GetKeyState()と似た使い方ができます.たとえば,
    BYTE key[256];
    GetKeyboardState(key);
    if( key[VK_UP] & 0x80 ) { ・・・ }
    if( key[VK_DOWN] & 0x80 ) { ・・・ }
といったようにもできますが,これは大抵の場合SetKeyboardSatate()と組み合わせて使用し,たとえばCTRLキーが押されていなくても「CTRLキーを押している」とWindowsに思い込ませたいときなどに使います.場合によってうまくいかないこともありますが...
    BYTE key[256];
    GetKeyboardState(key);
    key[VK_CONTROL] |= 0x80;
    SetKeyboardState(key);
 このほかにも,マルチメディア関数でジョイスティックをサポートしたりすると便利かもしれないです.
 ジョイスティックの関数はjoyで始まる関数名で,たとえばjoyGetPos()とかがあります.詳しくはマルチメディアのヘルプを参照するとよいでしょう.

Back to FAQ main page