Warum kann mein Eigentum Blatt, von einem System-Tray-Icon angezeigt, sperren Sie die Taskleiste auf?

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

  •  19-09-2019
  •  | 
  •  

Frage

. Hinweis: Codebeispiele wurden vereinfacht, aber die Gesamtstruktur intakt bleibt

Ich arbeite an einer Win32-Anwendung, deren Haupt-Schnittstelle ist ein System-Tray-Symbol. Ich erstelle ein Dummy-Fenster, mit HWND_MESSAGE als übergeordnetem, das Symbol der Nachrichten empfangen:

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);

Dann wird das Symbol erstellt wird, unter Bezugnahme auf diese Nachricht nur für Fenster:

NOTIFYICONDATA iconData;
iconData.hWnd = iconWindowHandle;
iconData.uCallbackMessage = TRAYICON_MESSAGE;
// ...
Shell_NotifyIcon(NIM_ADD, &iconData)

Wenn der Tray-Icon doppelt geklickt, ich erstellen und eine Karteikarte zeigen (von 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);
}

Das Eigenschaftsblatt hat kein übergeordnetes Fenster. Die PropertySheet Funktion wird aus dem Fensterprozedur der Nachricht nur Fenster genannt. Die PSH_MODELESS Flag nicht gesetzt ist; so PropertySheet kehrt erst nach dem Eigenschaftsfenster Fenster wieder geschlossen wird:

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);
}

Nun all dies funktioniert ganz gut, bis ich einen Haltepunkt in der Dialogprozedur eines des Eigenschaftsfensters der Seite festgelegt:

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

Wenn das Programm nicht mehr auf dem Haltepunkt, die gesamten Taskleiste blockiert

Der Call-Stack ist ziemlich nutzlos; es zeigt, dass das Dialogverfahren von irgendwo innerhalb comctl32.dll genannt wird, über einige Anrufe innerhalb user32.dll. Keine Fensterprozedur meiner eigenen ist dazwischen.

das Eigenschaftsblatt nicht modalen machen nicht zu helfen scheint. Auch ich würde lieber nicht tun, weil es den Code komplexer macht.

Solange mein Dialogprozedur schnell genug zurückkehrt, sollte dies kein Problem sein. Aber es scheint so seltsam, dass ein längerer Betrieb innerhalb des Dialogverfahrens würde nicht nur den Dialog perren selbst, sondern die gesamte Schale. Ich kann mir vorstellen, dass die Nachricht nur für Fensterprozedur die Kraft, dieses Verhalten zu veranlassen hat, da es mehr ist eng mit dem Tray-Icon im Zusammenhang ... aber diese Funktion ist nicht auf dem Call-Stack angezeigt.

Mache ich etwas grundlegend falsch? Kann jemand etwas Licht ins Dunkel bringen?

War es hilfreich?

Lösung

Eigentlich ist es ziemlich offensichtlich, und die Verwirrung aufgrund eines Mangels an Kaffee gewesen sein muss.

Die Taskleiste verwendet wahrscheinlich SendMessage die Nachricht an meine Bewerbung zu senden, die es, bis die Nachricht verarbeitet wird blockieren verursacht. SendMessageTimeout ist offenbar nicht verwendet.

Ich denke immer noch seltsam es ist, dass keine Funktion meiner eigenen Shows bis auf den Call-Stack. Sicher, eine solche Nachricht muss meine Nachrichtenschleife fließen, um durch verarbeitet zu werden? Vielleicht ist die Warnung, dass „Stapelrahmen unterhalb dieser Linie unvollständig sind oder fehlen“ war eigentlich gut, dann.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top