カーソル操作
カーソルの位置
マウスカーソルの位置情報は、メッセージから取得することができました
しかし、メッセージに関係なくマウスカーソルの位置を知りたい時もあるでしょう
また、キーボードやプログラムからマウスカーソルの位置を変更させたり
マウスがないコンピュータのために、キーボードでエミュレートしたい場合もあります
Windows は、このような要求もかなえることができます
マウスカーソルの現在位置を知るには GetCursorPos() 関数を使います
BOOL GetCursorPos(LPPOINT lpPoint);
lpPoint() には、マウス座標を格納するポイント構造体へのポインタを指定します
関数が成功すると 0 以外、失敗すると 0 が返ります
lpPoint に格納される座標は、スクリーン全体の座標です
マウスカーソルの位置をプログラムから変更するには
SetCursorPos() ファンクションを使います
BOOL SetCursorPos(int X , int Y)
X に スクリーン全体のX座標、Y に Y座標を指定します
関数が成功すれば 0 以外、失敗すれば 0 を返します
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
HDC hdc;
POINT po;
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
GetCursorPos(&po);
if(wp == VK_UP) po.y--;
if(wp == VK_DOWN) po.y++;
if(wp == VK_LEFT) po.x--;
if(wp == VK_RIGHT) po.x++;
SetCursorPos(po.x , po.y);
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)) DispatchMessage(&msg);
return msg.wParam;
}
このプログラムを実行し、キーボードフォーカスを得ている状態で
キーボードの方向キーを押すと、マウスカーソルが1ピクセルずつ移動します
マウスカーソルを消す
通常、マウスがインストールされていない場合はカーソルは表示されません
しかし、マウスがなくてもカーソルを表示させたり
マウスがインストールされていてもマウスカーソルを消すことができます
マウスカーソルの表示非表示は ShowCursor() 関数を使います
int ShowCursor(BOOL bShow);
bShow には、TRUE または FALSE を指定します
マウスの表示は、内部的に表示カウントが使用されていて
カウントが負数(0未満)の時は非表示にし、0以上であれば表示します
引数に TRUE を指定すれば内部カウントをインクリメントし
FALSE を指定すれば内部カウントをデクリメントする仕組みになっています
戻り値は、新しく設定したカウントの値を返します
#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_LBUTTONDOWN:
ShowCursor(TRUE);
return 0;
case WM_CREATE:
ShowCursor(FALSE);
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)) DispatchMessage(&msg);
return msg.wParam;
}
このプログラムのウィンドウは、マウスカーソルを表示しません
しかし、マウスカーソルをウィンドウのクライアントエリアでクリックすると表示されます
GetCursorPos()
BOOL GetCursorPos(LPPOINT lpPoint);
現在のマウスカーソルのスクリーン座標を得ます
lpPoint - 座標を格納する POINT 構造体へのポインタを指定します
戻り値 - 関数が成功すれば 0 以外。失敗すれば0
SetCursorPos()
BOOL SetCursorPos(int X , int Y)
マウスカーソルの位置を指定座標に移動します
X - X座標を指定します
Y - Y座標を指定します
戻り値 - 関数が成功すれば 0 以外。失敗すれば0
ShowCursor()
int ShowCursor(BOOL bShow);
マウスカーソルの内部カウントを変更します
TRUE を指定すればインクリメント FALSE を指定すればデクリメントし
0未満であれば、カーソルを非表示にします
bShow - カウント操作のためのブーリアンを指定します
戻り値 - 新しいカウントの値