在MouseDown之后阻止MouseUp / MouseClick发生

时间:2016-04-20 09:17:25

标签: vb.net outlook-addin

我们正在使用GMA MouseHook进行精心设计的Outlook VSTO AddIn。 由于我们AddIn的复杂性,我们在某些问题上发展成了一个角落。

我们的问题: 我们已经使Outlook最大化,并且Mail.Compose窗口也最大化了。如果我们单击Mail.Compose窗口上的关闭按钮,我们将在MouseDown-Event中调用实际的窗口关闭。 现在,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

然后我在关闭Window之前在我的MouseDown事件中调用它:

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

如果值为&lt;

第一个参数告诉Hook系统是否应该继续其他事件。所以我在MouseDown之后使用0来停止。第二个参数意味着&#34;左鼠标按钮向下&#34;,他们的参数似乎表明它是单击还是双击。我现在把它留在0。

1 个答案:

答案 0 :(得分:1)

您应该使用LowLevelMouseProc函数设置setWindowsHook的回调来处理全局鼠标事件。那么你可以防止将鼠标注册事件发送回窗口和其他应用程序。只是不要调用callNextHook函数来阻止Windows转发消息!

使用此示例:

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

}

警告:防止发生鼠标事件可能会发生意外的进一步问题。