|
@@ -0,0 +1,463 @@
|
|
|
+#include "StdAfx.h"
|
|
|
+#include "Assist.h"
|
|
|
+
|
|
|
+#include <D3D9.h>
|
|
|
+//#include <D3dx9tex.h>
|
|
|
+//#pragma comment(lib, "D3dx9.lib")
|
|
|
+
|
|
|
+// #pragma comment(lib, "d3d11.lib")
|
|
|
+// #pragma comment(lib, "dxgi.lib")
|
|
|
+
|
|
|
+namespace GAssist
|
|
|
+{
|
|
|
+ // 根据路径名查找进程,返回进程ID;
|
|
|
+ DWORD FindProcess(IN LPCSTR lpProName)
|
|
|
+ {
|
|
|
+ DWORD dwProcessID = 0;
|
|
|
+ PROCESSENTRY32 pe32 = { 0 };
|
|
|
+
|
|
|
+ HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
|
+ if (hProcessSnap == NULL)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ pe32.dwSize = sizeof(PROCESSENTRY32);
|
|
|
+
|
|
|
+ if (Process32First(hProcessSnap, &pe32)) {
|
|
|
+ do {
|
|
|
+ if (_tcscmp(lpProName, pe32.szExeFile) == 0) {
|
|
|
+ dwProcessID = pe32.th32ProcessID;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } while (Process32Next(hProcessSnap, &pe32));
|
|
|
+ }
|
|
|
+ CloseHandle(hProcessSnap);
|
|
|
+
|
|
|
+ return dwProcessID;
|
|
|
+ }
|
|
|
+
|
|
|
+ HWND GetProHwnd(DWORD dwProcessId)
|
|
|
+ {
|
|
|
+ DWORD dwPID = 0;
|
|
|
+ HWND hwndRet = NULL;
|
|
|
+ TCHAR szName[MAX_PATH] = {0};
|
|
|
+ TCHAR szClass[MAX_PATH] = {0};
|
|
|
+ TCHAR szLogMsg[MAX_PATH] = {0};
|
|
|
+ // 取得第一个窗口句柄
|
|
|
+ HWND hwndWindow = ::GetTopWindow(NULL);
|
|
|
+ // 遍历出结果窗口;
|
|
|
+ while (hwndWindow) {
|
|
|
+ dwPID = 0;
|
|
|
+ // 通过窗口句柄取得进程ID
|
|
|
+ DWORD dwTheardID = ::GetWindowThreadProcessId(hwndWindow, &dwPID);
|
|
|
+ if (dwTheardID != 0) {
|
|
|
+ // 判断和参数传入的进程ID是否相等
|
|
|
+ if (dwPID == dwProcessId) {
|
|
|
+ // 进程ID相等,则记录窗口句柄
|
|
|
+ hwndRet = hwndWindow;
|
|
|
+ //break; //存在Bug:有些进程有多个分离的窗口;
|
|
|
+ ::GetWindowText(hwndRet, szName, sizeof(szName) / sizeof(TCHAR));
|
|
|
+ ::GetClassName(hwndRet, szClass, sizeof(szClass) / sizeof(TCHAR)); // 窗口类
|
|
|
+ //TRACE3(_T("%s %s %s"), szClass, szName, "\n");
|
|
|
+ _stprintf_s(szLogMsg, _T("类名:%s, 窗口名:%s,窗口地址:%p \n"), szClass, szName, hwndRet);
|
|
|
+ OutputDebugString(szLogMsg);
|
|
|
+ if ( _tcsstr(szName, _T("大话水浒")) )
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 取得下一个窗口句柄
|
|
|
+ hwndWindow = ::GetNextWindow(hwndWindow, GW_HWNDNEXT);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 上面取得的窗口,不一定是最上层的窗口,需要通过GetParent获取最顶层窗口
|
|
|
+ HWND hwndWindowParent = NULL;
|
|
|
+ // 循环查找父窗口,以便保证返回的句柄是最顶层的窗口句柄
|
|
|
+ while (hwndRet != NULL) {
|
|
|
+ ::GetWindowText(hwndRet, szName, sizeof(szName) / sizeof(TCHAR));
|
|
|
+ ::GetClassName(hwndRet, szClass, sizeof(szClass) / sizeof(TCHAR)); // 窗口类
|
|
|
+ //TRACE3(_T("%s %s %s"), szClass, szName, "\n");
|
|
|
+ _stprintf_s(szLogMsg, _T("类名:%s, 窗口名:%s,窗口地址:%p \n"), szClass, szName, hwndRet);
|
|
|
+ OutputDebugString(szLogMsg);
|
|
|
+
|
|
|
+ hwndWindowParent = ::GetParent(hwndRet);
|
|
|
+ if (hwndWindowParent == NULL) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ hwndRet = hwndWindowParent;
|
|
|
+ }
|
|
|
+ // 返回窗口句柄
|
|
|
+ return hwndRet;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::vector<GameHwnd> g_vtGameHwnd;
|
|
|
+ BOOL CALLBACK EnumChildWindowCallBack(HWND hWnd, LPARAM lParam)
|
|
|
+ {
|
|
|
+ DWORD dwPid = 0;
|
|
|
+ GetWindowThreadProcessId(hWnd, &dwPid); // 获得找到窗口所属的进程
|
|
|
+ if (dwPid == lParam) // 判断是否是目标进程的窗口
|
|
|
+ {
|
|
|
+ TCHAR szName[MAX_PATH] = {0};
|
|
|
+ TCHAR szClass[MAX_PATH] = {0};
|
|
|
+ TCHAR szLogMsg[MAX_PATH] = {0};
|
|
|
+ ::GetWindowText(hWnd, szName, sizeof(szName) / sizeof(TCHAR));
|
|
|
+ ::GetClassName(hWnd, szClass, sizeof(szClass) / sizeof(TCHAR)); // 窗口类
|
|
|
+ DWORD dwId = ::GetDlgCtrlID(hWnd);
|
|
|
+ //TRACE3(_T("%s %s %s"), szClass, szName, "\n");
|
|
|
+ _stprintf_s(szLogMsg, _T("类名:%s, 窗口名:%s,ID:%d,窗口地址:%p \n"), szClass, szName, dwId, hWnd);
|
|
|
+ OutputDebugString(szLogMsg);
|
|
|
+
|
|
|
+ GameHwnd ghwnd;
|
|
|
+ ghwnd.dwId = dwId;
|
|
|
+ ghwnd.hwnd = hWnd;
|
|
|
+ ghwnd.strWinText = szName;
|
|
|
+ ghwnd.strClassName = szClass;
|
|
|
+ g_vtGameHwnd.push_back(ghwnd);
|
|
|
+
|
|
|
+ _tprintf_s(_T("0x%08X ") , hWnd); // 输出窗口信息
|
|
|
+ TCHAR buf[MAX_PATH];
|
|
|
+ SendMessage(hWnd, WM_GETTEXT, MAX_PATH, (LPARAM)buf);
|
|
|
+ _tprintf_s(_T("%s/n") , buf);
|
|
|
+ EnumChildWindows(hWnd, EnumChildWindowCallBack, lParam); // 递归查找子窗口
|
|
|
+ }
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // nStartCount:启动进程数量;
|
|
|
+ void StartGame(std::string strGameDir)
|
|
|
+ {
|
|
|
+ if ( !PathFileExists(strGameDir.c_str()) )
|
|
|
+ return;
|
|
|
+
|
|
|
+ SetCurrentDirectory(strGameDir.c_str());
|
|
|
+
|
|
|
+ ShellExecute(NULL, "open", GAssist::g_szGamePath, NULL, NULL, SW_SHOWNORMAL);//SW_HIDE无用,因为会自动结;
|
|
|
+ Sleep(1500); // Main.exe设置了陷阱(自己再开启了一个进程,结束上一个进程),需要等1.5秒;
|
|
|
+
|
|
|
+ DWORD dwProcId = GAssist::FindProcess(_T("Main.exe"));
|
|
|
+ if ( dwProcId <= 0 )
|
|
|
+ return;
|
|
|
+
|
|
|
+ EnumWindows(GAssist::EnumChildWindowCallBack, dwProcId);
|
|
|
+ if ( GAssist::g_vtGameHwnd.size() ) {
|
|
|
+ int nStatus = 0;
|
|
|
+ GAssist::GameHwnd* gp = NULL;
|
|
|
+ GAssist::GameHwnd* gbmin = NULL;
|
|
|
+ GAssist::GameHwnd* gbentry = NULL;
|
|
|
+ for ( std::vector<GAssist::GameHwnd>::iterator it = GAssist::g_vtGameHwnd.begin(); it != GAssist::g_vtGameHwnd.end(); it++ )
|
|
|
+ {
|
|
|
+ if ( nStatus >= 3 )
|
|
|
+ break;
|
|
|
+
|
|
|
+ if ( _tcsicmp(it->strWinText.c_str(), _T("最小化")) == 0 )
|
|
|
+ {
|
|
|
+ gbmin = &*it;
|
|
|
+ nStatus++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( _tcsicmp(it->strWinText.c_str(), _T("大话水浒")) == 0 )
|
|
|
+ {
|
|
|
+ gp = &*it;
|
|
|
+ nStatus++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( _tcsicmp(it->strWinText.c_str(), _T("进入游戏")) == 0 )
|
|
|
+ {
|
|
|
+ gbentry = &*it;
|
|
|
+ nStatus++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( gp && gbentry && gbmin) {
|
|
|
+ // 发送点击事件;
|
|
|
+ // 先最小化;
|
|
|
+ ::SendMessage(gp->hwnd,WM_COMMAND,gbmin->dwId,NULL);
|
|
|
+ // 再进入;
|
|
|
+ ::SendMessage(gp->hwnd,WM_COMMAND,gbentry->dwId,NULL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 使用WM_LBUTTONDBLCLK完全无效;
|
|
|
+ void MouseClick(HWND hwnd, POINT pt)
|
|
|
+ {
|
|
|
+ if ( !IsWindow(hwnd) )
|
|
|
+ return;
|
|
|
+
|
|
|
+ ::SetForegroundWindow(hwnd); // 窗口前置才能单击成功;
|
|
|
+ ::PostMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
|
|
|
+ ::PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(pt.x, pt.y));
|
|
|
+ OutputDebugString(_T("-------------------发送MouseClick\n"));
|
|
|
+ Sleep(200);
|
|
|
+ }
|
|
|
+
|
|
|
+ void MouseClick(HWND hwnd, unsigned int x, unsigned int y)
|
|
|
+ {
|
|
|
+ if ( !IsWindow(hwnd) )
|
|
|
+ return;
|
|
|
+
|
|
|
+ ::SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(x, y));
|
|
|
+ ::SendMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
|
|
|
+ Sleep(200);
|
|
|
+ }
|
|
|
+
|
|
|
+ void MouseMove(HWND hwnd, POINT pt)
|
|
|
+ {
|
|
|
+ if ( !IsWindow(hwnd) )
|
|
|
+ return;
|
|
|
+
|
|
|
+ ::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
|
|
|
+ Sleep(200);
|
|
|
+ }
|
|
|
+
|
|
|
+ void MouseMove(HWND hwnd, POINT ptStart, POINT ptEnd)
|
|
|
+ {
|
|
|
+ if ( !IsWindow(hwnd) )
|
|
|
+ return;
|
|
|
+
|
|
|
+ //::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, lparam);
|
|
|
+ ::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, MAKELPARAM(ptStart.x, ptStart.y));
|
|
|
+ Sleep(200);
|
|
|
+
|
|
|
+#if 1
|
|
|
+ // 计算个中间点;
|
|
|
+ POINT ptMid = { (ptStart.x + ptEnd.x) / 2, (ptStart.y + ptEnd.y) / 2};
|
|
|
+ ::SendMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(ptMid.x, ptMid.y));
|
|
|
+ Sleep(200);
|
|
|
+#endif
|
|
|
+
|
|
|
+ //::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, lparam);
|
|
|
+ ::SendMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(ptEnd.x, ptEnd.y));
|
|
|
+ Sleep(200);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 最后一步直接单击;
|
|
|
+ void MouseMoveEx(HWND hwnd, POINT ptStart, POINT ptEnd)
|
|
|
+ {
|
|
|
+ if ( !IsWindow(hwnd) )
|
|
|
+ return;
|
|
|
+
|
|
|
+ //::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, lparam);
|
|
|
+ ::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, MAKELPARAM(ptStart.x, ptStart.y));
|
|
|
+ Sleep(200);
|
|
|
+
|
|
|
+#if 1
|
|
|
+ // 计算个中间点;
|
|
|
+ POINT ptMid = { (ptStart.x + ptEnd.x) / 2, (ptStart.y + ptEnd.y) / 2};
|
|
|
+ ::SendMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(ptMid.x, ptMid.y));
|
|
|
+ Sleep(200);
|
|
|
+#endif
|
|
|
+
|
|
|
+ //::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, lparam);
|
|
|
+ ::SendMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(ptEnd.x, ptEnd.y));
|
|
|
+ Sleep(200);
|
|
|
+ MouseClick(hwnd, ptEnd);
|
|
|
+ }
|
|
|
+
|
|
|
+ void DragMouse(HWND hwnd, POINT ptStart, POINT ptEnd)
|
|
|
+ {
|
|
|
+ if ( !IsWindow(hwnd) )
|
|
|
+ return;
|
|
|
+
|
|
|
+#if 0
|
|
|
+ MouseClick(hwnd, ptStart);
|
|
|
+ // 按下鼠标左键;
|
|
|
+ ::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, MAKELPARAM(ptStart.x, ptStart.y));
|
|
|
+ //Sleep(200);
|
|
|
+
|
|
|
+ ::SendMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(ptEnd.x, ptEnd.y));
|
|
|
+ Sleep(200);
|
|
|
+#else
|
|
|
+ ::PostMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(ptStart.x, ptStart.y));
|
|
|
+
|
|
|
+ ::PostMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, MAKELPARAM(ptEnd.x, ptEnd.y));
|
|
|
+
|
|
|
+ ::PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(ptEnd.x, ptEnd.y));
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+ // 截图;
|
|
|
+ HBITMAP CopyDC2Bitmap(HWND hWnd, LPRECT lpRect)
|
|
|
+ {
|
|
|
+ if ( !lpRect || IsRectEmpty(lpRect) )
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ HDC hWndDC = ::GetWindowDC(hWnd);
|
|
|
+ //HDC hWndDC = ::GetDC(hWnd);
|
|
|
+ // 创建兼容DC;
|
|
|
+ HDC hMemDC = CreateCompatibleDC(hWndDC);
|
|
|
+ CRect rc(lpRect->top, lpRect->left, lpRect->right, lpRect->bottom);
|
|
|
+ //::ClientToScreen(hWnd, &rc);
|
|
|
+ HBITMAP hOldBitmap, hMenBitmap;
|
|
|
+ int top = 0, left = 0, right = 0, bottom = 0;
|
|
|
+ int nWidth = 0, nHeight = 0;
|
|
|
+
|
|
|
+ top = lpRect->top;
|
|
|
+ left = lpRect->left;
|
|
|
+ right = lpRect->right;
|
|
|
+ bottom = lpRect->bottom;
|
|
|
+
|
|
|
+ nWidth = right - left;
|
|
|
+ nHeight = bottom - top;
|
|
|
+
|
|
|
+ // 创建兼容DC;
|
|
|
+ hMenBitmap = CreateCompatibleBitmap(hWndDC, nWidth, nHeight);
|
|
|
+
|
|
|
+ hOldBitmap = (HBITMAP)SelectObject(hMemDC, hMenBitmap);
|
|
|
+ ::PrintWindow(hWnd, hMemDC, 0);
|
|
|
+ // 将窗口DC内存复制到兼容DC上;
|
|
|
+ StretchBlt(hMemDC, 0, 0, nWidth, nHeight, hWndDC, left, top, nWidth, nHeight, SRCCOPY);
|
|
|
+ //BitBlt(hMemDC, 0, 0, nWidth, nHeight, hWndDC, left, top, SRCCOPY);
|
|
|
+ hMenBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
|
|
|
+
|
|
|
+ DeleteDC(hMemDC);
|
|
|
+ DeleteObject(hOldBitmap);
|
|
|
+
|
|
|
+ return hMenBitmap;
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL SaveBitmap(HBITMAP hBitmpa, std::string strSavePath)
|
|
|
+ {
|
|
|
+ //把位图的信息保存到bmpinfo;
|
|
|
+ BITMAP bmpinfo;
|
|
|
+ GetObject(hBitmpa,sizeof(BITMAP),&bmpinfo);
|
|
|
+ DWORD dwBmBitsSize = ((bmpinfo.bmWidth * 32+31)/32) * 4 * bmpinfo.bmHeight;
|
|
|
+ //位图文件头 14字节
|
|
|
+ BITMAPFILEHEADER bf;
|
|
|
+ bf.bfType = 0x4D42;
|
|
|
+ //BM
|
|
|
+ bf.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize;
|
|
|
+ bf.bfReserved1 = 0;
|
|
|
+ bf.bfReserved2 = 0;
|
|
|
+ bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
|
|
|
+ //位图信息头
|
|
|
+ BITMAPINFOHEADER bi;
|
|
|
+ bi.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
+ bi.biWidth = bmpinfo.bmWidth;
|
|
|
+ bi.biHeight = bmpinfo.bmHeight;
|
|
|
+ bi.biPlanes = 1;
|
|
|
+ bi.biBitCount = 32;
|
|
|
+ bi.biCompression = BI_RGB;
|
|
|
+ bi.biSizeImage = 0;
|
|
|
+ bi.biXPelsPerMeter = 0;
|
|
|
+ bi.biYPelsPerMeter = 0;
|
|
|
+ bi.biClrUsed = 8;
|
|
|
+ bi.biClrImportant = 0;
|
|
|
+ //位图数据;
|
|
|
+ char* context = new char[dwBmBitsSize];
|
|
|
+ HDC dc = ::GetDC(NULL);
|
|
|
+ GetDIBits(dc, hBitmpa, 0, bi.biHeight, context, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
|
|
|
+ FILE* f = fopen(strSavePath.c_str(),"wb");
|
|
|
+ fwrite((char*)&bf,sizeof(BITMAPFILEHEADER),1,f);
|
|
|
+ fwrite((char*)&bi,sizeof(BITMAPINFOHEADER),1,f);
|
|
|
+ fwrite(context,dwBmBitsSize,1,f);
|
|
|
+ fclose(f);
|
|
|
+ delete context;
|
|
|
+ ::ReleaseDC(NULL,dc);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ void SaveHwndToBmpFile(HWND hWnd, LPCTSTR lpszPath) {
|
|
|
+ HDC hDC = ::GetWindowDC(hWnd);
|
|
|
+ ASSERT(hDC);
|
|
|
+ HDC hMemDC = ::CreateCompatibleDC(hDC);
|
|
|
+ ASSERT(hMemDC);
|
|
|
+
|
|
|
+ RECT rc;
|
|
|
+ ::GetWindowRect(hWnd, &rc);
|
|
|
+ HBITMAP hBitmap = ::CreateCompatibleBitmap(hDC, rc.right - rc.left, rc.bottom - rc.top);
|
|
|
+
|
|
|
+ ASSERT(hBitmap);
|
|
|
+ HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC, hBitmap);
|
|
|
+ ::PrintWindow(hWnd, hMemDC, 0);
|
|
|
+ BITMAP bitmap = {0};
|
|
|
+ ::GetObject(hBitmap, sizeof(BITMAP), &bitmap);
|
|
|
+ BITMAPINFOHEADER bi = {0};
|
|
|
+ BITMAPFILEHEADER bf = {0};
|
|
|
+ CONST int nBitCount = 24;
|
|
|
+ bi.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
+ bi.biWidth = bitmap.bmWidth;
|
|
|
+ bi.biHeight = bitmap.bmHeight;
|
|
|
+ bi.biPlanes = 1;
|
|
|
+ bi.biBitCount = nBitCount;
|
|
|
+ bi.biCompression = BI_RGB;
|
|
|
+ DWORD dwSize = ((bitmap.bmWidth * nBitCount + 31) / 32) * 4 * bitmap.bmHeight;
|
|
|
+ HANDLE hDib = GlobalAlloc(GHND, dwSize + sizeof(BITMAPINFOHEADER));
|
|
|
+ LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
|
|
|
+ *lpbi = bi;
|
|
|
+ ::GetDIBits(hMemDC, hBitmap, 0, bitmap.bmHeight, (BYTE*)lpbi + sizeof(BITMAPINFOHEADER), (BITMAPINFO*)lpbi, DIB_RGB_COLORS);
|
|
|
+ try
|
|
|
+ {
|
|
|
+ CFile file;
|
|
|
+ file.Open(lpszPath, CFile::modeCreate | CFile::modeWrite);
|
|
|
+ bf.bfType = 0x4d42;
|
|
|
+ dwSize += sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
|
|
|
+ bf.bfSize = dwSize;
|
|
|
+ bf.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
|
|
|
+ file.Write((BYTE*)&bf, sizeof(BITMAPFILEHEADER));
|
|
|
+ file.Write((BYTE*)lpbi, dwSize);
|
|
|
+ file.Close();
|
|
|
+ }
|
|
|
+ catch(CFileException* e)
|
|
|
+ {
|
|
|
+ e->ReportError();
|
|
|
+ e->Delete();
|
|
|
+ }
|
|
|
+ GlobalUnlock(hDib);
|
|
|
+ GlobalFree(hDib);
|
|
|
+ ::SelectObject(hMemDC, hOldBmp);
|
|
|
+ ::DeleteObject(hBitmap);
|
|
|
+ ::DeleteObject(hMemDC);
|
|
|
+ ::ReleaseDC(hWnd, hDC);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+// #include <D3D9.h>
|
|
|
+// #include <D3dx9tex.h>
|
|
|
+// #pragma comment(lib, "D3dx9.lib")
|
|
|
+ //#include <d3d9helper>
|
|
|
+ BOOL ScreenShot(LPDIRECT3DDEVICE9 lpDevice, HWND hWnd, TCHAR* fileName)
|
|
|
+ {
|
|
|
+ HRESULT hr;
|
|
|
+ // Get adapter display mode
|
|
|
+ D3DDISPLAYMODE mode;
|
|
|
+ if (FAILED(hr = lpDevice->GetDisplayMode(0, &mode)))
|
|
|
+ return hr;
|
|
|
+
|
|
|
+ // Create the surface to hold the screen image data
|
|
|
+ LPDIRECT3DSURFACE9 surf;
|
|
|
+ if (FAILED(hr = lpDevice->CreateOffscreenPlainSurface(mode.Width,
|
|
|
+ mode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL))) //注意第四个参数不能是D3DPOOL_DEFAULT
|
|
|
+ {
|
|
|
+ return hr;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the screen data
|
|
|
+ if (FAILED(hr = lpDevice->GetFrontBufferData(0, surf)))
|
|
|
+ {
|
|
|
+ surf->Release();
|
|
|
+ return hr;
|
|
|
+ }
|
|
|
+
|
|
|
+ // area to capture
|
|
|
+ RECT* rect = NULL;
|
|
|
+
|
|
|
+ WINDOWINFO windowInfo;
|
|
|
+ windowInfo.cbSize = sizeof(WINDOWINFO);
|
|
|
+
|
|
|
+ if (hWnd) // capture window
|
|
|
+ {
|
|
|
+ GetWindowInfo(hWnd, &windowInfo);
|
|
|
+ rect = &windowInfo.rcWindow;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Save the screen date to file
|
|
|
+ //hr = D3DXSaveSurfaceToFile(fileName, D3DXIFF_BMP, surf, NULL, rect);
|
|
|
+
|
|
|
+ surf->Release();
|
|
|
+
|
|
|
+ return hr;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|