仮想キーの状態
キーボードの状態
前回までのキーボードイベントは、メッセージを処理するという形でした
しかしそれ以外のイベントの発生時に、キーボードの状態を知りたい時があります
代表的な例では、シフトキーが押されているかなどですね
シフト状態やトグル状態などを知るにはGetKeyState()ファンクションを使います
SHORT GetKeyState(int nVirtKey);
nVirtKey には、調べたいキーの仮想キーコードを渡します
仮想キーコードはそれぞれのキーに対応しており、以下のものがあります
定数 | 数値 | IBM 互換キーボード
|
---|
VK_LBUTTON | 0x01 | マウス左ボタン
|
VK_RBUTTON | 0x02 | マウス右ボタン
|
VK_CANCEL | 0x03 | Ctrl-Break
|
VK_MBUTTON | 0x04 | マウス中央ボタン
|
VK_BACK | 0x08 | Backspace
|
VK_TAB | 0x09 | Tab
|
VK_CLEAR | 0x0C | NumLock を外した状態のテンキー5
|
VK_RETURN | 0x0D | Enter
|
VK_SHIFT | 0x10 | Shift
|
VK_CONTROL | 0x11 | Ctrl
|
VK_MENU | 0x12 | Alt
|
VK_PAUSE | 0x13 | Pause
|
VK_CAPITAL | 0x14 | Caps Lock
|
VK_KANA | 0x15
|
VK_HANGEUL
|
VK_HANGUL
|
VL_JUNJA | 0x17
|
VK_FINAL | 0x18
|
VK_HANJA | 0x19
|
VK_KANJI
|
VK_ESCAPE | 0x1B | Esc
|
VK_CONVERT | 0x1C
|
VK_NONCONVERT | 0x1D
|
VK_ACCEPT | 0x1E
|
VK_MODECHANGE | 0x1F
|
VK_SPACE | 0x20 | Spacebar
|
VK_PRIOR | 0x21 | Page Up
|
VK_NEXT | 0x22 | Page Down
|
VK_END | 0x23 | End
|
VK_HOME | 0x24 | Home
|
VK_LEFT | 0x25 | 左方向キー
|
VK_UP | 0x26 | 上方向キー
|
VK_RIGHT | 0x27 | 右方向キー
|
VK_DOWN | 0x28 | 下方向キー
|
VK_SELECT | 0x29
|
VK_PRINT | 0x2A
|
VK_EXECUTE | 0x2B
|
VK_SNAPSHOT | 0x2C | PringScreen
|
VK_INSERT | 0x2D | Insert
|
VK_DELETE | 0x2E | Delete
|
VK_HELP | 0x2F
|
-- | 0x30〜0x39 | メインキーボード 0〜9
|
-- | 0x41〜0x5A | 文字キー A から Z
|
VK_LWIN | 0x5B | 左 Windows キー
|
VK_RWIN | 0x5C | 右 Windows キー
|
VK_APPS | 0x5D | アプリケーションキー
|
VK_NUMPAD0 | 0x60 | NumLock がオンになっている状態で それぞれテンキーの 0 〜 9 まで
|
VK_NUMPAD1 | 0x61
|
VK_NUMPAD2 | 0x62
|
VK_NUMPAD3 | 0x63
|
VK_NUMPAD4 | 0x64
|
VK_NUMPAD5 | 0x65
|
VK_NUMPAD6 | 0x66
|
VK_NUMPAD7 | 0x67
|
VK_NUMPAD8 | 0x68
|
VK_NUMPAD9 | 0x69
|
VK_MULTIPLY | 0x6A | テンキー *
|
VK_ADD | 0x6B | テンキー +
|
VK_SEPARATOR | 0x6C
|
VK_SUBTRACT | 0x6D | テンキー -
|
VK_DECIMAL | 0x6E | テンキー .
|
VK_DIVIDE | 0x6F | テンキー /
|
VK_F1 | 0x70 | それぞれ F1 から F24 までのファンクションキー
|
VK_F2 | 0x71
|
VK_F3 | 0x72
|
VK_F4 | 0x73
|
VK_F5 | 0x74
|
VK_F6 | 0x75
|
VK_F7 | 0x76
|
VK_F8 | 0x77
|
VK_F9 | 0x78
|
VK_F10 | 0x79
|
VK_F11 | 0x7A
|
VK_F12 | 0x7B
|
VK_F13 | 0x7C
|
VK_F14 | 0x7D
|
VK_F15 | 0x7E
|
VK_F16 | 0x7F
|
VK_F17 | 0x80
|
VK_F18 | 0x81
|
VK_F19 | 0x82
|
VK_F20 | 0x83
|
VK_F21 | 0x84
|
VK_F22 | 0x85
|
VK_F23 | 0x86
|
VK_F24 | 0x87
|
VK_NUMLOCK | 0x90 | Num Lock
|
VK_SCROLL | 0x91 | Scroll
|
VK_LSHIFT | 0xA0 | Windows NT : 左Shiftキー
|
VK_RSHIFT | 0xA1 | Windows NT : 右Shiftキー
|
VK_LCONTROL | 0xA2 | Windows NT : 左Ctrlキー
|
VK_RCONTROL | 0xA3 | Windows NT : 右Ctrlキー
|
VK_LMENU | 0xA4 | Windows NT : 左Altキー
|
VK_RMENU | 0xA5 | Windows NT : 右Altキー
|
VK_PROCESSKEY | 0xE5 | WINVER が 0x400 と同じかそれ以上であれば定義される
|
VK_ATTN | 0xF6
|
VK_CRSEL | 0xF7
|
VK_EXSEL | 0xF8
|
VK_EREOF | 0xF9
|
VK_PLAY | 0xFA
|
VK_ZOOM | 0xFB
|
VK_NONAME | 0xFC
|
VK_PA1 | 0xFD
|
VK_OME_CLEAR | 0xFE
|
仮想キーコードは数値や文字の場合はASCIIコードがそのまま仮想キーコードになっています
これらの定数は WINUSER.H ヘッダファイルで確認することができます
戻り値は、指定したキーコードの状態が返ります
最上位ビットMSBが1(つまり、負数が返れば)ならば、キーが押されている状態で
0であれば、キーは押されていません
また、最下位ビットLSBが1の時は、キーがトグル状態であることを表します
0であればトグルが解除されているということです //たとえば、[CapsLock]キーが ON なら、トグル状態
では、早速プログラムを作ってみましょう
シフト状態を調べるには、シフトの仮想キーコードを渡せばよいですね
Shiftキーの仮想キーコードはVK_SHIFTです //仮想キーコードのプリフィックスは VK
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
HDC hdc;
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_KEYUP:
if (wp == VK_SHIFT) return 0;
if (GetKeyState(VK_SHIFT) < 0)
MessageBox(hwnd , TEXT("シフトを押した状態です") , TEXT("Kitty") , MB_OK);
else
MessageBox(hwnd , TEXT("シフトは押されていません") , TEXT("Kitty") , MB_OK);
return 0;
}
return DefWindowProc(hwnd , msg , wp , lp);
}
int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
PSTR lpCmdLine , int nCmdShow ) {
HWND hwnd;
MSG msg;
WNDCLASS winc;
winc.style = CS_HREDRAW | CS_VREDRAW;
winc.lpfnWndProc = WndProc;
winc.cbClsExtra = winc.cbWndExtra = 0;
winc.hInstance = hInstance;
winc.hIcon = LoadIcon(NULL , IDI_APPLICATION);
winc.hCursor = LoadCursor(NULL , IDC_ARROW);
winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
winc.lpszMenuName = NULL;
winc.lpszClassName = TEXT("KITTY");
if (!RegisterClass(&winc)) return -1;
hwnd = CreateWindow(
TEXT("KITTY") , TEXT("Kitty on your lap") ,
WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
CW_USEDEFAULT , CW_USEDEFAULT ,
CW_USEDEFAULT , CW_USEDEFAULT ,
NULL , NULL , hInstance , NULL
);
if (hwnd == NULL) return -1;
while(GetMessage(&msg , NULL , 0 , 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
SHIFTキーが離された時は、基本的に感知する必要がないので無視するとします
それ以外のキーが離された時、シフトが押されている状態かどうかを調べます
ただし、GetKeyState()はリアルタイムでキーボードを監視するわけではありません
これはメッセージ生成時までの状態を表しているのです
例えば処理中にシフトキーが開放されたことについては、興味を示しません
GetKeyState()
SHORT GetKeyState(int nVirtKey);
指定された仮想キーの状態を取得します
nVirtKey - 仮想キーコードを指定します
戻り値 - 仮想キーコードの状態
Windows NT では、VK_SHIFT、VK_CONTROL、VK_MENU の左右のキーを区別することができます
左 | 右
|
---|
VK_LSHIFT | VK_RSHIFT
|
VK_LCONTROL | VK_RCONTROL
|
VK_LMENU | VK_RMENU
|