Владелец и Владелец окна Проблема активации - PullRequest
2 голосов
/ 24 февраля 2020

В экспериментальном коде при создании трех верхних уровней windows с иерархическим владением я вижу странное поведение при отклонении их в обратном порядке .

Код:

#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);
}

Код выше делает это:

  1. Создает окно верхнего уровня Main Window
  2. Создает другой верхний уровень окно Window 2 и назначает его владельца как Main Window
  3. Создает еще одно окно верхнего уровня Window 3 и назначает его владельца как Window 2
  4. Все немодально, если вы внимательно наблюдаете , но с правильным владельцем

Теперь, когда это приложение запущено (Release built, run on Windows 10 x64) и мы закрываем windows в обратном порядке, после закрытия Window 2 активация уходит в существующее окно Notepad .

Поведение можно увидеть на следующем снимке экрана:

enter image description here

Мне интересно, что происходит. Как правило, такого рода поведение возникает, когда мы пропускаем правильную настройку владельца!

Во-вторых, при поиске по окрестностям я иногда вижу, что фокус переходит к окну Default IME (т. Е. Windows Редактор метода ввода). Я думаю, что окно по умолчанию назначается для IME для каждого приложения с пользовательским интерфейсом? Если это так, может быть, как только я создаю Main Window, создается окно IME, а затем при моих следующих вызовах на CreateWindowW создаются другие 2 принадлежащие windows, таким образом меняются родные братья на верхнем уровне windows список? Пока это всего лишь предположение.

Может кто-нибудь объяснить это, и каков обходной путь "без взлома" для этого?

...