Примечание: образцы кода были упрощены, но общая структура остается нетронутой.Почему моя панель свойств, показанная на значке в системном трее, блокирует панель задач?
Я работаю над приложением Win32, основным интерфейсом которого является значок в системном трее. Создать фиктивный окно, используя HWND_MESSAGE
в качестве родителя, чтобы получать сообщения значка:
WNDCLASSEX wndClass;
wndClass.lpfnWndProc = &iconWindowProc;
// ...
iconWindowHandle = CreateWindow(wndClass.lpszClassName, _T(""), 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_MESSAGE, NULL, GetModuleHandle(NULL), 0);
Затем создается значок, ссылаясь на это сообщение только для окна:
NOTIFYICONDATA iconData;
iconData.hWnd = iconWindowHandle;
iconData.uCallbackMessage = TRAYICON_MESSAGE;
// ...
Shell_NotifyIcon(NIM_ADD, &iconData)
Когда иконка в трее это двойной щелчок, я создаю и показать лист свойств (от comctl32.dll
):
LRESULT CALLBACK iconWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case TRAYICON_MESSAGE:
switch (lParam) { // that contains the "real" message
case WM_LBUTTONDBLCLK:
showPropertySheet();
return 0;
// ...
}
break;
// ...
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
лист свойств не имеет родительского окна. Функция PropertySheet
вызывается из оконной процедуры окна только для сообщений. Флаг PSH_MODELESS
не установлен; Таким образом, PropertySheet
возвращается только после того, как окно свойств листа снова закрывается:
void showPropertySheet() {
PROPSHEETPAGE pages[NUM_PAGES];
pages[0].pfnDlgProc = &firstPageDialogProc;
// ...
PROPSHEETHEADER header;
header.hwndParent = NULL;
header.dwFlags = PSH_PROPSHEETPAGE | PSH_USECALLBACK;
header.ppsp = pages;
// ...
PropertySheet(&header);
}
Теперь все это работает просто отлично, пока я не поставил точку останова внутри диалоговой процедуры одной из страниц таблицы свойств в:
BOOL CALLBACK firstPageDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
return FALSE; // breakpoint here
}
Когда программа останавливается в точке останова, вся панель задач блокируется!
Стол вызовов совершенно бесполезен; он показывает, что процедура диалога вызывается где-то внутри comctl32.dll
через некоторые вызовы внутри user32.dll
. Никакая оконная процедура не находится между ними.
Выполнение этой функции не помогает. Кроме того, я бы предпочел не делать этого, потому что это делает код более сложным.
До тех пор, пока моя процедура диалога вернется достаточно быстро, это не должно быть проблемой. Но кажется странным, что более длительная операция внутри процедуры диалога не только закроет сам диалог, но и всю оболочку. Я могу представить, что процедура окна только для сообщений имеет право вызвать такое поведение, поскольку оно более тесно связано с значком в трее ... но эта функция не отображается в стеке вызовов.
Я делаю что-то принципиально неправильно? Может ли кто-нибудь пролить свет на эту проблему?