c# winform 窗体失去焦点关闭(钩子实现)
先来一个辅助类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms; namespace HZCX.Utils
{
/// <summary>
/// 鼠标全局钩子
/// </summary>
public static class MouseHook
{
private const int WM_MOUSEMOVE = 0x200;
private const int WM_LBUTTONDOWN = 0x201;
private const int WM_RBUTTONDOWN = 0x204;
private const int WM_MBUTTONDOWN = 0x207;
private const int WM_LBUTTONUP = 0x202;
private const int WM_RBUTTONUP = 0x205;
private const int WM_MBUTTONUP = 0x208;
private const int WM_LBUTTONDBLCLK = 0x203;
private const int WM_RBUTTONDBLCLK = 0x206;
private const int WM_MBUTTONDBLCLK = 0x209; /// <summary>
/// 点
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public class POINT
{
public int x;
public int y;
} /// <summary>
/// 钩子结构体
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct
{
public POINT pt;
public int hWnd;
public int wHitTestCode;
public int dwExtraInfo;
} public const int WH_MOUSE_LL = ; // mouse hook constant // 装置钩子的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); // 卸下钩子的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook); // 下一个钩挂的函数
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam); // 全局的鼠标事件
public static event MouseEventHandler OnMouseActivity; // 钩子回调函数
public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); // 声明鼠标钩子事件类型
private static HookProc _mouseHookProcedure;
private static int _hMouseHook = ; // 鼠标钩子句柄
/// <summary>
/// 启动全局钩子
/// </summary>
public static void Start()
{
// 安装鼠标钩子
if (_hMouseHook != )
{
Stop();
}
// 生成一个HookProc的实例.
_mouseHookProcedure = new HookProc(MouseHookProc); _hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, _mouseHookProcedure, Marshal.GetHINSTANCE(System.Reflection.Assembly.GetEntryAssembly().GetModules()[]), ); //假设装置失败停止钩子
if (_hMouseHook == )
{
Stop();
throw new Exception("SetWindowsHookEx failed.");
}
} /// <summary>
/// 停止全局钩子
/// </summary>
public static void Stop()
{
bool retMouse = true; if (_hMouseHook != )
{
retMouse = UnhookWindowsHookEx(_hMouseHook);
_hMouseHook = ;
} // 假设卸下钩子失败
if (!(retMouse))
throw new Exception("UnhookWindowsHookEx failed.");
} /// <summary>
/// 鼠标钩子回调函数
/// </summary>
private static int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
// 假设正常执行而且用户要监听鼠标的消息
if ((nCode >= ) && (OnMouseActivity != null))
{
MouseButtons button = MouseButtons.None;
int clickCount = ; switch (wParam)
{
case WM_LBUTTONDOWN:
button = MouseButtons.Left;
clickCount = ;
break;
case WM_LBUTTONUP:
button = MouseButtons.Left;
clickCount = ;
break;
case WM_LBUTTONDBLCLK:
button = MouseButtons.Left;
clickCount = ;
break;
case WM_RBUTTONDOWN:
button = MouseButtons.Right;
clickCount = ;
break;
case WM_RBUTTONUP:
button = MouseButtons.Right;
clickCount = ;
break;
case WM_RBUTTONDBLCLK:
button = MouseButtons.Right;
clickCount = ;
break;
}
if (button != MouseButtons.None && clickCount>)
{
// 从回调函数中得到鼠标的信息
MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
MouseEventArgs e = new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, );
OnMouseActivity(null, e);
}
} // 启动下一次钩子
int inext = CallNextHookEx(_hMouseHook, nCode, wParam, lParam);
return inext;
}
}
}
Program的main函数里面调用 MouseHook.Start();
main函数里面写 Application.ApplicationExit += Application_ApplicationExit;
static void Application_ApplicationExit(object sender, EventArgs e)
{
MouseHook.Stop();
}
窗体load里面写 HZCX.Utils.MouseHook.OnMouseActivity += hook_OnMouseActivity;
窗体closing里面写 HZCX.Utils.MouseHook.OnMouseActivity -= hook_OnMouseActivity;
void hook_OnMouseActivity(object sender, MouseEventArgs e)
{
try
{
if (this._isLoseFocusClose && e.Clicks > )
{
if (e.Button == System.Windows.Forms.MouseButtons.Left || e.Button == System.Windows.Forms.MouseButtons.Right)
{
if (!this.IsDisposed)
{
if (!this.ClientRectangle.Contains(this.PointToClient(e.Location)))
{
base.Close();
}
}
}
}
}
catch { }
}
就这样了
c# winform 窗体失去焦点关闭(钩子实现)的更多相关文章
- Winform 窗体获得焦点
给窗体添加Shown事件 public void Form_Shown(object sender, EventArgs e) { this.Activate(); this.Focus(); //定 ...
- winform打开子窗体后,在子窗体中刷新父窗体,或者关闭子窗体刷新父窗体
winform打开子窗体后,在子窗体中刷新父窗体,或者关闭子窗体刷新父窗体,搜集了几个方法,列举如下: 一 . 所有权法 父窗体,名称为“fuForm”,在父窗体中有个公共刷新方法,也就是窗体数据初始 ...
- Winform开发之窗体显示、关闭与资源释放
Winform的窗体涉及到一般窗体(单文档窗体).MDI窗体.窗体之间的关系等,那么如果调用打开新窗体.如何关闭窗体.窗体资源的释放等都关系到软件运行的效率,本文一一介绍 1.窗体的显示 从一个窗体打 ...
- Winform 窗体的操作
原文:http://www.cnblogs.com/Billy-rao/archive/2012/05/16/2503437.html 怎样能使winform窗体的大小固定住,不能调整其大小 窗体Fo ...
- WinForm窗体嵌入
一.在winform窗体上添加两个控件 1.容器>Panel 2.添加 SideBar.dll (下载链接:http://pan.baidu.com/s/1o6qhf9w) (1)将SideBa ...
- C#中WinForm窗体事件的执行次序
C#中WinForm窗体事件的执行次序如下: 当 Windows Form 应用程序启动时,会以下列顺序引发主要表单的启动事件: System.Windows.Forms.Control ...
- C# winform窗体设计-通过条件查询数据
在winform 数据库设计中,有时候需要通过条件查询对应的数据,并且将数据显示在文本框(or 富文本框)中,下面,小编将讲述通过一个条件: 首先,我们需要对数据库建立连接,并且执行数据库命令,在此之 ...
- Winform窗体事件发生顺序
Form 和Control 类公开了一组与应用程序启动和关闭相关联的事件.当Windows 窗体应用程序启动时,主窗体的启动事件按以下顺序引发: System.Windows.Forms.Contro ...
- 小例子(二)、winform窗体间的关系
写一个关于winform窗体间的关系 1.登陆,思路:登陆后隐藏登陆窗体,关闭Form2时结束整个应用程序. //登陆窗体 private void button2_Click(object send ...
随机推荐
- Codeforces Round #607 (Div. 1)
A. Cut and Paste 题解 在计算答案的时候,我们发现只需要知道这个字符串前\(l\) 个具体是啥就行了.所以对于每一组询问,我们暴力把这个字符串前\(l\) 的位都算出来,然后剩下的就推 ...
- 《Netty Redis Zookeeper 高并发实战》声明
疯狂创客圈 Java 高并发[ 亿级流量聊天室实战]实战系列 [博客园总入口 ] 这里, 对疯狂创客圈 <Netty Redis Zookeeper 高并发实战> 一书,进行一些必要说明. ...
- Spring Cloud Alibaba 实战(十一) - Spring Cloud认证授权
欢迎关注全是干货的技术公众号:JavaEdge 本文主要内容: 如何实现用户认证与授权? 实现的三种方案,全部是通过画图的方式讲解.以及三种方案的对比 最后根据方案改造Gateway和扩展Feign ...
- VSCode 使用 ESLint + Prettier 来统一 JS 代码
环境: VSCode 1.33.1 Node.js 8.9.1 一.ESLint 1.介绍 ESLint是最流行的JavaScript Linter. Linter 是检查代码风格/错误的小工具.其他 ...
- 2019年全国高校计算机能力挑战赛初赛C语言解答
http://www.ncccu.org.cn 2019年全国高校计算机能力挑战赛分设大数据算法赛,人工智能算法赛,Office高级应用赛,程序设计赛4大赛项 C语言初赛解答 1:编程1 16.现有一 ...
- spring的简易实现(一)
[练习]spring的简易实现(一) 在第一部分我们实现读取xml的配置,然后实例化xml中的bean 首先定义一个xml和相关的class类 <?xml version="1.0&q ...
- 利用socket传递图片
package com.company.s3; import java.io.File; import java.io.FileOutputStream; import java.io.InputSt ...
- ES6-对象赋值,key值得构建,is()方法对比对象,assign()合并对象
ES6对象赋值: // es5 let name = "ananiah"; let skill ='web'; let obj = {name:name,skill:skill}; ...
- Linux ssh突然连接不了的案例浅析
公司的Linux服务器都是通过一台JumpServer跳转的.个人使用Jumpserver(开源跳板机系统)时,有时候由于需要上传.下载文件很不方便.而由于配置关系,一般情况无法使用SecureCRT ...
- 工作日志,go get -v -x github.com/pebbe/zmq4 失败问题
工作日志,go get -v -x github.com/pebbe/zmq4 失败问题 笔者因为工作需要使用ZeroMQ,但是在执行go get -v -x github.com/pebbe/zmq ...