码迷,mamicode.com
首页 > Windows程序 > 详细

C#父窗体右击事件实现

时间:2015-10-30 02:01:35      阅读:343      评论:0      收藏:0      [点我收藏+]

标签:

之前在博问上提问过,没人回答啊,豆太少没人权?

 

没注册钩子的话根本没办法弹出右键菜单啊,因为在父窗体内有一个容器,所以鼠标在右击时是无法触发窗体的mousedown事件的,即使把KeyPreview设置为true也一样无法触发

 

技术分享

 

 


 

 

代码思路:注册鼠标钩子,在钩子的鼠标右击时回调函数里调用事件,事件里判断当前鼠标位置是否在当前窗口的工作区域内,是的话把右键菜单控件show出来

 

 

——————————————————————

把api中钩子注册与卸载的函数重新在C#中装封一次

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace CSharp全局鼠标键盘Hook
{
    ///   <summary> 
    ///   这个类可以让你得到一个在运行中程序的所有鼠标事件 
    ///   并且引发一个带MouseEventArgs参数的.NET鼠标事件以便你很容易使用这些信息 
    ///   </summary> 
    public class MouseHook
    {
        //全局的事件 
        public event MouseEventHandler OnMouseActivity;//触发时被执行的
        static int hMouseHook = 0;   //鼠标钩子句柄 
        //鼠标常量 
        HookProc MouseHookProcedure;   //声明鼠标钩子事件类型.

        //声明一个Point的封送类型 
        [StructLayout(LayoutKind.Sequential)]
        public class POINT
        {
            public int x;
            public int y;
        }

        //声明鼠标钩子的封送结构类型 
        [StructLayout(LayoutKind.Sequential)]
        public class MouseHookStruct
        {
            public POINT pt;
            public int hWnd;
            public int wHitTestCode;
            public int dwExtraInfo;
        }
      
        #region  //……………… 引入api
        //装置钩子的函数 
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
        //卸下钩子的函数 
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);

        //下一个钩挂的函数 
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        static public extern int FormatMessage(
        uint dwFlags,
        IntPtr lpSource,
        int dwMessageId,
        int dwLanguageZId,
        string lpBuffer,
        int nSize,
        IntPtr Arguments);

        #endregion
        public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
      


        //析构函数. 
        ~MouseHook()
        {
            Stop();
        }



        #region//………………注册鼠标钩子
        public void Start()
        {
            //安装鼠标钩子 
            if (hMouseHook == 0)
            {
                //生成一个HookProc的实例. 
                MouseHookProcedure = new HookProc(MouseHookProc);//委托,c++中的函数指针
                hMouseHook = SetWindowsHookEx(14, MouseHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);//14为监控全局鼠标行为

               
                //如果装置失败停止钩子 
                if (hMouseHook == 0)
                {
                    int errNum = Marshal.GetLastWin32Error();
                    //函数内调用
                    int sLen = 0x100;
                    uint dwFlags = 0x1000 | 0x200;

                    string lpBuffer = new string( , sLen);

                    int count = FormatMessage(dwFlags, IntPtr.Zero, errNum, 0, lpBuffer, sLen, IntPtr.Zero);
                    Stop();
                    throw new Exception("SetWindowsHookEx failed." + lpBuffer);
                }
            }
        }
        #endregion

        #region//………………卸载鼠标钩子
        public void Stop()
        {
            bool retMouse = true;
            if (hMouseHook != 0)
            {
                retMouse = UnhookWindowsHookEx(hMouseHook);
                hMouseHook = 0;
            }

            //如果卸下钩子失败 
            if (!(retMouse)) throw new Exception("UnhookWindowsHookEx   failed. ");
        }


        #endregion


        #region//………………鼠标有行为时触发
        /// <summary>
        /// 有鼠标行为时执行回调方法(函数)
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
        {
            //如果正常运行并且用户要监听鼠标的消息 
            if ((nCode >= 0) && (OnMouseActivity != null))
            {
                MouseButtons button = MouseButtons.None;
                int clickCount = 0;
                if(wParam== 0x204)//右键按下时
                {
                        button = MouseButtons.Right;//转成C#行为
                        clickCount = 1;//鼠标单击次数
                        MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));//鼠标的信息
                        MouseEventArgs e = new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0);//装封鼠标信息以传入回调函数

                        OnMouseActivity(this, e);
                }
                //从回调函数中得到鼠标的信息 
            }
            return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
        }
        #endregion
    }
}

 

 

 

在窗口中注册事件和写事件触发时执行的代码

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace CSharp全局鼠标键盘Hook
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        public static extern IntPtr WindowFormPoint(Point p);

        MouseHook mouseHook;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                //安装鼠标钩子
                mouseHook = new MouseHook();
                mouseHook.OnMouseActivity += new MouseEventHandler(mouseHook_OnMouseActivity);
                mouseHook.Start();
            }
            catch (System.Exception ex)
            {
                Application.DoEvents();
            }
            
        }

        //鼠标事件处理程序
        void mouseHook_OnMouseActivity(object sender, MouseEventArgs e)
        {
            Rectangle rectangle = this.ClientRectangle;
            if (rectangle.Contains(PointToClient( MousePosition)))
            {
                this.contextMenuStrip1.Show(Control.MousePosition);
            }
        }

        //右键菜单触发的事件
        private void 新建ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form2 f = new Form2();
            f.Location =PointToClient( Control.MousePosition);
            f.MdiParent = this;
            f.Show();
        }
    }
}

 

 


 

 

示例代码链接:http://pan.baidu.com/s/1qW1kBus

 

 

要装载请注明链接!!!!!!

C#父窗体右击事件实现

标签:

原文地址:http://www.cnblogs.com/magicianlyx/p/4922261.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!