123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281 |
- #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
- {
- int frameWidth = 2;
- int titleBarHeight = 25;
- TCHAR g_szCurModuleFileName[MAX_PATH];
- TCHAR g_szCurModuleDir[MAX_PATH];
- TCHAR g_szCurModulePath[MAX_PATH];
- TCHAR g_szFna[_MAX_FNAME];
- TCHAR g_szExt[_MAX_EXT];
- TCHAR g_szAssistConfig[MAX_PATH];
- std::string g_strAppdir;
- std::string g_strGameDir;
- TCHAR g_szGameApp[MAX_PATH];
- std::map<byte, byte> vsKey;
- std::vector<GWnd> g_vtGWnd;
- int nGameWndType;
- void Init()
- {
- TCHAR szDrive[_MAX_DRIVE] = { 0 };
- TCHAR szDir[_MAX_DIR] = { 0 };
- TCHAR szFna[_MAX_FNAME] = { 0 };
- TCHAR szExt[_MAX_EXT] = { 0 };
- DWORD dwRet = ::GetModuleFileName(NULL, g_szCurModuleFileName, sizeof(g_szCurModuleFileName) / sizeof(TCHAR));
- _tsplitpath_s(g_szCurModuleFileName, szDrive, szDir, g_szFna, g_szExt);
- _tcscat_s(g_szCurModuleDir, MAX_PATH, szDrive);
- _tcscat_s(g_szCurModuleDir, MAX_PATH, szDir);
- g_strAppdir = g_szCurModuleDir;
- _stprintf_s(g_szAssistConfig, _T("%s%s"), g_szCurModuleDir, _T("Assist.ini"));
- // 插入map;
- // https://blog.csdn.net/xiadasong007/article/details/5026948?utm_source=blogxgwz0;
- vsKey.insert(std::pair<byte, byte>(VK_F1, 0x3B));
- vsKey.insert(std::pair<byte, byte>(VK_F2, 0x3C));
- vsKey.insert(std::pair<byte, byte>(VK_F3, 0x3D));
- vsKey.insert(std::pair<byte, byte>(VK_F4, 0x3E));
- vsKey.insert(std::pair<byte, byte>(VK_F5, 0x3F));
- vsKey.insert(std::pair<byte, byte>(VK_F6, 0x40));
- vsKey.insert(std::pair<byte, byte>(VK_F7, 0x41));
- vsKey.insert(std::pair<byte, byte>(VK_F8, 0x42));
- vsKey.insert(std::pair<byte, byte>(VK_F9, 0x43));
- vsKey.insert(std::pair<byte, byte>(VK_F10, 0x44));
- vsKey.insert(std::pair<byte, byte>(VK_F11, 0x57));
- vsKey.insert(std::pair<byte, byte>(VK_F12, 0x58));
- vsKey.insert(std::pair<byte, byte>(VK_NUMLOCK, 0x45));
- vsKey.insert(std::pair<byte, byte>(VK_SCROLL, 0x46));
- vsKey.insert(std::pair<byte, byte>(VK_LSHIFT, 0x2A));
- vsKey.insert(std::pair<byte, byte>(VK_RSHIFT, 0x36));
- vsKey.insert(std::pair<byte, byte>(VK_LCONTROL, 0x1D));
- vsKey.insert(std::pair<byte, byte>(VK_RCONTROL, 0x58));
- vsKey.insert(std::pair<byte, byte>(VK_LMENU, 0x38));
- vsKey.insert(std::pair<byte, byte>(VK_RMENU, 0x58));
- vsKey.insert(std::pair<byte, byte>(VK_BACK, 0x0E)); // V;
- vsKey.insert(std::pair<byte, byte>(VK_TAB, 0x0F)); // V;
- vsKey.insert(std::pair<byte, byte>(VK_RETURN, 0x1C)); // V;
- vsKey.insert(std::pair<byte, byte>(VK_SHIFT, 0x2F)); // V;
- vsKey.insert(std::pair<byte, byte>(VK_CONTROL, 0x2F)); // V;
- vsKey.insert(std::pair<byte, byte>(VK_MENU, 0x2F)); // Alt;
- vsKey.insert(std::pair<byte, byte>(VK_PAUSE, 0x2F)); // V;
- vsKey.insert(std::pair<byte, byte>(VK_CAPITAL, 0x3A)); // V;
- vsKey.insert(std::pair<byte, byte>(VK_ESCAPE, 0x01)); // V;
- vsKey.insert(std::pair<byte, byte>(VK_SPACE, 0x39)); // 空格;
- // 方向键;
- vsKey.insert(std::pair<byte, byte>(VK_END, 0x0E)); // 空格;
- vsKey.insert(std::pair<byte, byte>(VK_HOME, 0x0E)); // 空格;
- vsKey.insert(std::pair<byte, byte>(VK_LEFT, 0x0E)); // 空格;
- vsKey.insert(std::pair<byte, byte>(VK_UP, 0x0E)); // 空格;
- vsKey.insert(std::pair<byte, byte>(VK_RIGHT, 0x0E)); // 空格;
- vsKey.insert(std::pair<byte, byte>(VK_DOWN, 0x0E)); // 空格;
- // 系统功能键;
- vsKey.insert(std::pair<byte, byte>(VK_PRINT, 0x54)); // 空格;
- vsKey.insert(std::pair<byte, byte>(VK_SNAPSHOT, 0x0E)); // 空格;
- vsKey.insert(std::pair<byte, byte>(VK_INSERT, 0x0E)); // 空格;
- vsKey.insert(std::pair<byte, byte>(VK_DELETE, 0x0E)); // 空格;
- vsKey.insert(std::pair<byte, byte>(VK_LWIN, 0x0E)); // 空格;
- vsKey.insert(std::pair<byte, byte>(VK_RWIN, 0x0E)); // 空格;
- // 小键盘;
- vsKey.insert(std::pair<byte, byte>(VK_NUMPAD0, 0x52));
- vsKey.insert(std::pair<byte, byte>(VK_NUMPAD1, 0x4F));
- vsKey.insert(std::pair<byte, byte>(VK_NUMPAD2, 0x50));
- vsKey.insert(std::pair<byte, byte>(VK_NUMPAD3, 0x51));
- vsKey.insert(std::pair<byte, byte>(VK_NUMPAD4, 0x4B));
- vsKey.insert(std::pair<byte, byte>(VK_NUMPAD5, 0x4C));
- vsKey.insert(std::pair<byte, byte>(VK_NUMPAD6, 0x4D));
- vsKey.insert(std::pair<byte, byte>(VK_NUMPAD7, 0x47));
- vsKey.insert(std::pair<byte, byte>(VK_NUMPAD8, 0x48));
- vsKey.insert(std::pair<byte, byte>(VK_NUMPAD9, 0x49));
- vsKey.insert(std::pair<byte, byte>(VK_MULTIPLY, 0x37));
- vsKey.insert(std::pair<byte, byte>(VK_ADD, 0x4E));
- vsKey.insert(std::pair<byte, byte>(VK_SEPARATOR, 0x0E));
- vsKey.insert(std::pair<byte, byte>(VK_SUBTRACT, 0x4A));
- vsKey.insert(std::pair<byte, byte>(VK_DECIMAL, 0x0E));
- vsKey.insert(std::pair<byte, byte>(VK_DIVIDE, 0x0E));
- }
- void GetGameConfig()
- {
- TCHAR szValue[MAX_PATH] = { 0 };
- GetPrivateProfileString(_T("Assist"), _T("GamePath"), _T(""), szValue, MAX_PATH, g_szAssistConfig);
- g_strGameDir = szValue;
- GetPrivateProfileString(_T("Assist"), _T("GameApp"), _T(""), g_szGameApp, MAX_PATH, g_szAssistConfig);
- // 读取窗口类型;
- _stprintf_s(szValue, _T("%s%s"), g_szGameApp, _T("save\\config.ini"));
- int ScreenWidth = GetPrivateProfileInt(_T("SysCfg"), _T("ScreenWidth"), 640, szValue);
- if (ScreenWidth == 640)
- nGameWndType = GW_SMALL;
- else if (ScreenWidth == 800)
- nGameWndType = GW_LARGE;
- else
- nGameWndType = GW_FULL;
- }
- void ShowLog(const TCHAR* format, ...)
- {
- return;
- // 获取今年年份;
- __time64_t gmt = time(NULL);// 获取当前日历时间(1900-01-01开始的Unix时间戳);
- struct tm gmtm = { 0 };
- localtime_s(&gmtm, &gmt); // 时间戳转成本地时间;
- // 格式化前设置语言区域;
- TCHAR* old_locale = _tcsdup(_tsetlocale(LC_CTYPE, NULL));
- _tsetlocale(LC_CTYPE, _T("chs"));//设定中文;
- // 格式化日志内容;
- va_list args = NULL;
- int len = 0;
- TCHAR* buffer = NULL;
- va_start(args, format);
- // _vscprintf doesn't count. terminating '\0'
- len = _vsctprintf(format, args) + 1;
- buffer = (TCHAR*)malloc(len * sizeof(TCHAR) + 8);
- _tcscat_s(buffer, len * sizeof(TCHAR) + 8, _T("\n"));
- _vstprintf_s(buffer, len, format, args);
- // 将日志内容输入到文件中;
- OutputDebugString(buffer);
- // 关闭文件,释放资源并设置回原语言区域;
- free(buffer);
- _tsetlocale(LC_CTYPE, old_locale);
- free(old_locale);//还原区域设定;
- }
- // 根据路径名查找进程,返回进程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 GetProMainHwnd(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;
- // 获取窗口类名,标题名;
- ::GetWindowText(hwndRet, szName, sizeof(szName) / sizeof(TCHAR));
- ::GetClassName(hwndRet, szClass, sizeof(szClass) / sizeof(TCHAR)); // 窗口类
- TRACE3(_T("类名:%s 标题:%s 地址%p\n"), szClass, szName, hwndRet);
- // 是否找到目前窗口;
- 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;
- }
- DWORD GetProcessId(LPCTSTR lpProcessName /* = _T("Game.exe") */)
- {
- DWORD dwProcessId = 0;
- PROCESSENTRY32 pe32 = { 0 };
- HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (hProcessSnap == NULL) return 0;
- // 遍历进程;
- pe32.dwSize = sizeof(PROCESSENTRY32);
- for (BOOL bRet = Process32First(hProcessSnap, &pe32); bRet; bRet = Process32Next(hProcessSnap, &pe32)) {
- if (_tcscmp(lpProcessName, pe32.szExeFile) == 0) {
- dwProcessId = pe32.th32ProcessID;
- break;
- }
- }
- CloseHandle(hProcessSnap);
- return dwProcessId;
- }
- void GetAllProcessId(std::vector<DWORD>& vtPid, LPCTSTR lpProcessName)
- {
- vtPid.clear();
- PROCESSENTRY32 pe32 = { 0 };
- HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (hProcessSnap == NULL) return;
- // 遍历进程;
- pe32.dwSize = sizeof(PROCESSENTRY32);
- for (BOOL bRet = Process32First(hProcessSnap, &pe32); bRet; bRet = Process32Next(hProcessSnap, &pe32)) {
- if (_tcscmp(lpProcessName, pe32.szExeFile) == 0) {
- vtPid.push_back(pe32.th32ProcessID);
- }
- }
- CloseHandle(hProcessSnap);
- }
- HWND GetProcessMainWnd(const DWORD& dwTagetProcessId, LPCTSTR lpTagetWndName /* = _T("大话水浒") */)
- {
- DWORD dwCurPorcessId = 0;
- HWND hTagetProcessWnd = NULL;
- TCHAR szWndName[MAX_PATH] = { 0 };
- TCHAR szClassName[MAX_PATH] = { 0 };
- // 取得第一个窗口句柄;
- for (HWND hCurWnd = ::GetTopWindow(NULL); hCurWnd != NULL; hCurWnd = ::GetNextWindow(hCurWnd, GW_HWNDNEXT)) {
- // 重置为0;
- dwCurPorcessId = 0;
- // 通过窗口句柄反查进程pid;
- DWORD dwThreadId = ::GetWindowThreadProcessId(hCurWnd, &dwCurPorcessId);
- if (dwThreadId != 0) {
- // 判断当前进程id是否和目标进程id相同;
- if (dwCurPorcessId == dwTagetProcessId) {
- if (lpTagetWndName == NULL) {
- hTagetProcessWnd = hCurWnd;
- break;
- }
- else {
- // 获取窗口名称;
- ::GetWindowText(hCurWnd, szWndName, sizeof(szWndName) / sizeof(TCHAR));
- // 获取窗口类名;
- ::GetClassName(hCurWnd, szClassName, sizeof(szClassName) / sizeof(TCHAR));
- #ifdef _DEBUG
- TCHAR szLogMsg[MAX_PATH] = { 0 };
- _stprintf_s(szLogMsg, _T("类名:%s, 窗口名:%s,窗口地址:%p \n"), szClassName, szWndName, hCurWnd);
- OutputDebugString(szLogMsg);
- #endif
- if (_tcsstr(szWndName, lpTagetWndName) != NULL) {
- hTagetProcessWnd = hCurWnd;
- break;
- }
- }
- }
- }
- }
- // 当前窗口有可能不是进程父窗口;
- HWND hParentWnd = hTagetProcessWnd;
- while (hParentWnd) {
- hParentWnd = ::GetParent(hTagetProcessWnd);
- if (hParentWnd == NULL)
- break;
- hTagetProcessWnd = hParentWnd;
- }
- return hTagetProcessWnd;
- }
- void GetAllProcessMainWnd(const std::vector<DWORD>& vtPid, std::vector<GWnd>& vtGWnd)
- {
- // 删除已失效的进程;
- for (std::vector<GWnd>::iterator it = vtGWnd.begin(); it != vtGWnd.end();)
- {
- BOOL bExit = FALSE;
- for (std::vector<DWORD>::const_iterator it_pid = vtPid.begin(); it_pid != vtPid.end(); it_pid++ )
- {
- if (*it_pid == it->lProcId)
- bExit = TRUE;
- }
- if (!bExit)
- {
- it = vtGWnd.erase(it);
- }
- else
- {
- it++;
- }
- }
- for ( std::vector<DWORD>::const_iterator it = vtPid.begin(); it != vtPid.end(); it++ )
- {
- HWND hGWnd = GetProcessMainWnd(*it);
- }
- }
- HWND GetProcessMainWnd(LPCTSTR lpProcessName /* = _T("Game.exe") */, LPCTSTR lpTagetWndName /* = _T("大话水浒") */)
- {
- HWND hTagetWnd = NULL;
- DWORD dwProcessId = 0;
- if ((dwProcessId = GetProcessId(lpProcessName)) != 0) {
- hTagetWnd = GetProcessMainWnd(dwProcessId, lpTagetWndName);
- }
- return hTagetWnd;
- }
- 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_szGameApp, 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, BOOL bClientRect)
- {
- if (!IsWindow(hwnd))
- return;
- ::ShowWindow(hwnd, SW_SHOWNORMAL);
- ::SetForegroundWindow(hwnd); // 窗口前置才能单击成功;
- #if 0 // 使用Post或Send的方式,鼠标是不会显示出来的;
- ::PostMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
- ::PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(pt.x, pt.y));
- #else// 建议使用这种方式,可以看到鼠标;
- POINT ptScreen = pt;
- if (bClientRect)
- ClientToScreen(hwnd, &ptScreen);
- ::SetCursorPos(ptScreen.x, ptScreen.y); // 必须将鼠标定位到目标单击点;
- mouse_event(MOUSEEVENTF_LEFTDOWN, ptScreen.x, ptScreen.y, 0, 0);
- Sleep(10);
- mouse_event(MOUSEEVENTF_LEFTUP, ptScreen.x, ptScreen.y, 0, 0);
- #endif
- }
- void MouseDbClick(HWND hwnd, POINT pt)
- {
- if (!IsWindow(hwnd))
- return;
- ::ShowWindow(hwnd, SW_SHOWNORMAL);
- ::SetForegroundWindow(hwnd); // 窗口前置才能单击成功;
- #if 1 // 使用Post或Send的方式,鼠标是不会显示出来的;
- Sleep(200); // Sleep后才生效;
- ::PostMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
- ::PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(pt.x, pt.y));
- ::PostMessage(hwnd, WM_LBUTTONDBLCLK, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
- ::PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(pt.x, pt.y));
- #else// 建议使用这种方式,可以看到鼠标;
- POINT ptScreen = pt;
- ClientToScreen(hwnd, &ptScreen);
- ::SetCursorPos(ptScreen.x, ptScreen.y); // 必须将鼠标定位到目标单击点;
- mouse_event(MOUSEEVENTF_LEFTDOWN, ptScreen.x, ptScreen.y, 0, 0);
- mouse_event(MOUSEEVENTF_LEFTUP, ptScreen.x, ptScreen.y, 0, 0);
- mouse_event(MOUSEEVENTF_LEFTDOWN, ptScreen.x, ptScreen.y, 0, 0);
- mouse_event(MOUSEEVENTF_LEFTUP, ptScreen.x, ptScreen.y, 0, 0);
- #endif
- }
- void MouseRClick(HWND hwnd, POINT pt, BOOL bClientRect)
- {
- if (!IsWindow(hwnd))
- return;
- ::ShowWindow(hwnd, SW_SHOWNORMAL);
- ::SetForegroundWindow(hwnd); // 窗口前置才能单击成功;
- #if 0 // 使用Post或Send的方式,鼠标是不会显示出来的;
- ::PostMessage(hwnd, WM_RBUTTONDOWN, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
- ::PostMessage(hwnd, WM_RBUTTONUP, 0, MAKELPARAM(pt.x, pt.y));
- #else// 建议使用这种方式,可以看到鼠标;
- POINT ptScreen = pt;
- if (bClientRect)
- ClientToScreen(hwnd, &ptScreen);
- ::SetCursorPos(ptScreen.x, ptScreen.y); // 必须将鼠标定位到目标单击点;
- mouse_event(MOUSEEVENTF_RIGHTDOWN, ptScreen.x, ptScreen.y, 0, 0);
- Sleep(10);
- mouse_event(MOUSEEVENTF_RIGHTUP, ptScreen.x, ptScreen.y, 0, 0);
- #endif
- }
- void MouseRClick(HWND hwnd, unsigned int x, unsigned int y)
- {
- if (!IsWindow(hwnd))
- return;
- ::ShowWindow(hwnd, SW_SHOWNORMAL);
- ::SetForegroundWindow(hwnd); // 窗口前置才能单击成功;
- #if 0
- ::PostMessage(hwnd, WM_RBUTTONDOWN, MK_LBUTTON, MAKELPARAM(x, y));
- ::PostMessage(hwnd, WM_RBUTTONUP, 0, MAKELPARAM(x, y));
- #else
- POINT ptScreen = { x,y };
- ClientToScreen(hwnd, &ptScreen);
- ::SetCursorPos(ptScreen.x, ptScreen.y);
- mouse_event(MOUSEEVENTF_RIGHTDOWN, ptScreen.x, ptScreen.y, 0, 0);
- mouse_event(MOUSEEVENTF_RIGHTUP, ptScreen.x, ptScreen.y, 0, 0);
- #endif
- Sleep(200);
- }
- void MouseRClick(HWND hwnd)
- {
- if (!IsWindow(hwnd))
- return;
- ::ShowWindow(hwnd, SW_SHOWNORMAL);
- ::SetForegroundWindow(hwnd); // 窗口前置才能单击成功;
- #if 0
- ::PostMessage(hwnd, WM_RBUTTONDOWN, MK_LBUTTON, MAKELPARAM(x, y));
- ::PostMessage(hwnd, WM_RBUTTONUP, 0, MAKELPARAM(x, y));
- #else
- POINT ptScreen;// = { x,y };
- ::GetCursorPos(&ptScreen);
-
- mouse_event(MOUSEEVENTF_RIGHTDOWN, ptScreen.x, ptScreen.y, 0, 0);
- mouse_event(MOUSEEVENTF_RIGHTUP, ptScreen.x, ptScreen.y, 0, 0);
- #endif
- Sleep(200);
- }
- void MouseClick(HWND hwnd, unsigned int x, unsigned int y)
- {
- if (!IsWindow(hwnd))
- return;
- ::ShowWindow(hwnd, SW_SHOWNORMAL);
- ::SetForegroundWindow(hwnd); // 窗口前置才能单击成功;
- #if 0
- ::PostMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(x, y));
- ::PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
- #else
- POINT ptScreen = { x,y };
- ClientToScreen(hwnd, &ptScreen);
- ::SetCursorPos(ptScreen.x, ptScreen.y);
- mouse_event(MOUSEEVENTF_LEFTDOWN, ptScreen.x, ptScreen.y, 0, 0);
- mouse_event(MOUSEEVENTF_LEFTUP, ptScreen.x, ptScreen.y, 0, 0);
- #endif
- Sleep(200);
- }
- void MouseMove(HWND hwnd, POINT pt)
- {
- if (!IsWindow(hwnd))
- return;
- ::PostMessage(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);
- ::PostMessage(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 };
- ::PostMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(ptMid.x, ptMid.y));
- Sleep(200);
- #endif
- //::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, lparam);
- ::PostMessage(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);
- ::PostMessage(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 };
- ::PostMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(ptMid.x, ptMid.y));
- Sleep(200);
- #endif
- //::SendMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, lparam);
- ::PostMessage(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;
- ::ShowWindow(hwnd, SW_SHOWNORMAL);
- ::SetForegroundWindow(hwnd);
- #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);
- #endif
- #if 1
- POINT ptScreen = ptStart;
- ClientToScreen(hwnd, &ptScreen);
- ::SetCursorPos(ptScreen.x, ptScreen.y);
- ::PostMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(ptStart.x, ptStart.y));
- Sleep(1200);
- ::PostMessage(hwnd, WM_MOUSEMOVE, MK_LBUTTON, MAKELPARAM(ptEnd.x, ptEnd.y));
- Sleep(200);
- ::PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(ptEnd.x, ptEnd.y));
- #endif
- #if 0
- // 能成功拖动游戏里的东西。
- POINT ptSStart = ptStart;
- POINT ptSEnd = ptEnd;
- ClientToScreen(hwnd, &ptSStart);
- ClientToScreen(hwnd, &ptSEnd);
- ::SetCursorPos(ptSStart.x, ptSStart.y);
- mouse_event(MOUSEEVENTF_LEFTDOWN, ptSStart.x, ptSStart.y, 0, 0);
- Sleep(1200);//必须暂停1秒左右,拖动才有效;
- // MOUSEEVENTF_ABSOLUTE 使用绝对鼠标位置;
- mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, ptSEnd.x, ptSEnd.y, 0, 0);
- Sleep(500);
- mouse_event(MOUSEEVENTF_LEFTUP, ptSEnd.x, ptSEnd.y, 0, 0);
- #endif
- }
- void SendKey(HWND hwnd, DWORD key, BOOL bCtrl /* = FALSE */, BOOL bAtl /* = FALSE */, BOOL bShift /* = FALSE */)
- {
- if (!IsWindow(hwnd))
- return;
- ::ShowWindow(hwnd, SW_SHOWNORMAL);
- ::SetForegroundWindow(hwnd);
- if (bCtrl)
- keybd_event(VK_CONTROL, 0x1D, KEYEVENTF_EXTENDEDKEY | 0, 0);
- if (bAtl)
- keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
- if (bShift)
- keybd_event(VK_SHIFT, 0x2A, KEYEVENTF_EXTENDEDKEY | 0, 0);
- Sleep(120); // 注意:有些电脑能响应Ctrl+V,有些不行,则需要加大CTRL与V之间的时间间隔;
- // key down;
- keybd_event(key, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
- // key up;
- keybd_event(key, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
- Sleep(120);
- if (bCtrl)
- keybd_event(VK_CONTROL, 0x1D, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
- if (bAtl)
- keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
- if (bShift)
- keybd_event(VK_SHIFT, 0x2A, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
- }
- BOOL SetClipboardString(const char* lpString)
- {
- if (lpString == NULL || lpString[0] == '\0')
- return FALSE;
- if (OpenClipboard(NULL))
- {
- HGLOBAL hClipString;
- EmptyClipboard();
- hClipString = GlobalAlloc(GMEM_DDESHARE, _tcslen(lpString) + 1);
- char* lpBuffer = (char*)GlobalLock(hClipString);
- _tcscpy_s(lpBuffer, _tcslen(lpString) + 1, lpString);
- GlobalUnlock(hClipString);
- SetClipboardData(CF_TEXT, hClipString);
- CloseClipboard();
- return TRUE;
- }
- return FALSE;
- }
- CString GetClipboradString(/*char *pString, const int len*/)
- {
- if (OpenClipboard(NULL))
- {
- HANDLE hData = GetClipboardData(CF_TEXT);
- if (hData)
- {
- char* lpBuffer = (char*)GlobalLock(hData);
- //memcpy(pString, lpBuffer, len);
- CString str(lpBuffer);
- GlobalUnlock(hData);
- CloseClipboard();
- return str;
- }
- }
- return CString();
- }
- // 截图;
- 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;
- }
- BOOL IsWin10DpiScaleEanbled()
- {
- SetProcessDPIAware();
- HDC hDC = GetDC(NULL);
- int dpi_x = GetDeviceCaps(hDC, LOGPIXELSX);//96 是100%、120 是125%、144 是150%、168 是175%
- int dpi_y = GetDeviceCaps(hDC, LOGPIXELSY);
- int dpi1 = GetDeviceCaps(hDC, HORZRES);
- int dpi2 = GetDeviceCaps(hDC, DESKTOPHORZRES);
- BOOL bRet = FALSE;
- BOOL bProcessed = FALSE;
- if (GetDeviceCaps(hDC, LOGPIXELSX) != 96)
- {
- DEVMODE curDevMode;
- memset(&curDevMode, 0, sizeof(curDevMode));
- curDevMode.dmSize = sizeof(DEVMODE);
- BOOL bEnumRet = ::EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &curDevMode);
- if (bEnumRet < curDevMode.dmPelsWidth)
- {
- bProcessed = TRUE;
- //::SetStretchBltMode(hMemDC, STRETCH_HALFTONE);
- //bRet = ::StretchBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, 0, 0, curDevMode.dmPelsWidth, curDevMode.dmPelsHeight, SRCCOPY | CAPTUREBLT);
- }
- }
- ReleaseDC(NULL, hDC);
- return TRUE;
- }
- void SaveHwndToBmpFile(HWND hWnd, std::string strSavePath) {
- 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);
- BOOL bRet = FALSE;
- BOOL bProcessed = FALSE;
- // 针对win10 DWM虚拟缩放时的处理
- if (GetDeviceCaps(hDC, LOGPIXELSX) != 96)
- {
- DEVMODE curDevMode;
- memset(&curDevMode, 0, sizeof(curDevMode));
- curDevMode.dmSize = sizeof(DEVMODE);
- BOOL bEnumRet = ::EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &curDevMode);
- if (bEnumRet < curDevMode.dmPelsWidth)
- {
- bProcessed = TRUE;
- //::SetStretchBltMode(hMemDC, STRETCH_HALFTONE);
- //bRet = ::StretchBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, 0, 0, curDevMode.dmPelsWidth, curDevMode.dmPelsHeight, SRCCOPY | CAPTUREBLT);
- }
- }
- ::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);
- CFile file;
- CFileException fep;
- if (file.Open(strSavePath.c_str(), CFile::modeCreate | CFile::modeWrite, &fep)) {
- 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();
- }
- GlobalUnlock(hDib);
- GlobalFree(hDib);
- ::SelectObject(hMemDC, hOldBmp);
- ::DeleteObject(hBitmap);
- ::DeleteObject(hMemDC);
- ::ReleaseDC(hWnd, hDC);
- Sleep(30);
- }
- // #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;
- }
- // 判断窗口是否被遮住;
- bool IsCoveredByOtherWindow(HWND hWnd)
- {
- RECT rcTarget;
- GetWindowRect(hWnd, &rcTarget);
- bool isChild = (WS_CHILD == (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD));
- if (GetDesktopWindow() == hWnd)
- hWnd = GetWindow(GetTopWindow(hWnd), GW_HWNDLAST);
- do
- {
- HWND hCurWnd = hWnd;
- while (NULL != (hWnd = GetNextWindow(hWnd, GW_HWNDPREV)))
- {
- //过滤了非窗口,没有显示的,无效的,非windows工具栏,置顶的窗口。如果不过滤非工具栏的句柄,那么会得到一些奇怪的窗口,会很难判断是否被遮住。
- //if ( IsWindow(hWnd) && IsWindowVisible(hWnd) && IsWindowEnabled(hWnd) && !(GetWindowLong(hWnd,GWL_EXSTYLE)& WS_EX_TOOLWINDOW) && !(GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOPMOST))
- if (::IsWindowVisible(hWnd))
- {
- RECT rcWnd;
- GetWindowRect(hWnd, &rcWnd);
- if (!((rcWnd.right < rcTarget.left) || (rcWnd.left > rcTarget.right) ||
- (rcWnd.bottom < rcTarget.top) || (rcWnd.top > rcTarget.bottom)))
- {
- return true;
- }
- }
- }
- if (isChild)
- {
- hWnd = GetParent(hCurWnd);
- isChild = (WS_CHILD == (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD));
- }
- else
- {
- break;
- }
- } while (true);
- return false;
- }
- BOOL OpenImage(std::string strImag, cv::Mat& img)
- {
- if (!PathFileExists(strImag.c_str()))
- return FALSE;
- if (img.data != NULL)
- img.release();
- img = cv::imread(strImag.c_str(), cv::IMREAD_COLOR);
- if (img.data == NULL)
- return FALSE;
- return TRUE;
- }
- BOOL SetImgThreshold(cv::Mat& srcImg, cv::Mat& thresholdImg, long nThresholdVal, long nMaxThresholdVal, int type)
- {
- if (srcImg.data == NULL)
- return FALSE;
- if (thresholdImg.data && srcImg.data != thresholdImg.data)
- thresholdImg.release();
- switch (type)
- {
- case 0://全局阀值;
- {
- // 转成灰阶图;
- cv::cvtColor(srcImg, thresholdImg, cv::COLOR_BGR2GRAY);
- // 再高斯模糊处理(滤波);
- cv::GaussianBlur(thresholdImg, thresholdImg, cv::Size(5, 5), 0, 0);
- // 二值化;//全局化指定的阀值与返回值相等;
- double dRetVal = cv::threshold(thresholdImg, thresholdImg, nThresholdVal, nMaxThresholdVal, cv::THRESH_BINARY);
- }
- break;
- case 1://自适应阀值;
- {
- // 转成灰阶图;
- cv::cvtColor(srcImg, thresholdImg, cv::COLOR_BGR2GRAY);
- // 再高斯模糊处理(滤波);
- cv::GaussianBlur(thresholdImg, thresholdImg, cv::Size(3, 3), 0, 0);
- // 自适应阀值;
- cv::medianBlur(thresholdImg, thresholdImg, 3);
- // 局部二值化;//blocksize一般取3、5、7
- cv::adaptiveThreshold(thresholdImg, thresholdImg, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 3, 4.5);
- }
- break;
- case 2:// otsu阀值;
- {
- cv::cvtColor(srcImg, thresholdImg, cv::COLOR_BGR2GRAY);
- // 高斯模糊;
- cv::GaussianBlur(thresholdImg, thresholdImg, cv::Size(3, 3), 0, 0);
- cv::threshold(thresholdImg, thresholdImg, nThresholdVal, nMaxThresholdVal, cv::THRESH_BINARY | cv::THRESH_OTSU);
- }
- break;
- default:
- break;
- }
- return TRUE;
- }
- BOOL GetImgMatchtemplate(HWND hWnd, std::string strTempImg, RECT& rc, double lowestMatchValue)
- {
- GAssist::SaveHwndToBmpFile(hWnd, g_strAppdir + _T("Game.bmp"));
- cv::Mat srcImg, tempImg, matchImg;
- if (!OpenImage(g_strAppdir + _T("Game.bmp"), srcImg) || !OpenImage(strTempImg, tempImg))
- {
- if (srcImg.data) srcImg.release();
- if (tempImg.data) tempImg.release();
- return FALSE;
- }
- cv::matchTemplate(srcImg, tempImg, matchImg, cv::TM_CCOEFF_NORMED);
- // 归一化到0~1
- //cv::normalize(matchImg, matchImg, 0, 1, cv::NORM_MINMAX, -1);
- double lv_nMinVal = 0.0;
- double lv_nMaxVal = 0.0;
- cv::Point lv_nMinLoc = cv::Point(0, 0);
- cv::Point lv_nMaxLoc = cv::Point(0, 0);
- cv::Point lv_MatchLoc = cv::Point(0, 0);
- cv::minMaxLoc(matchImg, &lv_nMinVal, &lv_nMaxVal, &lv_nMinLoc, &lv_nMaxLoc);
- cv::Rect roi = cv::Rect(lv_nMaxLoc.x, lv_nMaxLoc.y, tempImg.cols, tempImg.rows);
- cv::Mat roiImg = srcImg(roi);
- cv::imwrite(g_strAppdir + _T("match.bmp"), roiImg);
- rc.left = lv_nMaxLoc.x - frameWidth;
- rc.top = lv_nMaxLoc.y - titleBarHeight;
- rc.right = rc.left + tempImg.cols;
- rc.bottom = rc.top + tempImg.rows;
- srcImg.release();
- tempImg.release();
- matchImg.release();
- roiImg.release();
- // 是否大于最低匹配度;
- return (lv_nMaxVal >= lowestMatchValue ? TRUE : FALSE);
- }
- BOOL GetImgMatchtemplate(std::string strSrcImg, std::string strTempImg, RECT& rc, double lowestMatchValue)
- {
- cv::Mat srcImg, tempImg, matchImg;
- if (!OpenImage(strSrcImg, srcImg) || !OpenImage(strTempImg, tempImg))
- {
- if (srcImg.data) srcImg.release();
- if (tempImg.data) tempImg.release();
- return FALSE;
- }
- cv::matchTemplate(srcImg, tempImg, matchImg, cv::TM_CCOEFF_NORMED);
- // 归一化到0~1
- //cv::normalize(matchImg, matchImg, 0, 1, cv::NORM_MINMAX, -1);
- double lv_nMinVal = 0.0;
- double lv_nMaxVal = 0.0;
- cv::Point lv_nMinLoc = cv::Point(0, 0);
- cv::Point lv_nMaxLoc = cv::Point(0, 0);
- cv::Point lv_MatchLoc = cv::Point(0, 0);
- cv::minMaxLoc(matchImg, &lv_nMinVal, &lv_nMaxVal, &lv_nMinLoc, &lv_nMaxLoc);
- cv::Rect roi = cv::Rect(lv_nMaxLoc.x, lv_nMaxLoc.y, tempImg.cols, tempImg.rows);
- cv::Mat roiImg = srcImg(roi);
- cv::imwrite("G:\\bin\\GameAssist\\match.bmp", roiImg);
- rc.left = lv_nMaxLoc.x - frameWidth;
- rc.top = lv_nMaxLoc.y - titleBarHeight;
- rc.right = rc.left + tempImg.cols;
- rc.bottom = rc.top + tempImg.rows;
- srcImg.release();
- tempImg.release();
- matchImg.release();
- roiImg.release();
- // 是否大于最低匹配度;
- return (lv_nMaxVal >= lowestMatchValue ? TRUE : FALSE);
- }
- BOOL IsMatchIcon(HWND hWnd, std::string strTempImg, RECT srcRect, RECT& matchRect, double lowestMatchValue)
- {
- GAssist::SaveHwndToBmpFile(hWnd, g_strAppdir + _T("Game.bmp"));
- cv::Mat srcImg, tempImg, matchImg;
- if (!OpenImage(g_strAppdir + _T("Game.bmp"), srcImg) || !OpenImage(strTempImg, tempImg))
- {
- if (srcImg.data) srcImg.release();
- if (tempImg.data) tempImg.release();
- return FALSE;
- }
- // 指定源图片区域来做模块比较,提高效率;
- cv::Mat imgROI;
- imgROI = srcImg(cv::Rect(srcRect.left, srcRect.top, srcRect.right - srcRect.left, srcRect.bottom - srcRect.top));
- cv::imwrite("roi.bmp", imgROI);
- /*
- m_ImgROI = srcImg([&]()-> cv::Rect {
- // 注意是x,y,w=cols,h=rows
- return cv::Rect(srcRect.left, srcRect.top, srcRect.right - srcRect.left, srcRect.bottom - srcRect.top);
- }());
- */
- cv::matchTemplate(imgROI, tempImg, matchImg, cv::TM_CCOEFF_NORMED);
- // 归一化到0~1
- //cv::normalize(matchImg, matchImg, 0, 1, cv::NORM_MINMAX, -1);
- double lv_nMinVal = 0.0;
- double lv_nMaxVal = 0.0;
- cv::Point lv_nMinLoc = cv::Point(0, 0);
- cv::Point lv_nMaxLoc = cv::Point(0, 0);
- cv::Point lv_MatchLoc = cv::Point(0, 0);
- cv::minMaxLoc(matchImg, &lv_nMinVal, &lv_nMaxVal, &lv_nMinLoc, &lv_nMaxLoc);
- cv::Rect roi = cv::Rect(lv_nMaxLoc.x, lv_nMaxLoc.y, tempImg.cols, tempImg.rows);
- cv::Mat roiImg = imgROI(roi);
- cv::imwrite("match.bmp", roiImg);
- matchRect.left = srcRect.left + lv_nMaxLoc.x - frameWidth;
- matchRect.top = srcRect.top + lv_nMaxLoc.y - titleBarHeight;
- matchRect.right = matchRect.left + tempImg.cols;
- matchRect.bottom = matchRect.top + tempImg.rows;
- imgROI.release();
- srcImg.release();
- tempImg.release();
- matchImg.release();
- roiImg.release();
- // 是否大于最低匹配度;
- return (lv_nMaxVal >= lowestMatchValue ? TRUE : FALSE);
- }
- BOOL CropPicture(HWND hWnd, CRect rc, const char *szSaveName)
- {
- GAssist::SaveHwndToBmpFile(hWnd, g_strAppdir + _T("Game.bmp"));
- cv::Mat srcImg, tempImg, matchImg;
- if (!OpenImage(g_strAppdir + _T("Game.bmp"), srcImg) )
- {
- if (srcImg.data) srcImg.release();
- return FALSE;
- }
- // 指定源图片区域来做模块比较,提高效率;
- cv::Mat imgROI;
- imgROI = srcImg(cv::Rect(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top));
- cv::imwrite(szSaveName, imgROI);
- }
- BOOL IsSimilarPicture(const char* szp1, const char* szp2, double lowestMatchValue)
- {
- cv::Mat src, dest, matchImg;
- src = cv::imread(szp1);
- dest = cv::imread(szp2);
-
- cv::matchTemplate(src, dest, matchImg, cv::TM_CCOEFF_NORMED);
- // 归一化到0~1
- //cv::normalize(matchImg, matchImg, 0, 1, cv::NORM_MINMAX, -1);
- double lv_nMinVal = 0.0;
- double lv_nMaxVal = 0.0;
- cv::Point lv_nMinLoc = cv::Point(0, 0);
- cv::Point lv_nMaxLoc = cv::Point(0, 0);
- cv::Point lv_MatchLoc = cv::Point(0, 0);
- cv::minMaxLoc(matchImg, &lv_nMinVal, &lv_nMaxVal, &lv_nMinLoc, &lv_nMaxLoc);
- src.release();
- matchImg.release();
- dest.release();
- // 是否大于最低匹配度;
- return (lv_nMaxVal >= lowestMatchValue ? TRUE : FALSE);
- }
- void ZhiYeDaTiaoZhan()
- {
- // 判断当前地图是否在应天府;
- //// 是:打开世界地图,寻路到NPC;
- //// 否:退出
- // 对话NPC,进入地图;
- }
- }
|