如何将窗口的客户区复制到另一个窗口?

3

我希望创建一个简单的项目(语言不是很重要/但我更喜欢C ++),它只需要将窗口标题作为输入,并将其视觉部分逐位复制到新窗口中。就像一个镜子一样,最好这么说。 据我所记,有一个win32 API可以实现这一点,但我记不清了,所以你能告诉我如何实现吗? 请告诉我,你的答案是否也适用于DirectX/Open-GL应用程序?

2个回答

0
你可以获取第一个窗口的DC,也可以获取第二个窗口的DC。然后进行BitBlt或StretchBlt操作。这应该是可行的...但我不知道DirectX/Open-Gl怎么样...我认为它也应该是可行的。无论如何,检查一下也不会花费太多时间。

0

这里是一个程序的源代码,可以镜像其他应用程序,您可以使用StretchBlt()代替BitBlt(),这将不会复制菜单栏或弹出窗口。 一些应用程序,如Chrome、计算器和相机,使用子窗口进行可视化部分,而FindWindow()仅扫描顶级窗口的标题,因此您可以使用FindWindowEx()来使其工作!

#include <windows.h>

HWND sourceWindow;

void Mirror(HWND hwndSource, HWND hwndDst)
{
    HDC source = GetDC(hwndSource);
    HDC dst = GetDC(hwndDst);
    
    RECT srcSiz;
    GetClientRect(hwndSource, &srcSiz);
    
    SetWindowPos(hwndDst, NULL, 0, 0, srcSiz.right, srcSiz.bottom, SWP_NOMOVE | SWP_NOZORDER);
    
    BitBlt(dst, 0, 0, srcSiz.right, srcSiz.bottom, source, 0, 0, SRCCOPY);
    
    ReleaseDC(hwndSource, source);
    ReleaseDC(hwndDst, dst);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch (Message)
    {
        case WM_CREATE:
            SetTimer(hwnd, 1, 500, (TIMERPROC) NULL);//This will refresh after every 500 ms
            break;
        case WM_TIMER:
            Mirror(sourceWindow, hwnd);
            break;
        case WM_DESTROY:
            KillTimer(hwnd, 1);
            break;
        default:
            return DefWindowProc(hwnd, Message, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hwnd;
    MSG msg;
    
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(CreateSolidBrush(RGB(0, 0, 0)));
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "MyWindow";
    wc.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
    
    if (!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
    
    hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "MyWindow", "MyTitle", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500,
                            NULL, NULL, hInstance, NULL);
                            
    if (!hwnd)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
    
    
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    
    sourceWindow = FindWindowA(NULL, "<WindowTitle>");//or you can use class name
    
    while(GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    
    return msg.wParam;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接