將鼠標消息發送給指定的父控件_勾子

以下類通過掛載勾子原理,實現將子控件鼠標消息發送給父控件。

 

調用:

MousePreview mp=new MousePreview(pControl);  //pControl爲父控件

//啓用勾子

mp.EnableHook();

 

//禁用勾子

mp.DisableHook();

 

 

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.InteropServices;

using System.Drawing;

using System.Windows.Forms;

 

 

    public class MousePreview

    {

        /// <summary>

        /// Hook管理器

        /// </summary>

        GCHandle mGC;

 

        [DllImport("kernel32")]

        public static extern int GetCurrentThreadId();

 

        /// <summary>

        /// 掛載勾子

        /// </summary>

        /// <param name="idHook"></param>

        /// <param name="lpfn"></param>

        /// <param name="hmod"></param>

        /// <param name="dwThreadId"></param>

        /// <returns></returns>

        [DllImport("user32", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]

        public static extern IntPtr  SetWindowsHookEx(int idHook, HOOKPROC lpfn, int hmod, int dwThreadId);

 

        /// <summary>

        /// 卸載勾子

        /// </summary>

        /// <param name="hhook"></param>

        /// <returns></returns>

        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]

        public static extern bool UnhookWindowsHookEx(IntPtr hhook);

 

        /// <summary>

        /// 發送消息

        /// </summary>

        /// <param name="hwnd"></param>

        /// <param name="wMsg"></param>

        /// <param name="wParam"></param>

        /// <param name="lParam"></param>

        /// <returns></returns>

        [DllImport("user32.dll", EntryPoint = "SendMessage")]

        public static extern IntPtr  SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);

 

        public delegate int HOOKPROC(int nCode, int wParam, int lParam);

 

        private Control mControl;

        private IntPtr mHook=IntPtr.Zero;

        /// <summary>

        /// 構造

        /// </summary>

        /// <param name="pControl"></param>

        public MousePreview(Control pControl)

        {

            mControl = pControl;

        }

 

        /// <summary>

        /// 啓用掛勾子

        /// </summary>

        public void EnableHook()

        {

            if (mHook == IntPtr.Zero)

            {

                HOOKPROC proc = new HOOKPROC(MyMouseProc);

                mGC=GCHandle .Alloc(proc);

                mHook = SetWindowsHookEx(7, proc, 0, GetCurrentThreadId());

            }

        }

 

        /// <summary>

        ///

        /// </summary>

        public void DisableHook()

        {

            if (mHook != IntPtr.Zero)

            {

                UnhookWindowsHookEx(mHook);

                mGC.Free();                

            }

            mHook = IntPtr.Zero;

        }

 

        /// <summary>

        /// 處理消息事件

        /// </summary>

        /// <param name="nCode"></param>

        /// <param name="wParam"></param>

        /// <param name="lParam"></param>

        /// <returns></returns>

        private  int MyMouseProc(int nCode, int wParam, int lParam)

        {

            if (nCode == 0)

            {

                GC.Collect();

                GC.WaitForPendingFinalizers();

                GC.Collect();

 

                Rectangle _Rect = mControl.RectangleToScreen(mControl.ClientRectangle);

                if (!_Rect.Contains(Cursor.Position)) return 0;

 

                short _X = (short)(Cursor.Position.X - _Rect.X);

                short _Y = (short)(Cursor.Position.Y - _Rect.Y);

 

                int _Point = _Y << 16;

                _Point += _X;

               

                switch (wParam)

                {

                    case 0x200: //移動鼠標

                    case 0x201:  //按下左鍵

                    case 0x202:  //釋放左鍵

                    case 0x203:  //雙擊左鍵

                    case 0x204:  //按下右鍵

                    case 0x205:  //釋放右鍵

                    case 0x206:  //雙擊右鍵

                    case 0x207:  //按下中鍵

                    case 0x208:  //釋放中鍵

                    case 0x209:   //雙擊中鍵

                        SendMessage(mControl.Handle, wParam, wParam, _Point);

                        break;

                        /*

                    case 512:

                        SendMessage(mControl.Handle, 512, wParam, _Point);

                        break;

                    case 513:

                        SendMessage(mControl.Handle, 513, wParam, _Point);

                        break;

                    case 514:

                        SendMessage(mControl.Handle, 514, wParam, _Point);

                        break;

                    case 516:

                        SendMessage(mControl.Handle, 516, wParam, _Point);

                        break;

                    case 517:

                        SendMessage(mControl.Handle, 517, wParam, _Point);

                        break;

                         */

                    default:

                        break;

                }

            }

            return 0;

        }

 

    }

 

 

 

 

發佈了58 篇原創文章 · 獲贊 4 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章