2009-07-24 5 views
1

J'essaye d'attraper des messages d'une application pour laquelle je n'ai aucun code source.
j'installer un crochet de Windows comme ceci:Problème avec WH_CALLWNDPROCRET

hhk = SetWindowsHookEx(WH_CALLWNDPROCRET, HookProcSetTextRet, hinst, threadID); 

(La variable HHK est dans les données partagées.)
Je ne comprends pas certains comportements, mais, plus précisément:

LRESULT CALLBACK HookProcSetTextRet(int code,WPARAM wParam,LPARAM lParam) { 
PCWPRETSTRUCT st = (PCWPRETSTRUCT)lParam; 
switch (HIWORD(st->wParam)) { 
    case WM_COMMAND: { 
     /* 
     For lbn_xxx: 
     wParam 
     The low-order word is the list box identifier. 
     The high-order word is the notification message. 

     lParam 
     Handle to the list box. 
     */ 
      switch (HIWORD(st->wParam)) { 
       case LBN_DBLCLK: { 
         log << L"\tWM_COMMAND --- LBN_DBLCLK" << endl; 
        } 
        break; 

       case LBN_SELCHANGE: { 
         log << L"\t+++ WM_COMMAND -LBN_SELCHANGE" << endl; 
         log << L"\t\tHandle to list box : " << st->lParam << endl; 

         HWND lbHwnd = (HWND) st->lParam; 

         res = SendMessage(lbHwnd, LB_GETCOUNT, 0, 0); 
         curSel = SendMessage(lbHwnd, LB_GETCURSEL, 0, 0); 
         log << L"\t\t\tLB_GETCURSEL returned : " << curSel << endl; 
         if (LB_ERR != curSel) { 
          res = SendMessage(lbHwnd, LB_GETTEXT, curSel, 
            (LPARAM)(LPTSTR) szBuf); 
           log << L"\t\tLB_GETTEXT returned : " << res <<     
             L"\t\tszBuf: " << szBuf << endl; 
         } 
        } 
        break; 

       default: 
        break; 
      } 
     } // WM_COMMAND 
    /* snip */ 
} 
return CallNextHookEx(0, code, wParam, lParam); 
} 

LBN_SELCHANGE est intercepté, mais la valeur renvoyée par LB_GETCURSEL et LB_GETTEXT est toujours la même.
LBN_DBLCLK n'est jamais intercepté.

Il existe également une incohérence similaire avec d'autres messages WM_. L'application elle-même mange-t-elle ces messages?
Merci pour toutes les idées ...

MISE À JOUR:
Suite à la suggestion ci-dessous, je mis en place un crochet WH_GETMESSAGE. Il semble obtenir le message doubleclick de la liste.
Malheureusement, LB_GETCOUNT retourne le nombre correct, mais LB_GETCURSEL retourne toujours 0, et LB_GETTEXT retourne toujours rien ...

case WM_LBUTTONDBLCLK: { 
     const unsigned int BUFFER_SIZE = 1024; 
     wchar_t titleBuffer[BUFFER_SIZE]; 
     UINT curSel = LB_ERR; 
     LRESULT res = LB_ERR; 

     MSG * pMsg = (MSG *) lParam; 
     HWND lbHwnd = pMsg->hwnd; 

     log << L"\tGetMsgProc\t\tWM_LBUTTONDBLCLK" << endl; 

     // Sanity check 
     HWND parent = GetParent(lbHwnd); 
     GetWindowText(parent, titleBuffer, BUFFER_SIZE - 1); 
     log << L"\t\tParent Title : " << titleBuffer << L"\tParent HWND : " << parent << endl; 

     // Sanity check 
     GetClassName(lbHwnd, titleBuffer, BUFFER_SIZE - 1); 
     log << L"\t\tList box class name: " << titleBuffer << L"\tList box hwnd: " << pMsg->hwnd << endl; 

     res = SendMessage(lbHwnd, LB_GETCOUNT, 0, 0); 
     if (LB_ERR != res) { log << L"\t\t\tLB_GETCOUNT : " << res << endl; } 

     curSel = SendMessage(lbHwnd, LB_GETCURSEL, 0, 0); 
     log << L"\t\t\tLB_GETCURSEL returned : " << curSel << endl; 
     if (LB_ERR != curSel) { 
      res = SendMessage(lbHwnd, LB_GETTEXT, curSel, (LPARAM)(LPTSTR) titleBuffer); 
      if (LB_ERR == res) { log << L"\t\t\tLB_GETTEXT Error -- invalid index" << endl; } 
      else { 
       log << L"\t\tLB_GETTEXT returned : " << res << L"\t\tszBuf: " << titleBuffer << endl; 
      } 
     } 
     else { log << L"\t\tLB_GETCURSEL returned LB_ERR" << endl; } 
    } 
+0

La zone de liste est-elle multi ou unique? La documentation du message LB_GETCURSEL indique clairement qu'il ne doit pas et ne fonctionnera pas avec les zones de liste à plusieurs sélections. – DeusAduro

+0

Assurez-vous qu'il s'agit d'un choix unique. Je vais voir ce qui se passe avec LB_GETSELCOUNT. Aucune raison pour laquelle il y a le message LBN_SELCHANGED, mais pas LBN_DBLCLK? – Number8

+0

LB_GETSELCOUNT renvoie LB_ERR. – Number8

Répondre

0

LBN_DBLCLK ne sera pas envoyé si la liste n'a pas l'état LBS_NOTIFY fixé sur elle . Je ne sais pas pourquoi LB_GETCURSEL et LB_GETTEXT ne fonctionnent pas ...

1

J'ai toujours trouvé que la documentation sur les crochets de fenêtres manquait cruellement.

De leurs noms, je pense que le crochet WH_CALLWNDPROCRET serait toujours appelé quelque part après un crochet WH_CALLWNDPROC correspondant. La documentation de SendWindowsHookEx dit à propos WH_CALLWNDPROC:

Installe une procédure de crochet qui surveille les messages avant que le système les envoie à la procédure de fenêtre de destination.

Cela suggère qu'il ne reçoit que les messages sont envoyés (SendMessage, qui appelle la procédure de fenêtre directement), pas posté (PostMessage, qui met le message dans la file d'attente des messages).

Si tel est effectivement le problème, vous pouvez essayer d'installer un crochet WH_GETMESSAGE avec votre crochet existant. Ce hook est appelé lorsque les messages sont supprimés de la file d'attente de messages (par la procédure de fenêtre, généralement). Essayez de voir si ce crochet attrape les messages perdus.

+0

Merci, je vais essayer ... – Number8

+0

Voir mise à jour dans OP. – Number8

+0

Désolé, je suis à la perte aussi.Peut-être essayer de désactiver votre hook 'WH_CALLWNDPROCRET', voir si cela fait une différence? – Thomas