【问题标题】:How do I draw a rectangle on the desktop like UISpy/Spy++/etc..?如何在桌面上绘制一个矩形,如 UISpy/Spy++/etc..?
【发布时间】:2020-11-12 19:04:57
【问题描述】:

我在一个控制台应用程序中玩耍,并认为如果我可以在桌面上的区域周围弹出一个矩形,这样我就可以直观地看到各种 RECT 的位置。就像你看到的 UISpy、Inspect、Spy++(将目标拖到窗口上)等。通常使用什么方法来做到这一点?

我试过了,但它不起作用:

void DoMessageLoop(void * parg)
{
  MSG msg;

  // Main message loop:
  while (GetMessage(&msg, NULL, 0, 0))
  {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
  }
  _endthread();
}


HWND CreateLayeredWindow(RECT *prc)
{
 LPCTSTR szWindowClass = _T("TransparentClass");

    // Register class
    WNDCLASSEX wcex = {0};

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.lpfnWndProc    = DefWindowProc;
    wcex.hInstance      = GetModuleHandle(NULL);
    wcex.lpszClassName  = szWindowClass;

    RegisterClassEx(&wcex);

    HWND hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOPMOST, szWindowClass, 0, WS_OVERLAPPEDWINDOW, prc->left, 
                               prc->top, prc->right-prc->left, prc->bottom-prc->top, NULL, NULL, GetModuleHandle(NULL), NULL);


    SetLayeredWindowAttributes(hWnd, RGB(255,0,255), 50, LWA_COLORKEY);

    HBRUSH brush=CreateSolidBrush(RGB(255, 0, 255));
    HPEN pen=CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
    HDC hdc=GetDC(hWnd);
    HBRUSH oldbrush=(HBRUSH)SelectObject(hdc, brush); 
    HPEN oldpen=(HPEN) SelectObject(hdc, pen);

    Rectangle(hdc, 0, 0, prc->right-prc->left, prc->bottom-prc->top);

    SelectObject(hdc, oldpen);
    SelectObject(hdc, oldbrush);

    DeleteObject(pen);
    DeleteObject(brush);

    ReleaseDC(hWnd, hdc);

    ShowWindow(hWnd, SW_SHOW);

    _beginthread(DoMessageLoop, 0, hWnd);

    return hWnd;
}

【问题讨论】:

  • 该库称为 Windows SDK。选择的工具是CreateWindowEx。神奇的成分是WS_EX_LAYERED 扩展窗口样式。
  • 如果要在一个分层窗口上显示所有矩形,可以先遍历所有窗口句柄,用GetWindowRect得到每个窗口的大小,然后用gdi画出它们的边框。
  • 好的,谢谢,我用不起作用的代码更新了问题。它不透明,也没有红色矩形。我究竟做错了什么?另外,我宁愿有一个没有标题栏的窗口,这样你就只能看到大纲。它也应该点击通过,这样窗口本身就不会被点击
  • 您提出的所有其他问题都是新问题。

标签: winapi gdi


【解决方案1】:

好的,我让它工作了,但必须设置一个 WndProc(并将创建/消息循环移动到同一个线程):

LRESULT DrawRedRect(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
  static RECT rcarea;

  switch (msg) {
    case WM_CREATE:
    {
      CREATESTRUCT *cs=(CREATESTRUCT*) lp;
      rcarea=*((LPRECT) cs->lpCreateParams);
      return DefWindowProc(hwnd, msg, wp, lp);
    }

    case WM_PAINT:
    {
      PAINTSTRUCT ps {};
      HDC hdc=BeginPaint(hwnd, &ps);

      RECT rc {}; 
      GetClientRect(hwnd, &rc);

      _ASSERT((rc.right-rc.left) == (rcarea.right-rcarea.left));
      _ASSERT((rc.bottom-rc.top) == (rcarea.bottom-rcarea.top));

      HPEN hPen=CreatePen(PS_SOLID, 5, RGB(255, 0, 0));
      HBRUSH hBrush=CreateSolidBrush(MYTRANSPARENTCOLOR);
      HGDIOBJ hOldPen=SelectObject(hdc, hPen);
      HGDIOBJ hOldBrush=SelectObject(hdc, hBrush);

      Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom);

      if (hOldPen)
        SelectObject(hdc, hOldPen);
      if (hOldBrush)
        SelectObject(hdc, hOldBrush);
      if (hPen)
        DeleteObject(hPen);
      if (hBrush)
        DeleteObject(hBrush);

      EndPaint(hwnd, &ps);
    }
    break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return DefWindowProc(hwnd, msg, wp, lp);
  }

  return 0;
}

//-----------------------------------------------------------------------------------

HWND g_hWnd=NULL;

void CreateLayeredWindowThread(void *parg) 
{
  const PRECT &prc=reinterpret_cast<PRECT>(parg);

  _ASSERT(g_hWnd==NULL);

   LPCTSTR szWindowClass = _T("TransparentClass");

    // Register class
    WNDCLASSEX wcex = {0};

    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.lpfnWndProc    = DefWindowProc;
    wcex.hInstance      = GetModuleHandle(NULL);
    wcex.lpszClassName  = szWindowClass;
    wcex.lpfnWndProc=DrawRedRect;

    RegisterClassEx(&wcex);

    RECT winrect=*prc;

    AdjustWindowRect(&winrect, WS_POPUP, FALSE);

    g_hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_NOACTIVATE | WS_EX_TOOLWINDOW, szWindowClass, 0, WS_POPUP, prc->left, 
                               winrect.top, winrect.right-winrect.left, winrect.bottom-winrect.top, NULL, NULL, GetModuleHandle(NULL), (LPVOID) prc);



    SetLayeredWindowAttributes(g_hWnd, MYTRANSPARENTCOLOR, 0, LWA_COLORKEY);

    ShowWindow(g_hWnd, SW_SHOW);

  MSG msg;

  // Main message loop:
  while (GetMessage(&msg, NULL, 0, 0))
  {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
  }
  _endthread();

}

//-----------------------------------------------------------------------------------

void CreateLayeredWindow(RECT *prc)
{
  _beginthread(CreateLayeredWindowThread, 0, prc);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-21
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多