如何将一个窗口的工作区复制到另一个窗口?

How to duplicate a window's clientarea to another window?

本文关键字:窗口 工作区 复制 另一个 一个      更新时间:2023-10-16

我想创建一个简单的项目(语言并不重要/但我更喜欢c++),它只是简单地将窗口标题作为输入并复制它的视觉部分,一点一点地,到一个新窗口。我得说,就像一面镜子。就我所记得的有一个win32 API,但我不记得了,所以你能告诉我如何才能实现这一点吗?请告诉我,你的答案是否适用于DirectX/Open-GL应用程序?

可以得到第一个窗口的DC,第二个窗口的DC。在此之后,执行BitBlt或StretchBlt。它必须起作用……但我不知道DirectX/Open-Gl怎么样…我认为它也必须起作用。但无论如何。检查一下不会花太多时间的。

这是一个程序的源代码,将镜像其他应用程序,你可以使用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;
}