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中我们可以看到,只用到了 ...
随机推荐
- Python 时间格式化(转)
From:http://www.cnblogs.com/65702708/archive/2011/04/17/2018936.html http://www.wklken.me/posts/2015 ...
- 多媒体开发之---live555 分析客户端
live555的客服端流程:建立任务计划对象--建立环境对象--处理用户输入的参数(RTSP地址)--创建RTSPClient实例--发出DESCRIBE--发出SETUP--发出PLAY--进入Lo ...
- Android API Guides---Storage Access Framework
存储訪问架构 Android 4.4系统(API级别19)推出存储訪问框架(SAF).新加坡武装部队变得很easy,为用户在其全部自己喜欢的文件存储提供商的浏览和打开文档,图像和其它文件.一个标准的, ...
- Android OOM解决方案 :
清单文件里 给Application标签加上android:largeHeap="true"这行代码 这样会给你的app分配一个大内存 如果某个页面在绘制时会耗非常多的内存 ...
- 九度OJ 1054:字符串内排序 (排序)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:7949 解决:4343 题目描述: 输入一个字符串,长度小于等于200,然后将输出按字符顺序升序排序后的字符串. 输入: 测试数据有多组,输 ...
- 如何获取 Greenplum 中用户最后登录时间和登录频率
这几天搞系统迁移,老板突然想知道给客户开的那么多用户当中,哪些还在用,哪些已经不用了.我们的数据库是 Greenplum,而且还是一直没有升级的老版本,Google 了一下没有发现特别好的查看用户登录 ...
- Linux就该这么学--Shell脚本条件语句(一)
1.条件测试语句能够让Shell脚本根据实际工作灵活调整工作内容,例如判断系统的状态后执行指定的工作,或创建指定数量的用户,批量修改用户密码,这些都可以让Shell脚本通过条件测试语句完成. if条件 ...
- spring-data-redis RedisTemplate操作
使用RedisTemplate来对对象.String等做缓存处理 首先定义一个对象并重写toString方法 public class UserInfo implements Serializable ...
- GEO(地理信息定位)
核心知识点: 1.GEO是利用zset来存储地理位置信息,可以用来计算地理位置之间的距离,也可以做统计: 2.命令:geoadd geopos geodist geohash georadius/ge ...
- Quartz Job scheduling 基础实现代码
Quartz 集成在 SpringBoot 中分为 config.task.utils.controller 和 MVC 的三层即 controller.service.dao 和 entity. c ...