C#父窗体右击事件实现
之前在博问上提问过,没人回答啊,豆太少没人权?
没注册钩子的话根本没办法弹出右键菜单啊,因为在父窗体内有一个容器,所以鼠标在右击时是无法触发窗体的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#父窗体右击事件实现的更多相关文章
- Extjs 窗体居中,双重窗体弹出时清除父窗体的鼠标事件
这个是监控窗体缩放的事件 缩放中居中主要在 'beforeshow' 和 'destroy'两个事件里面监控 var EditTempWindow; Ext.EventManager.onWindow ...
- WPF 子窗体关闭,刷新父窗体
父窗体代码 private void DGUserEdit() { if(DGUser.SelectedItem!=null) { DataRow dr = (DGUser.SelectedItem ...
- WPF 子窗体关闭时显示父窗体
这个问题纠结了两天,今天在一个朋友的帮助下,解决了,其实很简单,但是可能作为新手,接触WPF时间还是短,因此作为一个问题困扰了我. 父窗体部分代码 private void EditInformati ...
- winform打开子窗体后,在子窗体中刷新父窗体,或者关闭子窗体刷新父窗体
winform打开子窗体后,在子窗体中刷新父窗体,或者关闭子窗体刷新父窗体,搜集了几个方法,列举如下: 一 . 所有权法 父窗体,名称为“fuForm”,在父窗体中有个公共刷新方法,也就是窗体数据初始 ...
- WinFrom子窗体向父窗体传值
父窗框mainForm;子窗体childForm,利用事件进行传值 在子窗体中的操作: public event EventHandler accept;public string value; pr ...
- WPF用ShowDialog()弹出窗体时控制该窗体的显示位置,并传值回父窗体
原文:http://blog.csdn.net/kiss0622/article/details/5852153 方法一: 1.父窗口代码 Window1.xaml.cs private void B ...
- Winform中如何实现父窗体传递数据到子窗体并刷新子窗体
原理:利用委托和事件,本文将以图文并茂的例子讲述,告诉我们So Easy --------------------------------------------------------------- ...
- Winform中如何实现子窗体刷新父窗体
原理:利用委托和事件,本文将以图文并茂的例子讲述,告诉我们So Easy --------------------------------------------------------------- ...
- asp.net 父窗体获取子窗体的返回值,可用来对父窗体局部更新
今天在项目上遇到了这个问题,其实只是window.returnValue的简单应用,不是asp.net的专属内容.作为积累,记录一个简单的实现模型. 图1 用到的文件 从图1中我们可以看到,只用到了 ...
随机推荐
- c++ 通过数据流方式实现文件拷贝
#include "stdafx.h"#include <iostream>#include<fstream>using namespace std;voi ...
- 动态内存分配(Dynamic memory allocation)
下面的代码片段的输出是什么?为什么? 解析:这是一道动态内存分配(Dynamic memory allocation)题. 尽管不像非嵌入式计算那么常见,嵌入式系统还是有从堆(heap)中动态分 ...
- 1194: [HNOI2006]潘多拉的盒子
1194: [HNOI2006]潘多拉的盒子 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 464 Solved: 221[Submit][Stat ...
- maven工作的过程
1 建立各个module之间的依赖关系 2 越底层的依赖的module先生成 3 下载远程库中的依赖 4 先生成本地被依赖的module 问题是,如何保证本次module和远程库中的包不重名?
- 3行代码 多元线性方程组 rank=4 多元-一元 降元
对于线性方程组Ax=b 对A和b执行同样的一串行初等运算, 那么该方程组的解集不发生变化. [未知-已知 高阶--低阶] http://mathworld.wolfram.com/CramersR ...
- 【24题】P2766最长不下降子序列问题
网络流二十四题 网络流是个好东西,希望我也会. 网络流?\(orz\ zsy!!!!!\) P2766 最长不下降子序列问题 考虑我们是如何\(dp\)这个\(LIS\)的. 我们是倒着推,设置\(d ...
- 【题解】 CF11D A Simple Task
[题解] CF11D A Simple Task 传送门 \(n \le 20\) 考虑状态压缩\(dp\). 考虑状态,\(dp(i,j,O)\)表示从\(i\)到\(j\)经过点集\(O\)的路径 ...
- 题解 P1095 【守望者的逃离】
贪心.数组都不用开那种. 考虑跑步距离的构成.发现跑步只有三种情况构成 休息 传送 朴素地跑 显然,如果可以传送,我们就不要朴素地跑步.因为\(17\le 60 \div 2 =30\). 假如我们知 ...
- CF(439E - Devu and Birthday Celebration)莫比乌斯容斥
题意:将n个糖果插入f-1个挡板分成f分(a1,a2,a3...af). 问有多少种分法能够使得gcd(a1,a2,a3...af)=1; 解法.莫比乌斯容斥,首先按1为单位分,这时候有C(n-1,f ...
- Ubuntu/CentOS下使用脚本自动安装 Docker
Ubuntu.Debian 系列安装 Docker 系统要求 Docker 支持以下版本的 Ubuntu 和 Debian 操作系统: Ubuntu Xenial 16.04 (LTS) Ubuntu ...