有時咱們可能會在某個程序中用到模擬按鈕點擊事件。ios
本文中的例子在MFC程序中調試經過,duilib的沒試過,還需探索windows
很少說,上代碼:api
1 #include "stdafx.h" 2 #include "windows.h" 3 #include "Psapi.h" 4 #include "atlstr.h" 5 #include <string.h> 6 #include<iostream> 7 using namespace std; 8 9 #pragma comment(lib,"Psapi"); 10 #define ID_EXEC_CURFILE 32807 11 #define ID_RCL_HELP 32804 12 CString str; 13 14 //根據exe名字一部分查找進程id,返回 15 DWORD FindProcess(char *strProcessName) 16 { 17 DWORD aProcesses[1024], cbNeeded, cbMNeeded; 18 HMODULE hMods[1024]; 19 HANDLE hProcess; 20 char szProcessName[MAX_PATH]; 21 if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) return 0; 22 for(int i=0; i< (int) (cbNeeded / sizeof(DWORD)); i++) 23 { 24 hProcess = OpenProcess( /*PROCESS_QUERY_INFORMATION | PROCESS_VM_READ*/PROCESS_ALL_ACCESS, FALSE, aProcesses[i]); 25 if (hProcess == NULL) 26 continue; 27 EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbMNeeded); 28 GetModuleFileNameEx( hProcess, hMods[0], szProcessName,sizeof(szProcessName)); 29 30 if(strstr(szProcessName, strProcessName)) 31 { 32 OutputDebugString(_T("Find Process ok\n")); 33 cout<<szProcessName<<endl; 34 return(aProcesses[i]); 35 } 36 } 37 OutputDebugString(_T("Find Process fail\n")); 38 return 0; 39 } 40 41 42 /******************************************************************* 43 * 函數名稱:GetWindowHandleByPID 44 * 功 能:根據進程ID找窗口句柄 45 * 參 數:dwProcessID:進程Id號 46 * 返 回 值:成功返回窗口句柄,失敗返回NULL 47 *******************************************************************/ 48 HWND GetWindowHandleByPID(DWORD dwProcessID) 49 { 50 HWND h = GetTopWindow(0); 51 while ( h ) 52 { 53 DWORD pid = 0; 54 DWORD dwTheardId = GetWindowThreadProcessId( h,&pid); 55 56 if (dwTheardId != 0) 57 { 58 if ( pid == dwProcessID/*your process id*/ ) 59 { 60 // here h is the handle to the window 61 OutputDebugString(_T("GetWindowHandleByPID ok\n")); 62 return h; 63 } 64 } 65 66 67 h = GetNextWindow( h , GW_HWNDNEXT); 68 } 69 70 OutputDebugString(_T("GetWindowHandleByPID faild\n")); 71 return NULL; 72 } 73 74 75 /******************************************************************* 76 * 函數名稱:SendMsgChildWindow 77 * 功 能:遍歷子窗口句柄併發送按鈕消息 78 * 參 數:hWnd:父窗口句柄 79 * 返 回 值:null 80 *******************************************************************/ 81 void SendMsgChildWindow(HWND hWnd, UINT command, UINT ID, UINT eventType) 82 { 83 HWND hd = ::GetWindow(hWnd,GW_HWNDNEXT); 84 if (hd == NULL) 85 { 86 cout << "can not find window" <<endl; 87 } 88 while(hd!=NULL) //循環獲得全部的子窗口 89 { 90 PostMessage(hd,command,MAKEWPARAM(ID, eventType),0); 91 hd=GetNextWindow(hd,GW_HWNDNEXT); 92 } 93 //PostMessage(HWND_BROADCAST,command,MAKEWPARAM(ID, eventType),0);//廣播,不建議使用,其餘窗口也會收到 94 } 95 96 /******************************************************************* 97 * 函數名稱:FindWhndByName 98 * 功 能:根據exe名字找窗口句柄 99 * 參 數:exeName 100 * 返 回 值:窗口句柄,找不到返回NULL 101 *******************************************************************/ 102 HWND FindWhndByName(char *exeName) 103 { 104 HANDLE handle; 105 handle = OpenProcess( 106 // PROCESS_QUERY_INFORMATION | // Required by Alpha 107 // PROCESS_CREATE_THREAD | // For CreateRemoteThread 108 // PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx 109 // PROCESS_VM_WRITE, // For WriteProcessMemory 110 PROCESS_ALL_ACCESS, 111 FALSE, FindProcess(exeName)); 112 if (handle == NULL) 113 { 114 OutputDebugString(_T("error: handle null\n")); 115 } 116 DWORD ProcessId = GetProcessId(handle); 117 118 return GetWindowHandleByPID(ProcessId); 119 } 120 121 int CharToInt(char* str) 122 { 123 int ret = atoi(str); 124 return ret; 125 } 126 127 int HexstrToInt(char *str) 128 { 129 int nValude = 0; 130 sscanf(str,"%x",&nValude); 131 return nValude; 132 } 133 134 int _tmain(int argc, _TCHAR* argv[]) 135 { 136 HWND wHnd; 137 if (argc < 5) 138 { 139 OutputDebugString(_T("parameters not enough\n")); 140 return 0; 141 } 142 else if (argc == 5) 143 { 144 wHnd = FindWhndByName(argv[1]); 145 SendMsgChildWindow(wHnd,HexstrToInt(argv[2]),CharToInt(argv[3]),CharToInt(argv[4])); 146 } 147 else if (argc == 6) 148 { 149 wHnd = FindWhndByName(argv[1]); 150 if (wHnd == NULL) 151 { 152 wHnd = FindWhndByName(argv[2]); 153 cout << "second exeName" <<endl; 154 } 155 SendMsgChildWindow(wHnd,HexstrToInt(argv[3]),CharToInt(argv[4]),CharToInt(argv[5])); 156 } 157 158 return 1; 159 }
四個參數:
第一個參數:進程的名字 例如:QQ.exe
第二個參數:消息類型 例如: 0x0111 表明 WM_CZMMAND
第三個參數:資源ID(按鈕,菜單等)例如:32807(按鈕ID可在程序源碼中找到)
第四個參數:事件類型 例如:0 表明按鈕單擊(BN_CLICKED) 併發
第二第四個參數具體值可在:WinUser.h 頭文件中找到
調用實例:PostMsgProcess.exe QQ.exe 0x0111 32807 0
五個參數:
第一個參數:進程的名字 例如:QQ
第二個參數:進程的名字 例如:QQ.exe
第三個參數:消息類型 例如: 0x0111 表明 WM_CZMMAND
第四個參數:資源ID(按鈕,菜單等)例如:32807(按鈕ID可在程序源碼中找到)
第五個參數:事件類型 例如:0 表明按鈕單擊(BN_CLICKED) 函數
第二第四個參數具體值可在:WinUser.h 頭文件中找到
調用實例:PostMsgProcess.exe QQ QQ.exe 0x0111 32807 0 ui
若是有多個符合條件的窗口,先根據第一個參數找對應的窗口,找到就再也不尋找,只能找一個符合條件的窗口發送消息spa
須要的庫和頭文件:http://files.cnblogs.com/files/george-cw/psapi.rar調試