仮想キーの状態


キーボードの状態

前回までのキーボードイベントは、メッセージを処理するという形でした
しかしそれ以外のイベントの発生時に、キーボードの状態を知りたい時があります

代表的な例では、シフトキーが押されているかなどですね
シフト状態やトグル状態などを知るには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



前のページへ戻る次のページへ