将窗口窃取到CreateWindow窗口会创建一个“冻结”窗口?

时间:2012-06-11 22:13:09

标签: c++ winapi

我要做的是从屏幕上偷一个窗口,让它成为我自己创建的窗口的一个孩子。当我的程序关闭时,被盗的窗户也会消失,可能与其进程一起消失。

所以这是我的问题:

  1. 创建的窗口被冻结,它不会让我操作它的控件。控制台是否阻止它被操作?如果是这样,我该如何解决这个问题?
  2. (下面的代码)仅在第二次运行时窃取窗口,它在第一次运行时没有执行,窗口仍然留在任务栏中。
  3. 我尝试做同样的事情,除了我把Chrome窗口偷进了记事本窗口。同样的问题,当它确实偷走了窗户时,一切看起来都完全被撕裂了,导致浏览器几乎无法操作。
  4. 这是我使用的代码(Win32控制台应用程序):

    #include <conio.h> 
    #include <stdio.h>
    #include <Windows.h>
    #include <winuser.h>
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    LPCWSTR sClassName = L"MyClass";
    
    HWND CreateTheWindow(LPCWSTR WindowTitle) {
    
        // Create & register the class
        WNDCLASSEX WndClass;
        WndClass.cbSize = sizeof(WNDCLASSEX); WndClass.style = NULL; WndClass.lpfnWndProc = WndProc; 
        WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.lpszClassName = sClassName;
        WndClass.hInstance = NULL; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
        WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        WndClass.lpszMenuName  = NULL;  WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
        RegisterClassEx(&WndClass);
    
        // Create & show the window
        HWND hwnd = CreateWindowEx(WS_EX_STATICEDGE, sClassName, WindowTitle, WS_OVERLAPPEDWINDOW, 
            CW_USEDEFAULT, CW_USEDEFAULT, 320, 240, NULL, NULL, NULL, NULL);
    
        ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd);
        return hwnd;
    }
    
    // No idea what's this for, back in JS we simply had to do window.open 
    LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
        switch(Message) {
            case WM_CLOSE: DestroyWindow(hwnd); break;
            case WM_DESTROY: PostQuitMessage(0); break;
            default: return DefWindowProc(hwnd, Message, wParam, lParam);
        }
        return 0;
    }
    
    // start
    void main()
    {
        HWND chrome = FindWindow(L"Chrome_WidgetWin_1", NULL);
        HWND mywin = CreateTheWindow(L"HELLO BOSS");
    
        if(chrome!=0) printf("Got Chrome\r\n"); else printf("Chrome not found\r\n");
        if(mywin!=0) printf("Got yours\r\n"); else printf("Your window not found\r\n");
    
        SetParent(chrome, mywin);
        SetWindowLong(chrome, GWL_STYLE, WS_CHILDWINDOW | WS_VISIBLE  ); 
        UpdateWindow(chrome); 
        UpdateWindow(mywin);
    
        _getch();
    }
    

    哦,顺便说一句,请不要问我想要实现的目标。 :D这是一个惊喜。

2 个答案:

答案 0 :(得分:3)

您似乎没有运行消息循环,这对于您自己的窗口是必需的,并且可能需要在子节点和父节点之间传送消息。这似乎是被盗窗户似乎被锁定的最可能原因。 (可能还有其他问题,但我会从这里开始。)

尝试添加getch调用的基本消息循环:

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

可能还有其他困难。由于每线程消息队列,在另一个进程中具有子窗口是棘手的。与神话相反,它可以起作用:(多进程浏览器可以实现)。

您可能会从Chrome中抓取错误的窗口。请记住,Chrome也会玩这个游戏,在不同的进程中创建子窗口。你抓住其中一个孩子还是主框架窗口?

答案 1 :(得分:1)

我最终把窗户偷进了记事本。我所要做的就是摆脱Notepad的子编辑器窗口,油漆问题随之消失。

还需要应用的好样式是Chrome上的WS_CHILD和记事本上的WS_POPUP,然后是UIS_INITIALIZE WM_CHANGEUISTATE消息。

我真的希望Chrome Dev不会改变这种行为。

enter image description here