Owner and Owned window Activation issue

假装没事ソ 提交于 2021-02-04 18:54:05

问题


In an experimental code, when creating three top level windows with hierarchical ownership I am seeing weird behavior when dismissing them in reverse order.

Code:

#include <Windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    MSG msg;
    WNDCLASS wndClass;
    WCHAR className[] = L"OwnedWindowsWeirdness";

    wndClass.cbClsExtra = 0;
    wndClass.cbWndExtra = 0;
    wndClass.lpszMenuName = NULL;
    wndClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
    wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wndClass.hInstance = hInstance;
    wndClass.lpfnWndProc = WndProc;
    wndClass.lpszClassName = className;
    wndClass.style = CS_HREDRAW | CS_VREDRAW;

    if(!RegisterClassW(&wndClass))
    {
        MessageBoxW(0, L"Unable to register class...Exiting!", className, MB_OK);
        return -1;
    }

    HWND hwnd1 = CreateWindowW(className, L"Main Window", WS_OVERLAPPEDWINDOW, 
                               CW_USEDEFAULT, CW_USEDEFAULT, 500, 400, 
                               NULL, 0, hInstance, 0);
    HWND hwnd2 = CreateWindowW(className, L"Main Window > Window 2", WS_OVERLAPPEDWINDOW, 
                               CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, 
                               hwnd1, 0, hInstance, 0);

    HWND hwnd3 = CreateWindowW(className, L"Main Window > Window 2 > Window 3", WS_OVERLAPPEDWINDOW,
                               CW_USEDEFAULT, CW_USEDEFAULT, 300, 200,
                               hwnd2, 0, hInstance, 0);

    ShowWindow(hwnd1, SW_SHOWNORMAL);
    UpdateWindow(hwnd1);

    ShowWindow(hwnd2, SW_SHOWNORMAL);
    UpdateWindow(hwnd2);

    ShowWindow(hwnd3, SW_SHOWNORMAL);
    UpdateWindow(hwnd3);

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

    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    // Subdeveloper: Purposefully not complicating the code by calling PostQuitMessage/etc!
    // In absence of which, this test application will need to be closed using 
    // task manager

    return DefWindowProc(hwnd, iMsg, wParam, lParam);
}

The code above does this:

  1. Creates a top level window Main Window
  2. Creates another top level window Window 2 and assigns its owner as Main Window
  3. Creates yet another top level window Window 3 and assigns its owner as Window 2
  4. All are non-modal if you observe closely, but with correct ownership

Now when this application is run (Release built, run on Windows 10 x64) and we close the windows in reverse order, after closing Window 2 activation goes away to existing Notepad window.

The behavior could be seen in following screen capture:

I am wondering what is going on. Generally this kind of behavior occurs when we miss setting correct ownership!

Secondly, when hunting around I did see that focus goes to Default IME window sometimes (i.e. Windows Input Method Editor). I think a default window is assigned for IME to every application with UI? If so maybe as soon as I create the Main Window, an IME window is created, and then on my next calls to CreateWindowW, the other 2 owned windows are created, thus changing the siblings in top level windows list? This is just a speculation for now.

Can someone explain this, and whats the "no-hack" workaround for this?


回答1:


Adding additional WS_POPUP style to Window 2 (Or use WS_CAPTION | WS_POPUPWINDOW replace WS_OVERLAPPEDWINDOW.) solves the issue for me.

With WS_POPUP, the ownership will be picked, you will see the behavior you expected. Without WS_POPUP, system will find the next window to activate, this is undocumented.



来源:https://stackoverflow.com/questions/60377627/owner-and-owned-window-activation-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!