加賀一稿一記

心は戦国

WindowsAPIでマウス・キーボード操作

マウスやキーボードの入出力操作を書くときに毎回調べていたのでまとめておきます.
賢い方法や最新の方法ではないだろうし,専用ツールを使えば解決できそう.
C++として動作確認したけど,Cとしても動くかも.
(入出力の説明に他の説明で使ったアレコレが使われていることがあります.)


マウス入力(ボタン)
GetAsyncKeyStateを使う.(仮想キーはココ参照.)
左ボタンが入力されていたらカウンタが増えるサンプル.右ボタンで終了.

#include <stdio.h>
#include <windows.h>

int main(){
	
	int cnt=0;
	printf("cnt=%d\n",cnt);
	printf("LBUTTON:cnt++;\n");
	printf("RBUTTON:break;\n");
	while(1){
		if(GetAsyncKeyState(VK_LBUTTON)){
			cnt++;
			printf("cnt=%d\n",cnt);
		}
		if(GetAsyncKeyState(VK_RBUTTON)){
			break;
		}
	}
	
	return 0;
}


左クリックでカウンタを増やすようにしたサンプル.

#include <stdio.h>
#include <windows.h>

int main(){
	
	int cnt=0, tmp=0;
	printf("cnt=%d\n",cnt);
	printf("LCLICK:cnt++;\n");
	printf("RBUTTON:break;\n");
	while(1){
		if(GetAsyncKeyState(VK_LBUTTON)){
			tmp++;
		}
		else{
			tmp=0;
		}
		if(tmp==1){
			cnt++;
			printf("cnt=%d\n",cnt);
		}
		if(GetAsyncKeyState(VK_RBUTTON)){
			break;
		}
	}
	
	return 0;
}


マウス入力(カーソル移動)
現在のカーソル位置はGetCursorPosを使う.
右ボタンが押されるまでカーソルの移動量を表示するサンプル.

#include <stdio.h>
#include <windows.h>

int main(){
	
	POINT pt;
	GetCursorPos(&pt);
	int lstx = pt.x;
	int lsty = pt.y;
	printf("RBUTTON:break;\n");
	while(1){
		GetCursorPos(&pt);
		int x = pt.x;
		int y = pt.y;
		if(x!=lstx || y!=lsty){
			printf("%d, %d\n",x-lstx,y-lsty);
			lstx=x;
			lsty=y;
		}
		if(GetAsyncKeyState(VK_RBUTTON)){
			break;
		}
	}
	
	return 0;
}


マウス出力(ボタン)
今回はmouse_eventを使う方法.
SendInputを使う方法もあって,こちらのほうが推奨されているけれど記述が長くなりそうなのでパス.
右ボタンで開始・終了する左クリック連打サンプル.

#include <stdio.h>
#include <windows.h>

int main(){
	
	printf("RBUTTON:start;\n");
	while(1){
		if(GetAsyncKeyState(VK_RBUTTON)){
			break;
		}
	}
	Sleep(100);
	printf("RBUTTON:break;\n");
	while(1){
		if(GetAsyncKeyState(VK_RBUTTON)){
			break;
		}
		mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
		Sleep(10);
		mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
		Sleep(10);
	}
	
	return 0;
}


マウス出力(カーソル移動)
カーソルの位置を指定した座標に移動させるだけならSetCursorPosを使います.
SetCursorPosを使って相対的な移動をする場合は,前述のGetCursorPosを事前に使って移動先の座標を計算する必要があります.
座標(0,0)にカーソルを移動するだけのサンプル.

#include <windows.h>

int main(){
	
	SetCursorPos(0,0);
	
	return 0;
}


前述のmouse_event(や推奨されているSendInput)はカーソルの移動も可能です.
相対的な移動量を指定することもできます.
右ボタンで開始・終了する,カーソルが右に動いていくサンプル.

#include <stdio.h>
#include <windows.h>

int main(){
	
	printf("RBUTTON:start;\n");
	while(1){
		if(GetAsyncKeyState(VK_RBUTTON)){
			break;
		}
	}
	Sleep(100);
	printf("RBUTTON:break;\n");
	while(1){
		if(GetAsyncKeyState(VK_RBUTTON)){
			break;
		}
		mouse_event(MOUSEEVENTF_MOVE,1,0,0,0);
		Sleep(10);
	}
	
	return 0;
}


キーボード入力
マウスのボタン入力と同様に,GetAsyncKeyStateを使います.
やはり仮想キーはココから選びましょう.
エンターが入力されていたらカウンタが増えるサンプル.右ボタンで終了.

#include <stdio.h>
#include <windows.h>

int main(){
	
	int cnt=0;
	printf("cnt=%d\n",cnt);
	printf("ENTER:cnt++;\n");
	printf("RBUTTON:break;\n");
	while(1){
		if(GetAsyncKeyState(VK_RETURN)){
			cnt++;
			printf("cnt=%d\n",cnt);
		}
		if(GetAsyncKeyState(VK_RBUTTON)){
			break;
		}
	}
	
	return 0;
}


キーボード出力
今回はkeybd_eventを使う方法.
やはりSendInputが推奨されているけれど記述が長くなりそうなのでパス.
右ボタンで開始・終了するエンター連打サンプル.

#include <stdio.h>
#include <windows.h>

int main(){
	
	printf("RBUTTON:start;\n");
	while(1){
		if(GetAsyncKeyState(VK_RBUTTON)){
			break;
		}
	}
	Sleep(100);
	printf("RBUTTON:break;\n");
	while(1){
		if(GetAsyncKeyState(VK_RBUTTON)){
			break;
		}
		keybd_event(VK_RETURN,0,KEYEVENTF_EXTENDEDKEY|0,0);
		Sleep(10);
		keybd_event( VK_RETURN,0,KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP,0);
		Sleep(10);
	}
	
	return 0;
}