コード例 #1
0
        /// <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));
        }
コード例 #2
0
        /// <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));
        }
コード例 #3
0
 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);
 }
コード例 #4
0
        /// <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);
        }