2016-04-20 50 views
2

我們使用GMA MouseHook來製作精美的Outlook VSTO AddIn。 由於我們的AddIn的複雜性,我們有點發展到了某個問題的角落。防止在MouseDown後發生MouseUp/MouseClick

我們的問題: 我們展望最大化,也被最大化在它上面的Mail.Compose窗口。如果我們單擊Mail.Compose窗口上的關閉按鈕,我們會在MouseDown事件中調用實際的窗口關閉。 現在,Mail.Compose窗口關閉,並且MouseUp + MouseClick事件在基礎Outlook主窗口的關閉按鈕上觸發。

我試過設置MouseEventArgs'e.Handled = True,但它仍然執行MouseUp + MouseClick事件。

任何想法如何解決這個問題?

編輯感謝mehrdad safa爲我指出了正確的方向! 這是我如何解決我的問題:

首先,我創建(如複製和從網上粘貼)這個類:

Imports System.Runtime.InteropServices 

Public Class MouseInterceptor 

    Public Delegate Function CallBack(_ 
    ByVal nCode As Integer, _ 
    ByVal wParam As IntPtr, _ 
    ByVal lParam As IntPtr) As Integer 

    'Declare the mouse hook constant. 
    'For other hook types, obtain these values from Winuser.h in Microsoft SDK. 
    Dim WH_MOUSE As Integer = 7 
    Shared hHook As Integer = 0 

    'Keep the reference so that the delegate is not garbage collected. 
    Private hookproc As CallBack 

    'Import for the SetWindowsHookEx function. 
    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _ 
    Public Overloads Shared Function SetWindowsHookEx _ 
      (ByVal idHook As Integer, ByVal HookProc As CallBack, _ 
      ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer 
    End Function 

    'Import for the CallNextHookEx function. 
    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _ 
    Public Overloads Shared Function CallNextHookEx _ 
      (ByVal idHook As Integer, ByVal nCode As Integer, _ 
      ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer 
    End Function 
    'Import for the UnhookWindowsHookEx function. 
    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _ 
    Public Overloads Shared Function UnhookWindowsHookEx _ 
       (ByVal idHook As Integer) As Boolean 
    End Function 

    'Point structure declaration. 
    <StructLayout(LayoutKind.Sequential)> Public Structure Point 
     Public x As Integer 
     Public y As Integer 
    End Structure 

    'MouseHookStruct structure declaration. 
    <StructLayout(LayoutKind.Sequential)> Public Structure MouseHookStruct 
     Public pt As Point 
     Public hwnd As Integer 
     Public wHitTestCode As Integer 
     Public dwExtraInfo As Integer 
    End Structure 

    Public Shared Function MouseHookProc(_ 
    ByVal nCode As Integer, _ 
    ByVal wParam As IntPtr, _ 
    ByVal lParam As IntPtr) As Integer 
     Dim MyMouseHookStruct As New MouseHookStruct() 

     If (nCode < 0) Then 
      Return CallNextHookEx(hHook, nCode, wParam, lParam) 
     End If 

     MyMouseHookStruct = CType(Marshal.PtrToStructure(lParam, MyMouseHookStruct.GetType()), MouseHookStruct) 

     Return CallNextHookEx(hHook, nCode, wParam, lParam) 

    End Function 

然後,我只是把它在我的MouseDown事件之前關閉窗口:

MouseInterceptor.MouseHookProc(0, "0x201", 0) 

的第一個參數告訴掛鉤,如果該系統應與其他事件的繼續,如果該值爲0 <所以我使用0的MouseDown之後停止。第二個參數的意思是「鼠標左鍵按下」,這個參數似乎表明它是單擊還是雙擊。我現在只是把它留在0。

回答

1

您應該使用setWindowsHook函數來設置LowLevelMouseProc的回調函數來處理全局鼠標事件。那麼你可以防止發送鼠標事件返回到Windows和其他應用程序。只是不要撥打callNextHook函數來防止窗口轉發消息!

使用這個例子:

class InterceptMouse 

{ 

private static LowLevelMouseProc _proc = HookCallback; 

private static IntPtr _hookID = IntPtr.Zero; 

public static void Main() 

{ 

    _hookID = SetHook(_proc); 

    Application.Run(); 

    UnhookWindowsHookEx(_hookID); 

} 

private static IntPtr SetHook(LowLevelMouseProc proc) 

{ 

    using (Process curProcess = Process.GetCurrentProcess()) 

    using (ProcessModule curModule = curProcess.MainModule) 

    { 

     return SetWindowsHookEx(WH_MOUSE_LL, proc, 

      GetModuleHandle(curModule.ModuleName), 0); 

    } 

} 

private delegate IntPtr LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam); 

private static IntPtr HookCallback( 

    int nCode, IntPtr wParam, IntPtr lParam) 

{ 

    if (nCode >= 0 && 

     MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam) 

    { 

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

     Console.WriteLine(hookStruct.pt.x + 「, 」 + hookStruct.pt.y); 

    } 

    return CallNextHookEx(_hookID, nCode, wParam, lParam); 

} 

private const int WH_MOUSE_LL = 14; 

private enum MouseMessages 

{ 

    WM_LBUTTONDOWN = 0x0201, 

    WM_LBUTTONUP = 0x0202, 

    WM_MOUSEMOVE = 0x0200, 

    WM_MOUSEWHEEL = 0x020A, 

    WM_RBUTTONDOWN = 0x0204, 

    WM_RBUTTONUP = 0x0205 

} 

[StructLayout(LayoutKind.Sequential)] 

private struct POINT 

{ 

    public int x; 

    public int y; 

} 

[StructLayout(LayoutKind.Sequential)] 

private struct MSLLHOOKSTRUCT 

{ 

    public POINT pt; 

    public uint mouseData; 

    public uint flags; 

    public uint time; 

    public IntPtr dwExtraInfo; 

} 

[DllImport(「user32.dll」, CharSet = CharSet.Auto, SetLastError = true)] 

private static extern IntPtr SetWindowsHookEx(int idHook, 

    LowLevelMouseProc lpfn, IntPtr hMod, uint dwThreadId); 

[DllImport(「user32.dll」, CharSet = CharSet.Auto, SetLastError = true)] 

[return: MarshalAs(UnmanagedType.Bool)] 

private static extern bool UnhookWindowsHookEx(IntPtr hhk); 

[DllImport(「user32.dll」, CharSet = CharSet.Auto, SetLastError = true)] 

private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, 

    IntPtr wParam, IntPtr lParam); 

[DllImport(「kernel32.dll」, CharSet = CharSet.Auto, SetLastError = true)] 

private static extern IntPtr GetModuleHandle(string lpModuleName); 

}

警告:防止鼠標向上事件的發生5發生意外進一步的問題。

+0

不客氣!這是我的榮幸。 –