浏览代码

添加按钮模拟 。

Jeff 5 年之前
父节点
当前提交
e22fa24804

+ 126 - 7
GameAssist/GameAssist/Assist.cpp

@@ -36,7 +36,8 @@ namespace GAssist
 		return dwProcessID;
 	}
 
-	HWND GetProHwnd(DWORD dwProcessId)
+	// 注意:一个进程可能拥有多个独立的窗口句柄;
+	HWND GetProMainHwnd(DWORD dwProcessId)
 	{
 		DWORD dwPID = 0;
 		HWND hwndRet = NULL;
@@ -55,12 +56,13 @@ namespace GAssist
 				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);
+					
+					TRACE3(_T("类名:%s 标题:%s 地址%p\n"), szClass, szName, hwndRet);
+
+					// 是否找到目前窗口;
 					if ( _tcsstr(szName, _T("大话水浒")) )
 						break;
 				}
@@ -189,7 +191,7 @@ namespace GAssist
 #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
+#else// 建议使用这种方式,可以看到鼠标;
 		POINT ptScreen = pt;
 		ClientToScreen(hwnd, &ptScreen);
 		::SetCursorPos(ptScreen.x, ptScreen.y); // 必须将鼠标定位到目标单击点;
@@ -200,6 +202,30 @@ namespace GAssist
 		Sleep(200);
 	}
 
+	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 MouseClick(HWND hwnd, unsigned int x, unsigned int y)
 	{
 		if ( !IsWindow(hwnd) )
@@ -313,12 +339,62 @@ namespace GAssist
 
 		mouse_event(MOUSEEVENTF_LEFTDOWN, ptSStart.x, ptSStart.y, 0, 0);
 		Sleep(1200);//必须暂停1秒左右,拖动才有效;
-		mouse_event(MOUSEEVENTF_MOVE, 100, 0, 0, 0);
+		// 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 SendCtrlKey(HWND hwnd)
+	{
+
+	}
+
+	void SendKey2(HWND hwnd, DWORD key)
+	{
+		if ( !IsWindow(hwnd) )
+			return;
+
+		::ShowWindow(hwnd, SW_SHOWNORMAL);
+		::SetForegroundWindow(hwnd);
+#if 0
+		::PostMessage(hwnd, WM_KEYDOWN, key, 1);
+		Sleep(50);
+		::PostMessage(hwnd, WM_KEYUP, key, 1);
+#else
+		// 建议用这个;
+		keybd_event(key, 0x45, KEYEVENTF_EXTENDEDKEY | 0,0 );
+		keybd_event(key, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,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, 0, KEYEVENTF_EXTENDEDKEY | 0,0 );
+		if ( bAtl )
+			keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | 0,0 );
+		if ( bShift )
+			keybd_event(VK_SHIFT, 0, KEYEVENTF_EXTENDEDKEY | 0,0 );
+		// key down;
+		keybd_event(key, 0, KEYEVENTF_EXTENDEDKEY | 0,0 );
+		// key up;
+		keybd_event(key, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,0 );
+		if ( bCtrl )
+			keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,0 );
+		if ( bAtl )
+			keybd_event(VK_MENU, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,0 );
+		if ( bShift )
+			keybd_event(VK_SHIFT, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,0 );
+	}
+
 	// 截图;
 	HBITMAP CopyDC2Bitmap(HWND hWnd, LPRECT lpRect)
 	{
@@ -502,5 +578,48 @@ namespace GAssist
 		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;
+	}
 
 }

+ 8 - 1
GameAssist/GameAssist/Assist.h

@@ -9,7 +9,7 @@ namespace GAssist
 	//const TCHAR g_szGamePath[MAX_PATH] = _T("E:\\dhsh\\shdata\\Main.exe");
 	const TCHAR g_szGamePath[MAX_PATH] = _T("D:\\tools\\dhsh\\shdata\\Main.exe");
 	extern DWORD FindProcess(IN LPCSTR lpProName);
-	extern HWND GetProHwnd(DWORD dwProcessId);
+	extern HWND GetProMainHwnd(DWORD dwProcessId);
 	extern BOOL CALLBACK EnumChildWindowCallBack(HWND hWnd, LPARAM lParam);
 
 	typedef struct __GAME_HWNINFO__{
@@ -51,17 +51,24 @@ namespace GAssist
 	// 单击事件;
 	extern void MouseClick(HWND hwnd, POINT pt);
 	extern void MouseClick(HWND hwnd, unsigned int x, unsigned int y);
+	extern void MouseDbClick(HWND, POINT pt);
 	// 移动鼠标;
 	extern void MouseMove(HWND hwnd, POINT pt);
 	extern void MouseMove(HWND hwnd, POINT ptStart, POINT ptEnd);
 	extern void MouseMoveEx(HWND hwnd, POINT ptStart, POINT ptEnd);
 	// 拖动鼠标;
 	extern void DragMouse(HWND hwnd, POINT ptStart, POINT ptEnd);
+	// 发送Ctrl单个按键;
+	extern void SendCtrlKey(HWND hwnd);
+	// 发送F1~F12键;
+	extern void SendKey2(HWND hwnd, DWORD key);
+	extern void SendKey(HWND hwnd, DWORD key, BOOL bCtrl = FALSE, BOOL bAtl = FALSE, BOOL bShift = FALSE);
 	// 截图;
 	HBITMAP CopyDC2Bitmap(HWND hWnd, LPRECT lpRect);
 	// 保存图片;
 	BOOL SaveBitmap(HBITMAP hBitmpa, std::string strSavePath);
 	void SaveHwndToBmpFile(HWND hWnd, LPCTSTR lpszPath);
+	bool IsCoveredByOtherWindow(HWND  hWnd);
 };
 
 #endif // __ASSIST__

+ 13 - 13
GameAssist/GameAssist/GameAssist.rc

@@ -16,11 +16,13 @@
 #undef APSTUDIO_READONLY_SYMBOLS
 
 /////////////////////////////////////////////////////////////////////////////
-// 中文(简体,中国) resources
+// 中文(中华人民共和国) resources
 
 #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+#ifdef _WIN32
 LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
 #pragma code_page(936)
+#endif //_WIN32
 
 #ifdef APSTUDIO_INVOKED
 /////////////////////////////////////////////////////////////////////////////
@@ -70,7 +72,6 @@ END
 // remains consistent on all systems.
 IDR_MAINFRAME           ICON                    "res\\GameAssist.ico"
 
-
 /////////////////////////////////////////////////////////////////////////////
 //
 // Dialog
@@ -87,15 +88,14 @@ BEGIN
     DEFPUSHBUTTON   "确定",IDOK,113,41,50,14,WS_GROUP
 END
 
-IDD_GAMEASSIST_DIALOG DIALOGEX 0, 0, 320, 200
+IDD_GAMEASSIST_DIALOG DIALOGEX 0, 0, 139, 202
 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
 EXSTYLE WS_EX_APPWINDOW
 CAPTION "GameAssist"
 FONT 9, "MS Shell Dlg", 0, 0, 0x1
 BEGIN
-    DEFPUSHBUTTON   "确定",IDOK,209,179,50,14
-    PUSHBUTTON      "取消",IDCANCEL,263,179,50,14
-    CTEXT           "TODO: 在此放置对话框控件。",IDC_STATIC,10,96,300,8
+    DEFPUSHBUTTON   "确定",IDOK,29,181,50,14
+    PUSHBUTTON      "取消",IDCANCEL,80,181,50,14
     PUSHBUTTON      "打开",BTN_OPENGAME,7,7,50,14
     PUSHBUTTON      "Button2",IDC_BUTTON2,8,28,50,14
 END
@@ -146,7 +146,7 @@ END
 //
 
 #ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO
+GUIDELINES DESIGNINFO 
 BEGIN
     IDD_ABOUTBOX, DIALOG
     BEGIN
@@ -159,9 +159,9 @@ BEGIN
     IDD_GAMEASSIST_DIALOG, DIALOG
     BEGIN
         LEFTMARGIN, 7
-        RIGHTMARGIN, 313
+        RIGHTMARGIN, 132
         TOPMARGIN, 7
-        BOTTOMMARGIN, 193
+        BOTTOMMARGIN, 195
     END
 END
 #endif    // APSTUDIO_INVOKED
@@ -172,9 +172,9 @@ END
 // AFX_DIALOG_LAYOUT
 //
 
-IDD_GAMEASSIST_DIALOG AFX_DIALOG_LAYOUT
+IDD_GAMEASSIST_DIALOG AFX_DIALOG_LAYOUT 
 BEGIN
-    0
+    0x0000
 END
 
 
@@ -183,12 +183,12 @@ END
 // String Table
 //
 
-STRINGTABLE
+STRINGTABLE 
 BEGIN
     IDS_ABOUTBOX            "关于 GameAssist(&A)..."
 END
 
-#endif    // 中文(简体,中国) resources
+#endif    // 中文(中华人民共和国) resources
 /////////////////////////////////////////////////////////////////////////////
 
 

+ 13 - 4
GameAssist/GameAssist/GameAssistDlg.cpp

@@ -159,8 +159,8 @@ void CGameAssistDlg::OnBnClickedOpengame()
 {
 #if 1 // »ñÈ¡ÓÎÏ·±êÌâ;
 	DWORD dwPid = GAssist::FindProcess(_T("Game.exe"));
-	HWND hProWnd = GAssist::GetProHwnd(dwPid);
-	//HWND hProWnd = GAssist::GetProHwnd(5824);
+	HWND hProWnd = GAssist::GetProMainHwnd(dwPid);
+	//HWND hProWnd = GAssist::GetProMainHwnd(5824);
 	TCHAR szWinText[MAX_PATH] = {0};
 	::GetWindowText(hProWnd, szWinText, MAX_PATH);
 
@@ -185,13 +185,22 @@ void CGameAssistDlg::OnBnClickedOpengame()
 		GAssist::MouseClick(hProWnd, CPoint(275,150));
 	}
 
-	if (1)
+	if (0)
 	{
 		Sleep(1000);
 		::SetForegroundWindow(hProWnd);
 		GAssist::DragMouse(hProWnd, CPoint(173,192), CPoint(295,190));
 	}
 
+	if (0){
+		GAssist::MouseDbClick(hProWnd, CPoint(476, 158));
+	}
+
+	if (1)
+	{
+		GAssist::SendKey(hProWnd, VK_TAB);
+	}
+
 	RECT rc = {0,0,500,500};
 	HBITMAP hb = GAssist::CopyDC2Bitmap(hProWnd, &rc);
 	GAssist::SaveBitmap(hb, "1.bmp");
@@ -284,7 +293,7 @@ void CGameAssistDlg::OnBnClickedOpengame()
 			{
 				GAssist::g_vtGameHwnd.clear();
 				EnumWindows(GAssist::EnumChildWindowCallBack, dwPID);
-				HWND hwnd = GAssist::GetProHwnd(dwPID);
+				HWND hwnd = GAssist::GetProMainHwnd(dwPID);
 				if ( hwnd )
 				{
 					TCHAR szName[MAX_PATH] = {0};

+ 2 - 2
GameAssist/GameAssist/resource.h

@@ -1,6 +1,6 @@
 //{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ 生成的包含文件。
-// 供 GameAssist.rc 使用
+// Microsoft Visual C++ generated include file.
+// Used by GameAssist.rc
 //
 #define IDM_ABOUTBOX                    0x0010
 #define IDD_ABOUTBOX                    100