|
@@ -36,7 +36,8 @@ namespace GAssist
|
|
return dwProcessID;
|
|
return dwProcessID;
|
|
}
|
|
}
|
|
|
|
|
|
- HWND GetProHwnd(DWORD dwProcessId)
|
|
|
|
|
|
+ // 注意:一个进程可能拥有多个独立的窗口句柄;
|
|
|
|
+ HWND GetProMainHwnd(DWORD dwProcessId)
|
|
{
|
|
{
|
|
DWORD dwPID = 0;
|
|
DWORD dwPID = 0;
|
|
HWND hwndRet = NULL;
|
|
HWND hwndRet = NULL;
|
|
@@ -55,12 +56,13 @@ namespace GAssist
|
|
if (dwPID == dwProcessId) {
|
|
if (dwPID == dwProcessId) {
|
|
// 进程ID相等,则记录窗口句柄
|
|
// 进程ID相等,则记录窗口句柄
|
|
hwndRet = hwndWindow;
|
|
hwndRet = hwndWindow;
|
|
- //break; //存在Bug:有些进程有多个分离的窗口;
|
|
|
|
|
|
+ // 获取窗口类名,标题名;
|
|
::GetWindowText(hwndRet, szName, sizeof(szName) / sizeof(TCHAR));
|
|
::GetWindowText(hwndRet, szName, sizeof(szName) / sizeof(TCHAR));
|
|
::GetClassName(hwndRet, szClass, sizeof(szClass) / 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("大话水浒")) )
|
|
if ( _tcsstr(szName, _T("大话水浒")) )
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -189,7 +191,7 @@ namespace GAssist
|
|
#if 0 // 使用Post或Send的方式,鼠标是不会显示出来的;
|
|
#if 0 // 使用Post或Send的方式,鼠标是不会显示出来的;
|
|
::PostMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
|
|
::PostMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(pt.x, pt.y));
|
|
::PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(pt.x, pt.y));
|
|
::PostMessage(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(pt.x, pt.y));
|
|
-#else
|
|
|
|
|
|
+#else// 建议使用这种方式,可以看到鼠标;
|
|
POINT ptScreen = pt;
|
|
POINT ptScreen = pt;
|
|
ClientToScreen(hwnd, &ptScreen);
|
|
ClientToScreen(hwnd, &ptScreen);
|
|
::SetCursorPos(ptScreen.x, ptScreen.y); // 必须将鼠标定位到目标单击点;
|
|
::SetCursorPos(ptScreen.x, ptScreen.y); // 必须将鼠标定位到目标单击点;
|
|
@@ -200,6 +202,30 @@ namespace GAssist
|
|
Sleep(200);
|
|
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)
|
|
void MouseClick(HWND hwnd, unsigned int x, unsigned int y)
|
|
{
|
|
{
|
|
if ( !IsWindow(hwnd) )
|
|
if ( !IsWindow(hwnd) )
|
|
@@ -313,12 +339,62 @@ namespace GAssist
|
|
|
|
|
|
mouse_event(MOUSEEVENTF_LEFTDOWN, ptSStart.x, ptSStart.y, 0, 0);
|
|
mouse_event(MOUSEEVENTF_LEFTDOWN, ptSStart.x, ptSStart.y, 0, 0);
|
|
Sleep(1200);//必须暂停1秒左右,拖动才有效;
|
|
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);
|
|
Sleep(500);
|
|
mouse_event(MOUSEEVENTF_LEFTUP, ptSEnd.x, ptSEnd.y, 0, 0);
|
|
mouse_event(MOUSEEVENTF_LEFTUP, ptSEnd.x, ptSEnd.y, 0, 0);
|
|
#endif
|
|
#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)
|
|
HBITMAP CopyDC2Bitmap(HWND hWnd, LPRECT lpRect)
|
|
{
|
|
{
|
|
@@ -502,5 +578,48 @@ namespace GAssist
|
|
return hr;
|
|
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;
|
|
|
|
+ }
|
|
|
|
|
|
}
|
|
}
|