我们正在使用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。
答案 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);
}
警告:防止发生鼠标事件可能会发生意外的进一步问题。