Assist.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. #include "StdAfx.h"
  2. #include "Assist.h"
  3. #include <D3D9.h>
  4. //#include <D3dx9tex.h>
  5. //#pragma comment(lib, "D3dx9.lib")
  6. // #pragma comment(lib, "d3d11.lib")
  7. // #pragma comment(lib, "dxgi.lib")
  8. namespace GAssist
  9. {
  10. // 根据路径名查找进程,返回进程ID;
  11. DWORD FindProcess(IN LPCSTR lpProName)
  12. {
  13. DWORD dwProcessID = 0;
  14. PROCESSENTRY32 pe32 = { 0 };
  15. HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  16. if (hProcessSnap == NULL)
  17. {
  18. return 0;
  19. }
  20. pe32.dwSize = sizeof(PROCESSENTRY32);
  21. if (Process32First(hProcessSnap, &pe32)) {
  22. do {
  23. if (_tcscmp(lpProName, pe32.szExeFile) == 0) {
  24. dwProcessID = pe32.th32ProcessID;
  25. break;
  26. }
  27. } while (Process32Next(hProcessSnap, &pe32));
  28. }
  29. CloseHandle(hProcessSnap);
  30. return dwProcessID;
  31. }
  32. HWND GetProHwnd(DWORD dwProcessId)
  33. {
  34. DWORD dwPID = 0;
  35. HWND hwndRet = NULL;
  36. TCHAR szName[MAX_PATH] = {0};
  37. TCHAR szClass[MAX_PATH] = {0};
  38. TCHAR szLogMsg[MAX_PATH] = {0};
  39. // 取得第一个窗口句柄
  40. HWND hwndWindow = ::GetTopWindow(NULL);
  41. // 遍历出结果窗口;
  42. while (hwndWindow) {
  43. dwPID = 0;
  44. // 通过窗口句柄取得进程ID
  45. DWORD dwTheardID = ::GetWindowThreadProcessId(hwndWindow, &dwPID);
  46. if (dwTheardID != 0) {
  47. // 判断和参数传入的进程ID是否相等
  48. if (dwPID == dwProcessId) {
  49. // 进程ID相等,则记录窗口句柄
  50. hwndRet = hwndWindow;
  51. //break; //存在Bug:有些进程有多个分离的窗口;
  52. ::GetWindowText(hwndRet, szName, sizeof(szName) / sizeof(TCHAR));
  53. ::GetClassName(hwndRet, szClass, sizeof(szClass) / sizeof(TCHAR)); // 窗口类
  54. //TRACE3(_T("%s %s %s"), szClass, szName, "\n");
  55. _stprintf_s(szLogMsg, _T("类名:%s, 窗口名:%s,窗口地址:%p \n"), szClass, szName, hwndRet);
  56. OutputDebugString(szLogMsg);
  57. if ( _tcsstr(szName, _T("大话水浒")) )
  58. break;
  59. }
  60. }
  61. // 取得下一个窗口句柄
  62. hwndWindow = ::GetNextWindow(hwndWindow, GW_HWNDNEXT);
  63. }
  64. // 上面取得的窗口,不一定是最上层的窗口,需要通过GetParent获取最顶层窗口
  65. HWND hwndWindowParent = NULL;
  66. // 循环查找父窗口,以便保证返回的句柄是最顶层的窗口句柄
  67. while (hwndRet != NULL) {
  68. ::GetWindowText(hwndRet, szName, sizeof(szName) / sizeof(TCHAR));
  69. ::GetClassName(hwndRet, szClass, sizeof(szClass) / sizeof(TCHAR)); // 窗口类
  70. //TRACE3(_T("%s %s %s"), szClass, szName, "\n");
  71. _stprintf_s(szLogMsg, _T("类名:%s, 窗口名:%s,窗口地址:%p \n"), szClass, szName, hwndRet);
  72. OutputDebugString(szLogMsg);
  73. hwndWindowParent = ::GetParent(hwndRet);
  74. if (hwndWindowParent == NULL) {
  75. break;
  76. }
  77. hwndRet = hwndWindowParent;
  78. }
  79. // 返回窗口句柄
  80. return hwndRet;
  81. }
  82. std::vector<GameHwnd> g_vtGameHwnd;
  83. BOOL CALLBACK EnumChildWindowCallBack(HWND hWnd, LPARAM lParam)
  84. {
  85. DWORD dwPid = 0;
  86. GetWindowThreadProcessId(hWnd, &dwPid); // 获得找到窗口所属的进程
  87. if (dwPid == lParam) // 判断是否是目标进程的窗口
  88. {
  89. TCHAR szName[MAX_PATH] = {0};
  90. TCHAR szClass[MAX_PATH] = {0};
  91. TCHAR szLogMsg[MAX_PATH] = {0};
  92. ::GetWindowText(hWnd, szName, sizeof(szName) / sizeof(TCHAR));
  93. ::GetClassName(hWnd, szClass, sizeof(szClass) / sizeof(TCHAR)); // 窗口类
  94. DWORD dwId = ::GetDlgCtrlID(hWnd);
  95. //TRACE3(_T("%s %s %s"), szClass, szName, "\n");
  96. _stprintf_s(szLogMsg, _T("类名:%s, 窗口名:%s,ID:%d,窗口地址:%p \n"), szClass, szName, dwId, hWnd);
  97. OutputDebugString(szLogMsg);
  98. GameHwnd ghwnd;
  99. ghwnd.dwId = dwId;
  100. ghwnd.hwnd = hWnd;
  101. ghwnd.strWinText = szName;
  102. ghwnd.strClassName = szClass;
  103. g_vtGameHwnd.push_back(ghwnd);
  104. _tprintf_s(_T("0x%08X ") , hWnd); // 输出窗口信息
  105. TCHAR buf[MAX_PATH];
  106. SendMessage(hWnd, WM_GETTEXT, MAX_PATH, (LPARAM)buf);
  107. _tprintf_s(_T("%s/n") , buf);
  108. EnumChildWindows(hWnd, EnumChildWindowCallBack, lParam); // 递归查找子窗口
  109. }
  110. return TRUE;
  111. }
  112. // nStartCount:启动进程数量;
  113. void StartGame(std::string strGameDir)
  114. {
  115. if ( !PathFileExists(strGameDir.c_str()) )
  116. return;
  117. SetCurrentDirectory(strGameDir.c_str());
  118. ShellExecute(NULL, "open", GAssist::g_szGamePath, NULL, NULL, SW_SHOWNORMAL);//SW_HIDE无用,因为会自动结;
  119. Sleep(1500); // Main.exe设置了陷阱(自己再开启了一个进程,结束上一个进程),需要等1.5秒;
  120. DWORD dwProcId = GAssist::FindProcess(_T("Main.exe"));
  121. if ( dwProcId <= 0 )
  122. return;
  123. EnumWindows(GAssist::EnumChildWindowCallBack, dwProcId);
  124. if ( GAssist::g_vtGameHwnd.size() ) {
  125. int nStatus = 0;
  126. GAssist::GameHwnd* gp = NULL;
  127. GAssist::GameHwnd* gbmin = NULL;
  128. GAssist::GameHwnd* gbentry = NULL;
  129. for ( std::vector<GAssist::GameHwnd>::iterator it = GAssist::g_vtGameHwnd.begin(); it != GAssist::g_vtGameHwnd.end(); it++ )
  130. {
  131. if ( nStatus >= 3 )
  132. break;
  133. if ( _tcsicmp(it->strWinText.c_str(), _T("最小化")) == 0 )
  134. {
  135. gbmin = &*it;
  136. nStatus++;
  137. }
  138. if ( _tcsicmp(it->strWinText.c_str(), _T("大话水浒")) == 0 )
  139. {
  140. gp = &*it;
  141. nStatus++;
  142. }
  143. if ( _tcsicmp(it->strWinText.c_str(), _T("进入游戏")) == 0 )
  144. {
  145. gbentry = &*it;
  146. nStatus++;
  147. }
  148. }
  149. if ( gp && gbentry && gbmin) {
  150. // 发送点击事件;
  151. // 先最小化;
  152. ::SendMessage(gp->hwnd,WM_COMMAND,gbmin->dwId,NULL);
  153. // 再进入;
  154. ::SendMessage(gp->hwnd,WM_COMMAND,gbentry->dwId,NULL);
  155. }
  156. }
  157. }
  158. // 使用WM_LBUTTONDBLCLK完全无效;
  159. void MouseClick(HWND hwnd, POINT pt)
  160. {
  161. if ( !IsWindow(hwnd) )
  162. return;
  163. ::SetForegroundWindow(hwnd); // 窗口前置才能单击成功;
  164. ::PostMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
  165. ::PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(pt.x, pt.y));
  166. OutputDebugString(_T("-------------------发送MouseClick\n"));
  167. Sleep(200);
  168. }
  169. void MouseClick(HWND hwnd, unsigned int x, unsigned int y)
  170. {
  171. if ( !IsWindow(hwnd) )
  172. return;
  173. ::SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(x, y));
  174. ::SendMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
  175. Sleep(200);
  176. }
  177. void MouseMove(HWND hwnd, POINT pt)
  178. {
  179. if ( !IsWindow(hwnd) )
  180. return;
  181. ::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
  182. Sleep(200);
  183. }
  184. void MouseMove(HWND hwnd, POINT ptStart, POINT ptEnd)
  185. {
  186. if ( !IsWindow(hwnd) )
  187. return;
  188. //::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, lparam);
  189. ::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, MAKELPARAM(ptStart.x, ptStart.y));
  190. Sleep(200);
  191. #if 1
  192. // 计算个中间点;
  193. POINT ptMid = { (ptStart.x + ptEnd.x) / 2, (ptStart.y + ptEnd.y) / 2};
  194. ::SendMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(ptMid.x, ptMid.y));
  195. Sleep(200);
  196. #endif
  197. //::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, lparam);
  198. ::SendMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(ptEnd.x, ptEnd.y));
  199. Sleep(200);
  200. }
  201. // 最后一步直接单击;
  202. void MouseMoveEx(HWND hwnd, POINT ptStart, POINT ptEnd)
  203. {
  204. if ( !IsWindow(hwnd) )
  205. return;
  206. //::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, lparam);
  207. ::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, MAKELPARAM(ptStart.x, ptStart.y));
  208. Sleep(200);
  209. #if 1
  210. // 计算个中间点;
  211. POINT ptMid = { (ptStart.x + ptEnd.x) / 2, (ptStart.y + ptEnd.y) / 2};
  212. ::SendMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(ptMid.x, ptMid.y));
  213. Sleep(200);
  214. #endif
  215. //::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, lparam);
  216. ::SendMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(ptEnd.x, ptEnd.y));
  217. Sleep(200);
  218. MouseClick(hwnd, ptEnd);
  219. }
  220. void DragMouse(HWND hwnd, POINT ptStart, POINT ptEnd)
  221. {
  222. if ( !IsWindow(hwnd) )
  223. return;
  224. #if 0
  225. MouseClick(hwnd, ptStart);
  226. // 按下鼠标左键;
  227. ::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, MAKELPARAM(ptStart.x, ptStart.y));
  228. //Sleep(200);
  229. ::SendMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(ptEnd.x, ptEnd.y));
  230. Sleep(200);
  231. #else
  232. ::PostMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(ptStart.x, ptStart.y));
  233. ::PostMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, MAKELPARAM(ptEnd.x, ptEnd.y));
  234. ::PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(ptEnd.x, ptEnd.y));
  235. #endif
  236. }
  237. // 截图;
  238. HBITMAP CopyDC2Bitmap(HWND hWnd, LPRECT lpRect)
  239. {
  240. if ( !lpRect || IsRectEmpty(lpRect) )
  241. return NULL;
  242. HDC hWndDC = ::GetWindowDC(hWnd);
  243. //HDC hWndDC = ::GetDC(hWnd);
  244. // 创建兼容DC;
  245. HDC hMemDC = CreateCompatibleDC(hWndDC);
  246. CRect rc(lpRect->top, lpRect->left, lpRect->right, lpRect->bottom);
  247. //::ClientToScreen(hWnd, &rc);
  248. HBITMAP hOldBitmap, hMenBitmap;
  249. int top = 0, left = 0, right = 0, bottom = 0;
  250. int nWidth = 0, nHeight = 0;
  251. top = lpRect->top;
  252. left = lpRect->left;
  253. right = lpRect->right;
  254. bottom = lpRect->bottom;
  255. nWidth = right - left;
  256. nHeight = bottom - top;
  257. // 创建兼容DC;
  258. hMenBitmap = CreateCompatibleBitmap(hWndDC, nWidth, nHeight);
  259. hOldBitmap = (HBITMAP)SelectObject(hMemDC, hMenBitmap);
  260. ::PrintWindow(hWnd, hMemDC, 0);
  261. // 将窗口DC内存复制到兼容DC上;
  262. StretchBlt(hMemDC, 0, 0, nWidth, nHeight, hWndDC, left, top, nWidth, nHeight, SRCCOPY);
  263. //BitBlt(hMemDC, 0, 0, nWidth, nHeight, hWndDC, left, top, SRCCOPY);
  264. hMenBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
  265. DeleteDC(hMemDC);
  266. DeleteObject(hOldBitmap);
  267. return hMenBitmap;
  268. }
  269. BOOL SaveBitmap(HBITMAP hBitmpa, std::string strSavePath)
  270. {
  271. //把位图的信息保存到bmpinfo;
  272. BITMAP bmpinfo;
  273. GetObject(hBitmpa,sizeof(BITMAP),&bmpinfo);
  274. DWORD dwBmBitsSize = ((bmpinfo.bmWidth * 32+31)/32) * 4 * bmpinfo.bmHeight;
  275. //位图文件头 14字节
  276. BITMAPFILEHEADER bf;
  277. bf.bfType = 0x4D42;
  278. //BM
  279. bf.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize;
  280. bf.bfReserved1 = 0;
  281. bf.bfReserved2 = 0;
  282. bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  283. //位图信息头
  284. BITMAPINFOHEADER bi;
  285. bi.biSize = sizeof(BITMAPINFOHEADER);
  286. bi.biWidth = bmpinfo.bmWidth;
  287. bi.biHeight = bmpinfo.bmHeight;
  288. bi.biPlanes = 1;
  289. bi.biBitCount = 32;
  290. bi.biCompression = BI_RGB;
  291. bi.biSizeImage = 0;
  292. bi.biXPelsPerMeter = 0;
  293. bi.biYPelsPerMeter = 0;
  294. bi.biClrUsed = 8;
  295. bi.biClrImportant = 0;
  296. //位图数据;
  297. char* context = new char[dwBmBitsSize];
  298. HDC dc = ::GetDC(NULL);
  299. GetDIBits(dc, hBitmpa, 0, bi.biHeight, context, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
  300. FILE* f = fopen(strSavePath.c_str(),"wb");
  301. fwrite((char*)&bf,sizeof(BITMAPFILEHEADER),1,f);
  302. fwrite((char*)&bi,sizeof(BITMAPINFOHEADER),1,f);
  303. fwrite(context,dwBmBitsSize,1,f);
  304. fclose(f);
  305. delete context;
  306. ::ReleaseDC(NULL,dc);
  307. return 0;
  308. }
  309. void SaveHwndToBmpFile(HWND hWnd, LPCTSTR lpszPath) {
  310. HDC hDC = ::GetWindowDC(hWnd);
  311. ASSERT(hDC);
  312. HDC hMemDC = ::CreateCompatibleDC(hDC);
  313. ASSERT(hMemDC);
  314. RECT rc;
  315. ::GetWindowRect(hWnd, &rc);
  316. HBITMAP hBitmap = ::CreateCompatibleBitmap(hDC, rc.right - rc.left, rc.bottom - rc.top);
  317. ASSERT(hBitmap);
  318. HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC, hBitmap);
  319. ::PrintWindow(hWnd, hMemDC, 0);
  320. BITMAP bitmap = {0};
  321. ::GetObject(hBitmap, sizeof(BITMAP), &bitmap);
  322. BITMAPINFOHEADER bi = {0};
  323. BITMAPFILEHEADER bf = {0};
  324. CONST int nBitCount = 24;
  325. bi.biSize = sizeof(BITMAPINFOHEADER);
  326. bi.biWidth = bitmap.bmWidth;
  327. bi.biHeight = bitmap.bmHeight;
  328. bi.biPlanes = 1;
  329. bi.biBitCount = nBitCount;
  330. bi.biCompression = BI_RGB;
  331. DWORD dwSize = ((bitmap.bmWidth * nBitCount + 31) / 32) * 4 * bitmap.bmHeight;
  332. HANDLE hDib = GlobalAlloc(GHND, dwSize + sizeof(BITMAPINFOHEADER));
  333. LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
  334. *lpbi = bi;
  335. ::GetDIBits(hMemDC, hBitmap, 0, bitmap.bmHeight, (BYTE*)lpbi + sizeof(BITMAPINFOHEADER), (BITMAPINFO*)lpbi, DIB_RGB_COLORS);
  336. try
  337. {
  338. CFile file;
  339. file.Open(lpszPath, CFile::modeCreate | CFile::modeWrite);
  340. bf.bfType = 0x4d42;
  341. dwSize += sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  342. bf.bfSize = dwSize;
  343. bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  344. file.Write((BYTE*)&bf, sizeof(BITMAPFILEHEADER));
  345. file.Write((BYTE*)lpbi, dwSize);
  346. file.Close();
  347. }
  348. catch(CFileException* e)
  349. {
  350. e->ReportError();
  351. e->Delete();
  352. }
  353. GlobalUnlock(hDib);
  354. GlobalFree(hDib);
  355. ::SelectObject(hMemDC, hOldBmp);
  356. ::DeleteObject(hBitmap);
  357. ::DeleteObject(hMemDC);
  358. ::ReleaseDC(hWnd, hDC);
  359. }
  360. // #include <D3D9.h>
  361. // #include <D3dx9tex.h>
  362. // #pragma comment(lib, "D3dx9.lib")
  363. //#include <d3d9helper>
  364. BOOL ScreenShot(LPDIRECT3DDEVICE9 lpDevice, HWND hWnd, TCHAR* fileName)
  365. {
  366. HRESULT hr;
  367. // Get adapter display mode
  368. D3DDISPLAYMODE mode;
  369. if (FAILED(hr = lpDevice->GetDisplayMode(0, &mode)))
  370. return hr;
  371. // Create the surface to hold the screen image data
  372. LPDIRECT3DSURFACE9 surf;
  373. if (FAILED(hr = lpDevice->CreateOffscreenPlainSurface(mode.Width,
  374. mode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL))) //注意第四个参数不能是D3DPOOL_DEFAULT
  375. {
  376. return hr;
  377. }
  378. // Get the screen data
  379. if (FAILED(hr = lpDevice->GetFrontBufferData(0, surf)))
  380. {
  381. surf->Release();
  382. return hr;
  383. }
  384. // area to capture
  385. RECT* rect = NULL;
  386. WINDOWINFO windowInfo;
  387. windowInfo.cbSize = sizeof(WINDOWINFO);
  388. if (hWnd) // capture window
  389. {
  390. GetWindowInfo(hWnd, &windowInfo);
  391. rect = &windowInfo.rcWindow;
  392. }
  393. // Save the screen date to file
  394. //hr = D3DXSaveSurfaceToFile(fileName, D3DXIFF_BMP, surf, NULL, rect);
  395. surf->Release();
  396. return hr;
  397. }
  398. }