VC 模拟鼠标和键盘输入

时间:2022-02-03 07:07:48

模拟鼠标点击:

1、这里是鼠标左键按下和松开两个事件的组合即一次单击: 

mouse_event (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 ) 

2、模拟鼠标右键单击事件: 
mouse_event (MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0 ) 

3、两次连续的鼠标左键单击事件 构成一次鼠标双击事件: 
mouse_event (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 ) 
mouse_event (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 ) 

4、使用绝对坐标 
MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, 500, 500, 0, 0 

需要说明的是,如果没有使用MOUSEEVENTF_ABSOLUTE,函数默认的是相对于鼠标当前位置的点,如果dx,和dy,用0,0表示,这函数认为是当前鼠标所在的点--直接设定绝对坐标并单击 
mouse_event(MOUSEEVENTF_LEFTDOWN, X * 65536 / 1024, Y * 65536 / 768, 0, 0); 
mouse_event(MOUSEEVENTF_LEFTUP, X * 65536 / 1024, Y * 65536 / 768, 0, 0); 

其中X,Y分别是你要点击的点的横坐标和纵坐标 


模拟键盘输入:

void EnterString(const char* text)
{
	bool bShift = false;
	size_t length = strlen(text);
	for(size_t index = 0;index < length;index++)
	{
		int val = text[index];
		if(val >= 97 && val <= 122)    //小写a-z
		{
			val -= 32;
			bShift = false;
		}
		else if(val >= 65 && val <= 90) //大写A-Z
		{
			bShift = true;
		}
		else if(val >= 48 && val <= 57) //数字0-9
		{
			bShift = false;
		}
		else //特殊符号
		{
			switch(val)
			{
			case '`':
				val = 192;
				bShift = false;
				break;
			case '~':
				val = 192;
				bShift = true;
				break;
			case '!':
				val = '1';    //!和1在同一个键盘,使用同一个键盘码,以下相同
				bShift = true;
				break;
			case '@':
				val = '2';    //@和2在同一个键盘,使用同一个键盘码,以下相同
				bShift = true;
				break;
			case '#':
				val = '3';
				bShift = true;
				break;
			case '$':
				val = '4';
				bShift = true;
				break;
			case '%':
				val = '5';
				bShift = true;
				break;
			case '^':
				val = '6';
				bShift = true;
				break;
			case '&':
				val = '7';
				bShift = true;
				break;
			case '*':
				val = '8';
				bShift = true;
				break;
			case '(':
				val = '9';
				bShift = true;
				break;
			case ')':
				val = '0';
				bShift = true;
				break;
			case '-':
				val = 189;
				bShift = false;
				break;
			case '=':
				val = 187;
				bShift = false;
				break;
			case '_':
				val = 189;
				bShift = true;
				break;
			case '+':
				val = 187;
				bShift = true;
				break;
			case '[':
				val = 219;
				bShift = false;
				break;
			case '{':
				val = 219;
				bShift = true;
				break;
			case ']':
				val = 221;
				bShift = false;
				break;
			case '}':
				val = 221;
				bShift = true;
				break;
			case '\\':
				val = 220;
				bShift = false;
				break;
			case '|':
				val = 220;
				bShift = true;
				break;
			case ';':
				val = 186;
				bShift = false;
				break;
			case ':':
				val = 186;
				bShift = true;
			case '\'':
				val = 222;
				bShift = false;
				break;
			case '\"':
				val = 222;
				bShift = true;
				break;
			case ',':
				val = 188;
				bShift = false;
				break;
			case '<':
				val = 188;
				bShift = true;
				break;
			case '.':
				val = 190;
				bShift = false;
				break;
			case '>':
				val = 190;
				bShift = true;
				break;
			case '/':
				val = 191;
				bShift = false;
				break;
			case '?':
				val = 191;
				bShift = true;
				break;
			default:
				break;
			}
		}

		if(bShift)
			keybd_event(VK_SHIFT,0,0,0);
		keybd_event(val,0,0,0);
		keybd_event(val,0,KEYEVENTF_KEYUP,0);
		if(bShift)
			keybd_event(VK_SHIFT,0,KEYEVENTF_KEYUP,0);
	}
}
但是要注意,如果用户默认是中文输入法,那我们得先想办法切换到英文输入法才行。

到网上看到一篇文章,说的是在WinCE下的法:

http://www.cnblogs.com/iVincentFeng/archive/2010/04/20/KeyboardInputSimulation_SendMessage_keybd_event_PostKeybdMessage.html

但是后来发现,如果我们想写入中文字符,怎么办呢??

我开始的思路是像控制输入法的切换状态,来实现。。。 其实,我们只需找到我们需要输入的控件,然后填入中文字符就行了。

我用"按键精灵"找到控件的名称等相关信息,然后用下面的代码来遍历,之后填充数据即可。

	wchar_t sPath[]=_T("niha风范股份围观");
	CWnd * pWnd = FindWindow(NULL,_T("另存为"));
	CString sCtrlName;
	CWnd *pedit;
	CString filename;
	wchar_t *buf=new wchar_t[512];

	if(pWnd)
	{
		CWnd *pwnd=pWnd->GetWindow(GW_CHILD);//枚举保存对话框的所有子控件
		
		while(pwnd!=NULL)
		{
			::GetClassName(pwnd->GetSafeHwnd(),buf,512);//得到枚举的控件是什么类型的,
			CString str=buf;   
			str.TrimRight();           
			if(str==_T("ComboBoxEx32"))//如果枚举到保存文件名的EDIT
			{
				pedit=pwnd;//保存EDIT句柄用来发消息
				pwnd->SendMessage(WM_SETTEXT,sizeof(sPath)/sizeof(wchar_t),(LPARAM)(void*)sPath);
				UpdateData(FALSE);
				break;
			}
			pwnd = pwnd->GetNextWindow();
		}
		
	}
	delete [] buf; 

	SetCursorPos(512+r2.left,366+r2.top);//按钮【保存】
	mouse_event (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 ); 

想想,如果把坐标的操作全部转化为控件指针来处理,也许更安全,这样,不管客户那边的分辨率和中途改变窗口,我们的操作依然正确。


下面是附带的一点代码:

	if(str=="保存(&S)")//如果是保存按钮
	{   
		lstrcpy(BUF,(LPCTSTR)sPath);//sPath表示我们要设置的对话框浏览目录
		//发消息设置文件名EDIT为我们的路径名,完成第二步
		pedit->SendMessage(WM_SETTEXT,0,(LPARAM)BUF);
		//发消息模拟点击保存按钮,完成第三步
		::SendMessage(pwnd->GetSafeHwnd(),WM_LBUTTONDOWN,0,0);
		::SendMessage(pwnd->GetSafeHwnd(),WM_LBUTTONUP,0,0);
	}

//发消息还原EDIT里的文件名,完工!
pedit->SendMessage(WM_SETTEXT,0,(LPARAM)filename);


附带一个链接,自认为比较好的一篇文章:点击打开链接

OK ,就此为止,有什么不正确的地方,欢迎大家指正,共同进步..!!!VC 模拟鼠标和键盘输入