---恢复内容开始---
1 void GetCtrlWndFromPoint(const POINT& point) 2 { 3 ClientToScreen(this->GetHWND(),&pt); // 转换到屏幕坐标 4 5 //找到当前位置的最小窗口 6 HWND current_window = SpyFindSmallestWindow(pt); 7 if (current_window != NULL) 8 { 9 // 确保找到的窗口不是自己的窗口,窗口进程不同 10 if (GetWindowThreadProcessId(/*GetSafeHwnd()*/*this, NULL) != GetWindowThreadProcessId(current_window, NULL)) 11 { 12 // 若是新窗口,就把旧窗口的边界去掉,画新窗口的边界 13 if (current_window != prev_window) 14 { 15 SpyInvertBorder(prev_window); 16 prev_window = current_window; 17 SpyInvertBorder(prev_window); 18 } 19 } 20 else 21 { 22 // 窗口是自己的 23 SpyInvertBorder(prev_window); 24 prev_window = NULL; 25 }
GetWindowRect() //获取控件矩阵
GetWindowLong(hwnd, GWL_STYLE);// 窗口风格
GetWindowLong(hwnd, GWL_EXSTYLE);// 窗口扩展风格
::GetClassName(hwnd, szClassName, MAX_BUFFER_LENGTH);
26 } 27 }
HWND SpyFindSmallestWindow(const POINT &pt) { HWND hWnd = WindowFromPoint(pt);// 鼠标所在窗口 if (hWnd != NULL) { // 得到本窗口大小和父窗口句柄,以便比较 RECT rect; ::GetWindowRect(hWnd, &rect); HWND parent = ::GetParent(hWnd); // 父窗口 // 只有该窗口有父窗口才继续比较 if (parent != NULL) { // 按Z方向搜索 HWND find = hWnd; // 递归调用句柄 RECT rect_find; while (TRUE) // 循环 { CHAR szWindowText[MAX_BUFFER_LENGTH]; // 窗口标题 ZeroMemory(szWindowText, sizeof(szWindowText)); DWORD dwResult = 0; ::SendMessageTimeoutA(hWnd, WM_GETTEXT, MAX_BUFFER_LENGTH, (LPARAM)szWindowText, SMTO_ABORTIFHUNG, 5 * 1000, &dwResult); find = ::GetWindow(find, GW_HWNDNEXT); // 得到下一个窗口的句柄 ::GetWindowRect(find, &rect_find); // 得到下一个窗口的大小 if (::PtInRect(&rect_find, pt) // 鼠标所在位置是否在新窗口里 && ::GetParent(find) == parent // 新窗口的父窗口是否是鼠标所在主窗口 && ::IsWindowVisible(find)) // 窗口是否可视 { // 比较窗口,看哪个更小 if ( ((rect_find.right - rect_find.left) * (rect_find.bottom - rect_find.top) < (rect.right - rect.left) * (rect.bottom - rect.top))) { // 找到更小窗口 hWnd = find; // 计算新窗口的大小 ::GetWindowRect(hWnd, &rect); } } // hWnd的子窗口find为NULL,则hWnd为最小窗口 if (find == NULL) { break; // 退出循环 } } } } return NULL; }
void SpyInvertBorder(const HWND &hWnd) { // 若非窗口则返回 if (!IsWindow(hWnd)) return; RECT rect; // 窗口矩形 // 得到窗口矩形 ::GetWindowRect(hWnd, &rect); HDC dc = ::GetDC(hWnd); // 设置窗口当前前景色的混合模式为R2_NOT // R2_NOT - 当前的像素值为屏幕像素值的取反,这样可以覆盖掉上次的绘图 SetROP2(dc,R2_NOT); // 创建画笔 //CPen pen; // PS_INSIDEFRAME - 产生封闭形状的框架内直线,指定一个限定矩形 // 3 * GetSystemMetrics(SM_CXBORDER) - 三倍边界粗细 // RGB(0,0,0) - 黑色 HPEN pen = CreatePen(PS_INSIDEFRAME, 3 * GetSystemMetrics(SM_CXBORDER), RGB(0, 0, 0)); // 选择画笔 HGDIOBJ old_pen = SelectObject(dc,pen); // 设定画刷 HGDIOBJ old_brush = SelectObject(dc,GetStockObject(NULL_BRUSH)); // 画矩形 Rectangle(dc,0, 0, rect.right-rect.left, rect.bottom-rect.top); // 恢复原来的设备环境 SelectObject(dc,old_pen); SelectObject(dc,old_brush); DeleteObject(pen); }
---恢复内容结束---