Pourquoi mon feuille de propriétés, illustrée d'une icône de la barre système, verrouiller la barre des tâches?

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

  •  19-09-2019
  •  | 
  •  

Question

Remarque:. Exemples de code ont été simplifiées, mais la structure globale reste intacte

Je travaille sur une application Win32 dont l'interface principale est une icône de la barre système. Je crée une fenêtre factice, en utilisant HWND_MESSAGE comme parent, de recevoir les messages de l'icône:

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

Ensuite, l'icône est créée, se référant à cette fenêtre de message uniquement:

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

Lorsque l'icône est double cliquée, je crée et montrer une feuille de propriétés (de 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);
}

La feuille de propriétés n'a pas de fenêtre parent. La fonction est appelée PropertySheet de la procédure de fenêtre de la fenêtre de message uniquement. Le drapeau de PSH_MODELESS n'est pas défini; Ainsi, PropertySheet renvoie uniquement après que la fenêtre de la feuille de propriétés est à nouveau fermé:

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

Maintenant tout cela fonctionne très bien, jusqu'à ce que je mets un point d'arrêt dans la procédure de dialogue de l'une des pages de la feuille de propriétés:

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

Lorsque le programme cesse sur le point d'arrêt, l'ensemble des verrous de la barre des tâches vers le haut

La pile d'appel est tout à fait inutile; il montre que la procédure de dialogue est appelée à partir de quelque part à l'intérieur comctl32.dll, via des appels à l'intérieur user32.dll. Aucune procédure de fenêtre de mon propre est entre les deux.

Faire la feuille de propriétés modales ne semble pas aider. De plus, je préfère ne pas le faire parce que cela rend le code plus complexe.

Tant que ma procédure de dialogue revient assez rapidement, cela ne devrait pas être un problème. Mais il semble si étrange qu'une opération plus à l'intérieur de la procédure de dialogue ne se verrouille pas seulement la boîte de dialogue lui-même, mais l'ensemble de la coquille. Je peux imaginer que la procédure de fenêtre des messages uniquement a le pouvoir de provoquer ce problème, car il est plus étroitement lié à l'icône de la barre ... mais cette fonction ne figure pas sur la pile d'appel.

Est-ce que je fais quelque chose de fondamentalement mauvais? Quelqu'un peut-il faire la lumière sur cette question?

Était-ce utile?

La solution

En fait, il est assez évident, et la confusion doit être dû à un manque de café.

La barre des tâches utilise probablement SendMessage pour envoyer le message à ma demande, ce qui entraîne à bloquer jusqu'à ce que le message est traité. SendMessageTimeout est apparemment pas utilisé.

Je pense toujours qu'il est étrange qu'aucune fonction de mes propres spectacles sur la pile d'appels. Certes, un tel message doit passer par ma boucle de message afin d'être traité? Peut-être l'avertissement que « les cadres de pile en dessous de cette ligne peuvent être incomplètes ou manquantes » était en fait bien, alors.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top