WS_EX_TOOLWINDOW переход в фоновый режим при уничтожении окна

StackOverflow https://stackoverflow.com/questions/175738

  •  05-07-2019
  •  | 
  •  

Вопрос

Странная проблема:

  1. Откройте большое окно блокнота
  2. создать окно инструментов (стиль WS_EX_TOOLWINDOW)
  3. создать еще 2 окна (обычные с перекрытием) (WS_OVERLAPPED)
  4. закройте эти два перекрывающихся окна (дочернее окно рабочего стола или окно инструментов)
  5. окно инструментов перемещается за окно блокнота

Кто-нибудь знает, почему это так?Или что я могу делать не так?Я бы сказал «ошибка в Windows», но это бывает редко.

Чтобы ответить на вопросы:

Это не диалоговое окно, а полное окно.Если я сделаю это, у меня будут правильные дети (т.е.:не является дочерним элементом рабочего стола), запись для дочерних элементов на панели задач не отображается (вероятно, это легко исправить), но в любом случае ошибка все равно возникает.

Я включил пример кода, показывающий проблему.Я надеюсь, что я просто неправильно создаю окно или мне нужно ответить на сообщение, на которое я не отвечаю.

В этом примере откроется окно инструментов (без записи на панели задач, что и требуется).Затем вы нажмете на это окно, откроется подокно.Нажимаете на подокно, откроется другое окно.Затем закройте оба новых подокна, и исходное окно вместо того, чтобы получить фокус, сразу же перейдет за другие окна (блокнот и т. д.).

Спасибо за любую помощь!

Пример кода для пояснения:

// WindowToback.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "WindowToback.h"

// Global Variables:
HINSTANCE g_instance;
HWND g_mainWnd = NULL;

wchar_t *szWindowClass = L"WindowToBackSub";
wchar_t *szWindowClass2 = L"WindowToBackSub2";

ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    WndProc2(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    MSG msg;

    MyRegisterClass(hInstance);

// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
    return FALSE;
}

// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

return (int) msg.wParam;
}


ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style          = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc    = WndProc;
wcex.cbClsExtra     = 0;
wcex.cbWndExtra     = 0;
wcex.hInstance      = hInstance;
wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWTOBACK));
wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_WINDOWTOBACK);
wcex.lpszClassName  = szWindowClass;
wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

RegisterClassEx(&wcex);

wcex.lpfnWndProc    = WndProc2;
wcex.lpszClassName  = szWindowClass2;

return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   g_instance = hInstance; 
   g_mainWnd = CreateWindowEx(WS_EX_TOOLWINDOW,szWindowClass, szWindowClass,WS_OVERLAPPED,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!g_mainWnd) return FALSE;

   ShowWindow(g_mainWnd, nCmdShow);
   UpdateWindow(g_mainWnd);

   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
    case WM_LBUTTONDOWN:
    {
        HWND l_hwnd = CreateWindow(szWindowClass2, szWindowClass2, WS_VISIBLE | WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, g_instance, NULL);
        ShowWindow(l_hwnd,SW_SHOW);
        break;
    }

    case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    }
}

return DefWindowProc(hWnd, message, wParam, lParam);
}

LRESULT CALLBACK WndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
    case WM_LBUTTONDOWN:
    {
        HWND l_hwnd = CreateWindow(szWindowClass2, szWindowClass2, WS_VISIBLE | WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, g_instance, NULL);
        ShowWindow(l_hwnd,SW_SHOW);
    }
    break;
}

return DefWindowProc(hWnd, message, wParam, lParam);

}

Это было полезно?

Решение

Это неудивительно.На самом деле, это именно то поведение, которого я ожидал.

Окно инструментов не опускается;скорее Блокнот подпрыгивает.

Вы закрыли окно, в котором была активация.Система собирается активировать следующее по величине окно верхнего уровня в z-порядке.В этом отношении ваше окно инструментов не считается окном верхнего уровня (это часть того, что означает окно инструментов).Итак, Блокнот активируется и оказывается наверху.

Если вы хотите, чтобы вместо этого активировалось окно инструментов, вам, вероятно, на самом деле не нужно окно инструментов.

Другие советы

Являются ли эти три диалоговых окна другим главным окном или это отдельные приложения?

Если это диалоговые окна, я бы проверил, правильно ли назначено их родительское окно.

Если это окна приложений, я бы проверил, появляются ли они на панели задач.

Без дополнительной информации о проблеме трудно дать более содержательный ответ.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top