C/C++ 實現模擬鍵盤鼠標


今天寫了點代碼,功能是篩選桌面中符合某些條件的窗口,模擬鼠標鍵盤實現全選 → 復制 → 檢測剪切板 → 判斷是否存在某些敏感字符串。

大致功能是這樣。下面是代碼(如果不想看不相關的內容可以直接跳到底部):

#include <afx.h>  
#include <afxwin.h>
#include <Windows.h>
#include <vector>
#include <iostream>
#include <assert.h>
#include <psapi.h>
#include <tlhelp32.h>
#include <WtsApi32.h>
#include <locale.h>
#include <stdio.h>

#pragma comment(lib,"WtsApi32.lib")

using namespace std; 

// 獲取剪切板內容
char* getClipBoardValue(){
	// 初始化
	char *url,*pData;
	size_t length;

	// 打開剪切板
	OpenClipboard(NULL);

	// 獲取剪切板內的數據
	HANDLE hData=GetClipboardData(CF_TEXT);
	assert(hData!=NULL);

	// 獲取數據長度
	length=GlobalSize(hData);
	url=(char*)malloc(length+1);

	// 將數據轉換為字符
	pData=(char*)GlobalLock(hData);
	strcpy_s(url, length,pData); 

	// 一系列善后工作
	GlobalUnlock(hData);
	CloseClipboard();
	url[length]=0;
	
	return url;
}

// 遍歷窗口
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
	// 過濾不可見的窗口
	if(IsWindowVisible(hwnd)){
		// 過濾掉存在標題的窗口
		char szTitle[100];
		GetWindowText(hwnd, szTitle, 100);
		if(strcmp(szTitle,"") == 0){
			// 過濾掉大小不為 650*380 的窗口
			RECT rect;
			GetWindowRect(hwnd,&rect);
			if((rect.right - rect.left) == 650 && (rect.bottom - rect.top) == 380){
				// 過濾掉沒有指定文本的窗口
				for(int i=0;i<5;i++){
					// 指定位置右鍵
					PostMessage(hwnd, WM_RBUTTONDOWN, 0,MAKELPARAM(200,200));
					PostMessage(hwnd, WM_RBUTTONUP,0,MAKELPARAM(200,200));
					Sleep(10);
					// 按下 'A'
					PostMessage(hwnd, WM_KEYDOWN,0x41,0);
					PostMessage(hwnd, WM_KEYUP,0x41,0);
					Sleep(10);
					// 指定位置右鍵
					PostMessage(hwnd, WM_RBUTTONDOWN, 0,MAKELPARAM(200,200));
					PostMessage(hwnd, WM_RBUTTONUP,0,MAKELPARAM(200,200));
					Sleep(10);
					// 按下 'C'
					PostMessage(hwnd, WM_KEYDOWN,0x43,0);
					PostMessage(hwnd, WM_KEYUP,0x43,0);
				}
				// 指定位置左鍵(取消選中)
				PostMessage(hwnd, WM_LBUTTONDOWN, 0,MAKELPARAM(200,200));
				PostMessage(hwnd, WM_LBUTTONUP,0,MAKELPARAM(200,200));
				
				// 輸出剪切板內容
				cout << getClipBoardValue() << endl;
				
				// 判斷是否匹配特征
				string s_clipBoard = getClipBoardValue();
				if(s_clipBoard.find("未來終生的伴侶")!=s_clipBoard.npos){
					cout << "檢測到特征" << endl;
				}
			}
		}	
	}
    

    return TRUE;
}


int _tmain(int argc, _TCHAR* argv[])
{
	EnumWindows(EnumWindowsProc, 0);
	 
	getchar();
	return 0;
}

下面是 PostMessage 在本代碼中的詳解

首先就是,為什么用 PostMessage 而不用 SendMessage ?因為 SendMessage 會等待目標返回的結果,如果你發送消息的窗口一直不返回結果,它就會一直等待下去,導致程序卡死在這里,而 PostMessage 不會去關心這些問題。

這是上面代碼中的一部分:

// 模擬鼠標
PostMessage(
	hwnd, 					// 目標窗口句柄
	WM_RBUTTONDOWN, 		// 更多鼠標事件宏定義類型參考 : https://docs.microsoft.com/en-us/windows/win32/inputdev/mouse-input-notifications
	0,
	MAKELPARAM(200,200)		// x = 200,y = 200(相對於窗口的坐標,而不是屏幕的坐標)
	);

// 模擬鍵盤
PostMessage(
	hwnd,					// 目標窗口句柄
	WM_KEYDOWN,				// 更多鍵盤事件共定義參考 : https://docs.microsoft.com/en-us/windows/win32/inputdev/keyboard-input
	0x41,					// 更多按鍵種類宏定義參考 : https://docs.microsoft.com/zh-cn/windows/win32/inputdev/virtual-key-codes
	0
	);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM