WS_EX_TOOLWINDOW sautant au fond de la fenêtre détruite
Question
Problème étrange:
- Ouvrez une grande fenêtre du bloc-notes
- créer une fenêtre d’outils (style WS_EX_TOOLWINDOW)
- créer 2 autres fenêtres (chevauchement normal) (WS_OVERLAPPED)
- fermez ces 2 fenêtres superposées (enfant du bureau ou de la fenêtre d'outils)
- la fenêtre d'outils saute derrière la fenêtre du bloc-notes
Est-ce que quelqu'un sait pourquoi c'est le cas? Ou ce que je pourrais faire mal? Je dirais "bug dans Windows", mais c'est rarement le cas.
Pour répondre aux questions:
Ce n'est pas une fenêtre de dialogue, mais une fenêtre complète. Si je lui donne des enfants corrects (c'est-à-dire: pas un enfant de bureau), l'entrée de la barre des tâches pour les enfants n'apparaît pas (probablement facilement réparable), mais dans tous les cas, le bogue persiste.
J'ai inclus un exemple de code illustrant le problème. J'espère que je crée simplement la fenêtre mal ou qu'il est nécessaire de répondre à un message auquel je ne réponds pas.
Dans cet exemple, une fenêtre d’outil s’ouvrira (aucune entrée dans la barre des tâches, ce qui est recherché). Ensuite, vous cliquez sur cette fenêtre, une sous-fenêtre s'ouvrira. Vous cliquez sur la sous-fenêtre, une autre fenêtre s'ouvrira. Ensuite, fermez les deux nouvelles fenêtres et la fenêtre d’origine, au lieu d’être centrées, saute immédiatement derrière les fenêtres (bloc-notes, etc.).
Merci pour toute aide!
Exemple de code à préciser:
// 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);
}
La solution
Ce n'est pas surprenant. En fait, c'est exactement le comportement auquel je m'attendais.
Votre fenêtre d’outil ne saute pas; le Bloc-notes saute plutôt.
Vous avez fermé la fenêtre d'activation. Le système va activer la fenêtre de niveau supérieur la plus haute suivante dans l'ordre z. À cet égard, votre fenêtre d’outil ne compte pas comme une fenêtre de niveau supérieur (cela fait partie de ce qu’est une fenêtre d’outil). Donc, le Bloc-notes est activé et arrive au sommet.
Si vous souhaitez que votre fenêtre d'outils soit activée à la place, vous ne voulez probablement pas vraiment une fenêtre d'outils.
Autres conseils
Les trois fenêtres dialogues sont-elles dans une autre fenêtre principale ou s'agit-il d'applications à part entière?
Si ce sont des fenêtres de dialogue, je vérifierais que la fenêtre parente est correctement attribuée.
Si ce sont des fenêtres d’application, je vérifierais qu’elles apparaissent dans la barre des tâches.
Sans plus d'informations sur le problème, il est difficile de donner une réponse plus significative.