注意:码样本已被简化,但整体结构保持完整

我工作的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几个电话。我没有自己的窗口过程是介于两者之间。

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

只要我的对话过程返回的速度不够快,这不应该是一个问题。但它似乎很奇怪的是,对话的过程中更长的操作不仅会锁定对话框本身,而是整个外壳。我可以想像,唯一的消息窗口过程有可能导致这种行为的权力,因为它更密切相关的托盘图标...但此功能未调用堆栈上显示。

我做得基本上是错误的?任何人都可以提供一些线索对这个问题?

有帮助吗?

解决方案

其实,这是相当明显,而混乱一定是由于缺乏咖啡。

在任务栏可能使用SendMessage将消息发送到我的应用程序,这会导致它阻塞直到该消息被处理。 SendMessageTimeout显然不被使用。

我仍然认为这是奇怪的是,没有自己拍的戏函数调用堆栈上。当然,要处理这种消息必须按顺序流动通过我的消息循环?也许警告“这条线之下的堆栈帧可以是不完整的或缺失”实际上是正确的,那么

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top