/// <summary> /// Function to process the messages through the installed message filters. /// </summary> /// <param name="hwnd">Window handle receiving the message.</param> /// <param name="msg">Message being received.</param> /// <param name="wParam">Window parameter 1.</param> /// <param name="lParam">Window parameter 2.</param> /// <returns>The result of a call to the previous window procedure if the message was not processed, or <see cref="IntPtr.Zero"/> if the message was processed.</returns> private IntPtr NewWndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam) { if (!_hooked) { UninstallWindowProcedure(); return(UserApi.CallWindowProc(_defaultWndProc, hwnd, msg, wParam, lParam)); } var windowMessage = new Message { HWnd = hwnd, Msg = msg, WParam = wParam, LParam = lParam }; // Send a copy of the message to any installed filters. // ReSharper disable once LoopCanBeConvertedToQuery // ReSharper disable once ForCanBeConvertedToForeach for (int i = 0; i < _messageFilters.Count; i++) { // ReSharper disable once InconsistentlySynchronizedField IMessageFilter filter = _messageFilters[i]; if (filter.PreFilterMessage(ref windowMessage)) { return(windowMessage.Result); } } return(UserApi.CallWindowProc(_defaultWndProc, hwnd, msg, wParam, lParam)); }
/// <summary>Hook callback to process <see cref="WM.WM_MOUSEMOVE" /> messages to move the thumbnail along with the cursor.</summary> /// <param name="nCode">The message being received.</param> /// <param name="wParam">Additional information about the message.</param> /// <param name="lParam">Additional information about the message.</param> /// <returns>A zero value if the procedure processes the message; a nonzero value if the procedure ignores the message.</returns> protected IntPtr MouseHookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0) { switch ((WM)wParam) { case WM.WM_MOUSEMOVE: MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT)); Point cursorPosition = new Point(hookStruct.pt.x, hookStruct.pt.y); SetWindowPosition(cursorPosition); { var msg = new Message() { HWnd = Handle, LParam = lParam, WParam = wParam, Msg = (int)WM.WM_MOUSEMOVE, }; Invoke(new Action(() => m_messageFilter.PreFilterMessage(ref msg))); } break; case WM.WM_LBUTTONUP: { var msg = new Message() { HWnd = Handle, LParam = lParam, WParam = wParam, Msg = (int)WM.WM_LBUTTONUP, }; Invoke(new Action(() => m_messageFilter.PreFilterMessage(ref msg))); } break; default: break; } } return(User32.CallNextHookEx(m_hookId, nCode, wParam, lParam)); }
public static bool FilterMessage(ref Message message) { lock (message_filters) { for (int i = 0; i < message_filters.Count; i++) { IMessageFilter filter = (IMessageFilter)message_filters[i]; if (filter.PreFilterMessage(ref message)) { return(true); } } } return(false); }
/// <summary> /// 本函数实现 System.Windows.Forms.IMessageFilter接口的PreFilterMessage函数,用于对当前应用程序的消息进行预处理 /// </summary> /// <remarks>本过滤器处理了鼠标按钮按下时间和键盘事件以及鼠标滚轮事件, /// 若鼠标在本列表边框外部按下则表示认为用户想要关闭列表,此时立即关闭本列表窗体 /// 此外本函数还处理汉语拼音辅助定位列表元素 /// 用户可用上下光标键或者上下翻页键来滚动列表,用空格或回车来进行选择</remarks> /// <param name="m">当前消息队列中的消息对象</param> /// <returns>true 当前消息其他程序不可处理(本消息被吃掉了) false本消息还可被其他程序处理</returns> public virtual bool PreFilterMessage(ref System.Windows.Forms.Message m) { bool eatMessage = false; if (this.IsDisposed || this.Disposing || this.Visible == false) { // 若对象被销毁了或列表不显示则删除本消息过滤器 System.Windows.Forms.Application.RemoveMessageFilter(this); return(false); } Win32Message msg = new Win32Message(m); // 获得窗体的绝对位置和大小 System.Drawing.Rectangle BoundsRect = this.Bounds; // 鼠标在客户区的按键按下消息 // Mouse was pressed in a window of this application if (msg.IsMouseDownMessage) { if (msg.Msg == (int)Msgs.WM_LBUTTONDOWN || msg.Msg == (int)Msgs.WM_MBUTTONDOWN || msg.Msg == (int)Msgs.WM_RBUTTONDOWN || msg.Msg == (int)Msgs.WM_XBUTTONDOWN) { System.Drawing.Point mousePos = msg.ScreenMousePosition; bolExitLoop = !BoundsRect.Contains(mousePos); msgBack = m; eatMessage = bolExitLoop; if (bolExitLoop) { if (IsChildWindow(m.HWnd)) { bolExitLoop = false; } WindowInformation info = new WindowInformation(this.Handle); if (info.Enabled == false) { // 窗体不可用,很可能正在显示对话框使得本窗体暂时不可用 bolExitLoop = false; } //else //{ // this.UserProcessState = WinForms.UserProcessState.Accept; //} return(true); } } } // 鼠标在非客户区的按键按下消息 // Mouse was pressed in a window of this application if ((m.Msg == (int)Msgs.WM_NCLBUTTONDOWN) || (m.Msg == (int)Msgs.WM_NCMBUTTONDOWN) || (m.Msg == (int)Msgs.WM_NCRBUTTONDOWN) || (m.Msg == (int)Msgs.WM_NCXBUTTONDOWN)) { System.Drawing.Point mousePos = msg.MousePosition; bolExitLoop = !BoundsRect.Contains(mousePos); //eatMessage = true; msgBack = m; eatMessage = bolExitLoop; if (bolExitLoop) { if (IsChildWindow(m.HWnd)) { bolExitLoop = false; } WindowInformation info = new WindowInformation(this.Handle); if (info.Enabled == false) { // 窗体不可用,很可能正在显示对话框使得本窗体暂时不可用 bolExitLoop = false; } //else //{ // this.UserProcessState = WinForms.UserProcessState.Accept; //} return(true); } } if (this.RuntimeContentControl is IMessageFilter) { WindowInformation info = new WindowInformation(this.Handle); //if (info.Enabled) { IMessageFilter mf = (IMessageFilter)this.RuntimeContentControl; return(mf.PreFilterMessage(ref m)); } } return(eatMessage); }