【问题标题】:GDI Drawing to external windows (C++)GDI 绘图到外部窗口 (C++)
【发布时间】:2020-09-12 12:32:14
【问题描述】:

任务是绘制到外部窗口,例如画一条线到一个正在运行的窗口。 (有点像游戏中的 ESP)。

我有这段代码可以绘制到桌面(绘制一个矩形),但我该如何更改它以绘制到我选择的运行窗口?

绘制到桌面的代码:

#include <iostream>
#include <Windows.h>

int main() {

/* hide console window */
ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);

/* Calling GetDC with argument 0 retrieves the desktop's DC */
HDC hDC_Desktop = GetDC(0);

/* Draw a simple blue rectangle on the desktop */
RECT rect = { 20, 20, 200, 200 };
HBRUSH blueBrush = CreateSolidBrush(RGB(0, 0, 255));
FillRect(hDC_Desktop, &rect, blueBrush);

Sleep(10);
return 0;
}

【问题讨论】:

  • 编辑:我可以将 GetDC 中的 0 更改为我选择的窗口吗?
  • 简单的回答:你不能。渲染到窗口对于该窗口的所有者来说是私有的。如果您想在其他窗口前面出现图形,请创建您自己的透明覆盖窗口。像这样的问题实际上有几十个,甚至几百个。做一些研究。

标签: c++ winapi gdi


【解决方案1】:

当外部窗口被重绘时,你绘制的矩形会消失。如果希望刷新窗口时矩形不消失,请按照@llspectable 的建议。

您可以添加WS_EX_LAYERED 样式来制作分层窗口。

如果你想在分层窗口后面做点什么,你可以添加WS_EX_TRANSPARENT来增加透明度。

这里有一些你可以参考的代码。

#include <Windows.h>
#include <stdio.h>
#include <iostream>

using namespace std;


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{
    PAINTSTRUCT ps;
    HDC hdc;
    RECT rect;
    switch (message)
    {
    case WM_PAINT:
    {
        hdc = BeginPaint(hwnd, &ps);
        RECT rect = { 0, 0, 200, 200 };
        HBRUSH blueBrush = CreateSolidBrush(RGB(0, 0, 255));
        FillRect(hdc, &rect, blueBrush);
        EndPaint(hwnd, &ps);
    }
    break;
    case WM_SIZE:
    {
        HWND notepad = (HWND)0x00060BA6; //Test window
        GetWindowRect(notepad, &rect);

        float m = (200.0 / 1920.0);
        float n = (200.0 / 1040.0);

        int wh = (rect.right - rect.left) * m;
        int ht = (rect.bottom - rect.top) * n;

        int x = 100 * m;
        int y = 100 * n;

        SetWindowPos(hwnd, HWND_TOPMOST, x+rect.left, y+rect.top, wh, ht, SWP_SHOWWINDOW);
    }
    break;
    case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    }
    }
    return DefWindowProc(hwnd, message, wParam, lParam);   
};

HINSTANCE hinst;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, PSTR szCmdLine, int iCmdShow) {
    HWND hwnd;

    hinst = GetModuleHandle(NULL);
    // create a window class:
    WNDCLASS wc = {};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hinst;
    wc.lpszClassName = L"win32";

    // register class with operating system:
    RegisterClass(&wc);

    // create and show window:
    hwnd = CreateWindowEx(WS_EX_LAYERED| WS_EX_TRANSPARENT, L"win32", L"My program", WS_POPUP &~WS_BORDER, 0, 0, 0, 0, NULL, NULL, hinst, NULL);

    SetLayeredWindowAttributes(hwnd, NULL, 255, LWA_ALPHA);
    if (hwnd == NULL) {
        return 0;
    }

    ShowWindow(hwnd, SW_SHOW);


    MSG msg = {};

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

}

注意:如果希望分层窗口一起跟随特定的外部窗口,则需要单独处理WM_SIZE 消息。如果您有任何其他问题,请随时告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-03
    • 1970-01-01
    • 2011-08-29
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多