【问题标题】:Prevent MouseUp/MouseClick from happening after MouseDown防止 MouseUp/MouseClick 在 MouseDown 之后发生
【发布时间】:2016-08-12 20:34:38
【问题描述】:

我们使用GMA MouseHook 来制作精美的 Outlook VSTO 插件。 由于我们的 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

然后我只是在关闭窗口之前在我的 MouseDown 事件中调用它:

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

第一个参数告诉 Hook 如果值

【问题讨论】:

    标签: vb.net outlook-addin


    【解决方案1】:

    您应该使用setWindowsHook 函数为LowLevelMouseProc 设置回调来处理全局鼠标事件。然后您可以防止将鼠标向上事件发送回 Windows 和其他应用程序。只是不要调用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);  
    

    }

    警告:阻止鼠标向上事件的发生可能会出现意想不到的进一步问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-09
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      相关资源
      最近更新 更多