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

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

wndproc里同样无法截获右键按下的事件


代码思路:注册鼠标钩子,在钩子的鼠标右击时回调函数里调用事件,事件里判断当前鼠标所在位置窗口的父窗口句柄是否等于当前窗体句柄,是的话把右键菜单控件show出来

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

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

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

namespace CSharpmouseHook
{
    ///   <summary>
    ///   这个类可以让你得到一个在运行中程序的所有鼠标事件
    ///   并且引发一个带MouseEventArgs参数的.NET鼠标事件以便你很容易使用这些信息
    ///   </summary>
    public class MouseHook
    {
        //全局的事件
        public event MouseEventHandler OnMouseActivity;//触发时被执行的
        ;   //鼠标钩子句柄
        //鼠标常量
        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()
        {
            //安装鼠标钩子
            )
            {
                //生成一个HookProc的实例.
                MouseHookProcedure = new HookProc(MouseHookProc);//委托,c++中的函数指针
                hMouseHook = SetWindowsHookEx(, MouseHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[]), );//14为监控全局鼠标行为

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

                    string lpBuffer = new string(' ', sLen);

                    , lpBuffer, sLen, IntPtr.Zero);
                    Stop();
                    throw new Exception("SetWindowsHookEx failed." + lpBuffer);
                }
            }
        }
        #endregion

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

            //如果卸下钩子失败
            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)
        {
            //如果正常运行并且用户要监听鼠标的消息
            ) && (OnMouseActivity != null))
            {
                MouseButtons button = MouseButtons.None;
                ;
                if(wParam== 0x204)//右键按下时
                {
                        button = MouseButtons.Right;//转成C#行为
                        clickCount = ;//鼠标单击次数
                        MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));//鼠标的信息
                        MouseEventArgs e = );//装封鼠标信息以传入回调函数

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

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

using CSharpmouseHook;
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 子父窗体的建成
{
    public partial class Form1 : Form
    {

        [DllImport("user32")]
        public static extern IntPtr WindowFromPoint(Point p);
        [DllImport("user32")]
        public static extern IntPtr GetParent(IntPtr i);

        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)
        {
            if (GetParent(WindowFromPoint(e.Location)) == this.Handle)
            {
                this.contextMenuStrip1.Show(Control.MousePosition);
            }
        }

        //右键菜单触发的事件
        private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("窗口右击!!");

        }
    }
}

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

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

C#父窗体右击事件实现的更多相关文章

  1. Extjs 窗体居中,双重窗体弹出时清除父窗体的鼠标事件

    这个是监控窗体缩放的事件 缩放中居中主要在 'beforeshow' 和 'destroy'两个事件里面监控 var EditTempWindow; Ext.EventManager.onWindow ...

  2. WPF 子窗体关闭,刷新父窗体

    父窗体代码 private void DGUserEdit() { if(DGUser.SelectedItem!=null) { DataRow dr = (DGUser.SelectedItem ...

  3. WPF 子窗体关闭时显示父窗体

    这个问题纠结了两天,今天在一个朋友的帮助下,解决了,其实很简单,但是可能作为新手,接触WPF时间还是短,因此作为一个问题困扰了我. 父窗体部分代码 private void EditInformati ...

  4. winform打开子窗体后,在子窗体中刷新父窗体,或者关闭子窗体刷新父窗体

    winform打开子窗体后,在子窗体中刷新父窗体,或者关闭子窗体刷新父窗体,搜集了几个方法,列举如下: 一 . 所有权法 父窗体,名称为“fuForm”,在父窗体中有个公共刷新方法,也就是窗体数据初始 ...

  5. WinFrom子窗体向父窗体传值

    父窗框mainForm;子窗体childForm,利用事件进行传值 在子窗体中的操作: public event EventHandler accept;public string value; pr ...

  6. WPF用ShowDialog()弹出窗体时控制该窗体的显示位置,并传值回父窗体

    原文:http://blog.csdn.net/kiss0622/article/details/5852153 方法一: 1.父窗口代码 Window1.xaml.cs private void B ...

  7. Winform中如何实现父窗体传递数据到子窗体并刷新子窗体

    原理:利用委托和事件,本文将以图文并茂的例子讲述,告诉我们So Easy --------------------------------------------------------------- ...

  8. Winform中如何实现子窗体刷新父窗体

    原理:利用委托和事件,本文将以图文并茂的例子讲述,告诉我们So Easy --------------------------------------------------------------- ...

  9. asp.net 父窗体获取子窗体的返回值,可用来对父窗体局部更新

    今天在项目上遇到了这个问题,其实只是window.returnValue的简单应用,不是asp.net的专属内容.作为积累,记录一个简单的实现模型. 图1  用到的文件 从图1中我们可以看到,只用到了 ...

随机推荐

  1. 06 redis中set结构及命令详解

    集合 set 相关命令 集合的性质: 唯一性,无序性,确定性 注: 在string和link的命令中,可以通过range 来访问string中的某几个字符或某几个元素 但,因为集合的无序性,无法通过下 ...

  2. Oracle学习第三篇—多行函数

    0 order by asc/desc 默认升序 order by 列的名字|表达式|别名|序号 把空放在后边:order by desc nulls last 1分组函数--会自动滤空值 count ...

  3. hive job oom问题

    错误信息例如以下:Container [pid=26845,containerID=container_1419056923480_0212_02_000001] is running beyond ...

  4. 【BZOJ3544】[ONTAK2010]Creative Accounting 前缀和+set

    [BZOJ3544][ONTAK2010]Creative Accounting Description 给定一个长度为N的数组a和M,求一个区间[l,r],使得(\sum_{i=l}^{r}{a_i ...

  5. EasyNVR H5无插件摄像机直播解决方案前端解析之:如何在播放界面添加实时云台控制界面

    如何在播放器上加一个云台控制界面 问题: 对于实时直播的视频播放, 由于播放页面客观样式要求(一个播放器占据了整个页面),因此很难找出很合理的空间来放置其他功能按钮的位置(比如配合实时是平的云台控制界 ...

  6. 如何解决安装好的google浏览器打不开网页的问题?

    1.Google浏览器右上角,三个点,点击一下, 2.点击设置 3.在"搜索引擎"这一栏,选择'管理搜索引擎',右边的倒三角,进入选择界面 4.在其他搜索引擎中选择"百度 ...

  7. Swift 学习笔记 (函数)

    函数 函数是一个独立的代码块,用来执行特定的任务.Swift中的函数与Object-C中的函数一样,但是声明与书写的方式不太一样,现在我们就通过几个例子介绍一下Swift中的函数.简单的来说,他与JS ...

  8. Django框架打印orm转换过程中的sql_模型层

    LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBU ...

  9. Hadoop-2.2.0中文文档—— MapReduce 下一代--容量调度器

    目的 这份文档描写叙述 CapacityScheduler,一个为Hadoop能同意多用户安全地共享一个大集群的插件式调度器,如他们的应用能适时被分配限制的容量. 概述 CapacitySchedul ...

  10. ERR:/usr/local/lib/libcrypto.so.1.0.0: no version information available

    解决方法: locate libssl.so.1.0.0   sudo rm /usr/local/lib/libssl.so.1.0.0   sudo ln -s /lib/x86_64-linux ...