2012-10-13 6 views
2

Dans mon projet C# j'essaie d'intercepter les clics de souris à partir d'un autre programme, mais seulement ceux qui proviennent d'un certain hwnd aussi ... J'ai lu here que je peux filtrer mes messages en utilisant le lParam mais je n'ai pas réussi à le projeter sur quelque chose dont je peux réellement obtenir le retour de Hwnd.Cast IntPtr à CWPSTRUCT

Voilà comment je mis en place le crochet de la souris mondiale:

SetWindowsHookEx(WH_MOUSE_LL, s_MouseDelegate, IntPtr.Zero, 0); 

je puis attraper les messages dans cette fonction:

private static int MouseHookProc(int nCode, int wParam, IntPtr lParam) 
{ 
    if (nCode >= 0) 
    { 
      switch (wParam) 
      { 
       case WM_LBUTTONDOWN: 
        mouseDown = true; 
        mouseUp = false; 
        break; 
       case WM_LBUTTONUP: 
        mouseUp = true; 
        mouseDown = false; 
        break; 
      } 
    } 
    return CallNextHookEx(s_MouseHookHandle, nCode, wParam, lParam); 
} 

Je me suis alors fait la CWPSTRUCT comme ceci:

[StructLayout(LayoutKind.Sequential)] 
public struct CWPSTRUCT 
{ 
    public IntPtr lparam; 
    public IntPtr wparam; 
    public int message; 
    public IntPtr hwnd; 
} 

Et voici la partie où ça va probablement mal ... J'ai essayé 2 choses:

CWPSTRUCT cwp = (CWPSTRUCT)Marshal.PtrToStructure(lParam, typeof(CWPSTRUCT)); 

Ou la version dangereuse this is where I got it from:

CWPSTRUCT* cp = (CWPSTRUCT*)lParam; 

Lorsque vous utilisez la première option je reçois toujours 0 pour la partie hwnd et la version dangereuse Je viens obtenir rien ... Je ne sais pas vraiment sais ce que je fais mal ici. Toute aide serait appréciée :)

Merci

Répondre

1

Puisque vous accrocher WH_MOUSE_LL, lParam contient pointeur vers MSLLHOOKSTRUCT au lieu de CWPSTRUCT (qui est en fait pour WH_CALLWNDPROC).

Vous devez donc définir les structures suivantes:

[StructLayout(LayoutKind.Sequential)] 
public struct POINT 
{ 
    public int X; 
    public int Y; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct MSLLHOOKSTRUCT 
{ 
    public POINT pt; 
    public int mouseData; 
    public int flags; 
    public int time; 
    public UIntPtr dwExtraInfo; 
} 

maréchal lParam-MSLLHOOKSTRUCT:

MSLLHOOKSTRUCT mouseLowLevelHook = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, 
    typeof(MSLLHOOKSTRUCT)); 

En outre, vous devez changer le type de wParam de int à IntPtr, il fonctionnera correctement sur les plates-formes 64 bits.

Liens supplémentaires:

+0

Merci beaucoup! Cela a résolu mon problème. J'ai une petite question à gauche ... le UIntPtr dwExtraInfo, qu'est-ce qu'il contient exactement? (Informations supplémentaires associées au message.) Parce que je pensais que c'était peut-être la fenêtre sur laquelle je cliquais? Mais je ne pense pas que ce soit parce que c'est 0 aussi. J'ai obtenu le handle de la fenêtre sur laquelle j'ai cliqué maintenant en utilisant [WindowFromPoint] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633558%28v=vs.85%29.aspx) est-ce la bonne façon? – VincentC

+0

@VincentC 'dwExtraInfo' semble être une référence aux informations supplémentaires spécifiques à l'application. –

+0

@VincentC Oui, vous pouvez utiliser ['WindowFromPoint'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633558%28v=vs.85%29.aspx) pour obtenir hwnd.Bien qu'il soit préférable de créer un hook global pour ['WH_MOUSE'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644988 (v = vs.85) .aspx) ou [ 'WH_CALLWNDPROC'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644975 (v = vs.85) .aspx). Vous pouvez lire à ce sujet ici: [Utilisation de messages de fenêtre pour implémenter Global Hooks système en C#] (http://www.codeproject.com/Articles/18638/Using-Window-Messages-to-Implement-Global-System-H) –