今天寫了點代碼,功能是篩選桌面中符合某些條件的窗口,模擬鼠標鍵盤實現全選 → 復制 → 檢測剪切板 → 判斷是否存在某些敏感字符串。
大致功能是這樣。下面是代碼(如果不想看不相關的內容可以直接跳到底部):
#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
);
