标签:
之前在博问上提问过,没人回答啊,豆太少没人权?
没注册钩子的话根本没办法弹出右键菜单啊,因为在父窗体内有一个容器,所以鼠标在右击时是无法触发窗体的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
要装载请注明链接!!!!!!
标签:
原文地址:http://www.cnblogs.com/magicianlyx/p/4922261.html