2009-02-06 14 views
5

J'ai une fenêtre pour gérer les messages WM_NCLBUTTONUP, afin de gérer les clics sur les boutons personnalisés dans la barre de légende. Cela fonctionne très bien lorsque la fenêtre est agrandie, mais quand ce n'est pas le cas, le message WM_NCLBUTTONUP n'arrive jamais! J'obtiens un message WM_NCLBUTTONDOWN cependant. Bizarrement WM_NCLBUTTONUP arrive si je clique sur la droite de la barre de menu, mais n'importe où le long de la barre de légende/cadre de la fenêtre, le message n'arrive jamais. Après un moment de débogage, j'ai découvert que si je définissais un point d'arrêt sur CMainFrame :: OnNcLButtonDown(), je cliquais sur la barre de légende, mais maintenez le bouton de la souris enfoncé, laissez le débogueur interrompre la fonction, appuyez sur F5 pour continuer débogage, puis relâchez le bouton de la souris - magiquement WM_NCLBUTTONUP est envoyé !!Le curieux problème du message WM_NCLBUTTONUP manquant lorsqu'une fenêtre n'est pas agrandie

Ma question est double, (1) qu'est-ce qui se passe? (2) comment contourner ce "problème".

Je remarque également qu'il y a plusieurs autres personnes sur Internet qui ont le même problème (un rapide Google révèle beaucoup d'autres personnes avec le même problème, mais aucune solution).

Modifier
Merci pour les deux premières réponses, j'ai essayé d'appeler ReleaseCapture dans NCLButtonDown, mais il n'a pas d'effet (en fait, elle retourne NULL, ce qui indique une capture est pas en place). Je ne peux que supposer que la fonctionnalité de classe de base (def window proc) peut définir une capture. Je vais enquêter sur lundi ...

Répondre

4

J'ai eu le même problème. Le problème est en effet qu'un clic gauche sur la légende de la fenêtre commence un glissement, et donc la capture de la souris, ce qui empêche WM_NCLBUTTONUP d'arriver.

La solution est de passer outre WM_NCHITTEST:

LRESULT CALLBACK WndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam) 
{ 
    switch (nMsg) 
    { 
     ... 
     case WM_NCHITTEST: 
      Point p(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam); 
      ScreenToClient(p); 
      if (myButtonRect.Contains(p)) 
      { 
       return HTBORDER; 
      } 
      break; 
    } 
    return DefWindowProc(hWnd, nMsg, wParam, lParam); 
} 

donc essentiellement vous indiquer à Windows que la zone occupée par le bouton ne fait pas partie de la légende de la fenêtre, mais une partie non spécifique de la zone non-client (HTBORDER). Note: Si vous avez appelé SetCapture() et pas encore appelé ReleaseCapture() lorsque vous attendez que le message WM_NCLBUTTONDOWN arrive, il n'arrivera pas même avec la modification ci-dessus. Cela peut être irritant car il est normal de capturer la souris lors de l'interaction avec de tels boutons personnalisés afin que vous puissiez annuler le clic/surligner si la souris quitte la fenêtre. Toutefois, comme alternative à l'utilisation de la capture, vous pouvez considérer SetTimer()/KillTimer() avec un intervalle court (par exemple 100 ms), ce qui ne provoquera pas l'annulation des messages WM_NCLBUTTONUP.

2

Une conjecture sauvage - du code capture la souris, probablement pour faciliter le déplacement de la fenêtre lorsque vous récupérez le titre. Cela expliquerait également pourquoi la rupture dans le débogueur provoquerait l'affichage du message - l'interaction du débogueur efface la capture de la souris.

Je vous suggère d'exécuter Spy ++ sur cette fenêtre et c'est les enfants et essayer de comprendre qui reçoit le message bouton.

En ce qui concerne la façon de résoudre ce problème - ne peut pas vous aider sans regarder le code réel. Vous devrez déterminer qui est le coupable et regarder leur code.

1

Pour ajouter à Franci Penov's answer, un clic sur la barre de titre est interprété comme le début d'un glisser pour repositionner la fenêtre. La fenêtre capture la souris afin qu'elle puisse effectuer le glisser. Étant donné qu'une fenêtre agrandie ne peut pas être déplacée, la capture est ignorée et le message est routé normalement.

1

inclure ReleaseCapture() dans WM_NCLBUTTONDOWN {code bloc}

Questions connexes