Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winapi 为什么我的属性页(从系统托盘图标显示)可以锁定任务栏?_Winapi_System Tray_Trayicon - Fatal编程技术网

Winapi 为什么我的属性页(从系统托盘图标显示)可以锁定任务栏?

Winapi 为什么我的属性页(从系统托盘图标显示)可以锁定任务栏?,winapi,system-tray,trayicon,Winapi,System Tray,Trayicon,注意:代码示例已简化,但总体结构保持不变 我正在开发一个Win32应用程序,它的主界面是一个系统托盘图标。我创建了一个虚拟窗口,使用HWND_MESSAGE作为其父窗口,以接收图标的消息: WNDCLASSEX wndClass; wndClass.lpfnWndProc = &iconWindowProc; // ... iconWindowHandle = CreateWindow(wndClass.lpszClassName, _T(""), 0, CW_USEDEFAULT, C

注意:代码示例已简化,但总体结构保持不变

我正在开发一个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
):

属性页没有父窗口。
PropertySheet
函数是从仅消息窗口的窗口过程调用的。未设置
PSH_无模式
标志;因此,
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
内部的一些调用调用的。没有我自己的窗口程序介于两者之间

使属性表无模式似乎没有帮助。另外,我不希望这样做,因为这会使代码更加复杂

只要我的对话过程足够快地返回,这应该不会是一个问题。但是,在对话框过程中执行更长的操作不仅会锁定对话框本身,而且会锁定整个shell,这看起来非常奇怪。我可以想象,只显示消息的窗口过程具有导致这种行为的能力,因为它与托盘图标更密切相关。。。但是这个函数没有显示在调用堆栈上


我是不是做错了什么?有人能解释一下这个问题吗?

事实上,这是很明显的,这种混乱肯定是因为缺少咖啡

任务栏可能使用
SendMessage
将消息发送到我的应用程序,这会导致它阻塞,直到消息得到处理<代码>发送消息超时显然未使用

我仍然觉得奇怪的是,调用堆栈上没有显示我自己的函数。当然,这样的消息必须通过我的消息循环才能被处理?也许“这条线下的堆栈帧可能不完整或丢失”的警告实际上是正确的

BOOL CALLBACK firstPageDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  return FALSE; // breakpoint here
}