先来一个辅助类

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.Windows.Forms;
  7.  
  8. namespace HZCX.Utils
  9. {
  10. /// <summary>
  11. /// 鼠标全局钩子
  12. /// </summary>
  13. public static class MouseHook
  14. {
  15. private const int WM_MOUSEMOVE = 0x200;
  16. private const int WM_LBUTTONDOWN = 0x201;
  17. private const int WM_RBUTTONDOWN = 0x204;
  18. private const int WM_MBUTTONDOWN = 0x207;
  19. private const int WM_LBUTTONUP = 0x202;
  20. private const int WM_RBUTTONUP = 0x205;
  21. private const int WM_MBUTTONUP = 0x208;
  22. private const int WM_LBUTTONDBLCLK = 0x203;
  23. private const int WM_RBUTTONDBLCLK = 0x206;
  24. private const int WM_MBUTTONDBLCLK = 0x209;
  25.  
  26. /// <summary>
  27. /// 点
  28. /// </summary>
  29. [StructLayout(LayoutKind.Sequential)]
  30. public class POINT
  31. {
  32. public int x;
  33. public int y;
  34. }
  35.  
  36. /// <summary>
  37. /// 钩子结构体
  38. /// </summary>
  39. [StructLayout(LayoutKind.Sequential)]
  40. public class MouseHookStruct
  41. {
  42. public POINT pt;
  43. public int hWnd;
  44. public int wHitTestCode;
  45. public int dwExtraInfo;
  46. }
  47.  
  48. public const int WH_MOUSE_LL = ; // mouse hook constant
  49.  
  50. // 装置钩子的函数
  51. [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
  52. public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
  53.  
  54. // 卸下钩子的函数
  55. [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
  56. public static extern bool UnhookWindowsHookEx(int idHook);
  57.  
  58. // 下一个钩挂的函数
  59. [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
  60. public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
  61.  
  62. // 全局的鼠标事件
  63. public static event MouseEventHandler OnMouseActivity;
  64.  
  65. // 钩子回调函数
  66. public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
  67.  
  68. // 声明鼠标钩子事件类型
  69. private static HookProc _mouseHookProcedure;
  70. private static int _hMouseHook = ; // 鼠标钩子句柄
  71. /// <summary>
  72. /// 启动全局钩子
  73. /// </summary>
  74. public static void Start()
  75. {
  76. // 安装鼠标钩子
  77. if (_hMouseHook != )
  78. {
  79. Stop();
  80. }
  81. // 生成一个HookProc的实例.
  82. _mouseHookProcedure = new HookProc(MouseHookProc);
  83.  
  84. _hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, _mouseHookProcedure, Marshal.GetHINSTANCE(System.Reflection.Assembly.GetEntryAssembly().GetModules()[]), );
  85.  
  86. //假设装置失败停止钩子
  87. if (_hMouseHook == )
  88. {
  89. Stop();
  90. throw new Exception("SetWindowsHookEx failed.");
  91. }
  92. }
  93.  
  94. /// <summary>
  95. /// 停止全局钩子
  96. /// </summary>
  97. public static void Stop()
  98. {
  99. bool retMouse = true;
  100.  
  101. if (_hMouseHook != )
  102. {
  103. retMouse = UnhookWindowsHookEx(_hMouseHook);
  104. _hMouseHook = ;
  105. }
  106.  
  107. // 假设卸下钩子失败
  108. if (!(retMouse))
  109. throw new Exception("UnhookWindowsHookEx failed.");
  110. }
  111.  
  112. /// <summary>
  113. /// 鼠标钩子回调函数
  114. /// </summary>
  115. private static int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)
  116. {
  117. // 假设正常执行而且用户要监听鼠标的消息
  118. if ((nCode >= ) && (OnMouseActivity != null))
  119. {
  120. MouseButtons button = MouseButtons.None;
  121. int clickCount = ;
  122.  
  123. switch (wParam)
  124. {
  125. case WM_LBUTTONDOWN:
  126. button = MouseButtons.Left;
  127. clickCount = ;
  128. break;
  129. case WM_LBUTTONUP:
  130. button = MouseButtons.Left;
  131. clickCount = ;
  132. break;
  133. case WM_LBUTTONDBLCLK:
  134. button = MouseButtons.Left;
  135. clickCount = ;
  136. break;
  137. case WM_RBUTTONDOWN:
  138. button = MouseButtons.Right;
  139. clickCount = ;
  140. break;
  141. case WM_RBUTTONUP:
  142. button = MouseButtons.Right;
  143. clickCount = ;
  144. break;
  145. case WM_RBUTTONDBLCLK:
  146. button = MouseButtons.Right;
  147. clickCount = ;
  148. break;
  149. }
  150. if (button != MouseButtons.None && clickCount>)
  151. {
  152. // 从回调函数中得到鼠标的信息
  153. MouseHookStruct MyMouseHookStruct = (MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));
  154. MouseEventArgs e = new MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, );
  155. OnMouseActivity(null, e);
  156. }
  157. }
  158.  
  159. // 启动下一次钩子
  160. int inext = CallNextHookEx(_hMouseHook, nCode, wParam, lParam);
  161. return inext;
  162. }
  163. }
  164. }

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;

  1. void hook_OnMouseActivity(object sender, MouseEventArgs e)
  2. {
  3. try
  4. {
  5. if (this._isLoseFocusClose && e.Clicks > )
  6. {
  7. if (e.Button == System.Windows.Forms.MouseButtons.Left || e.Button == System.Windows.Forms.MouseButtons.Right)
  8. {
  9. if (!this.IsDisposed)
  10. {
  11. if (!this.ClientRectangle.Contains(this.PointToClient(e.Location)))
  12. {
  13. base.Close();
  14. }
  15. }
  16. }
  17. }
  18. }
  19. catch { }
  20. }

就这样了

c# winform 窗体失去焦点关闭(钩子实现)的更多相关文章

  1. Winform 窗体获得焦点

    给窗体添加Shown事件 public void Form_Shown(object sender, EventArgs e) { this.Activate(); this.Focus(); //定 ...

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

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

  3. Winform开发之窗体显示、关闭与资源释放

    Winform的窗体涉及到一般窗体(单文档窗体).MDI窗体.窗体之间的关系等,那么如果调用打开新窗体.如何关闭窗体.窗体资源的释放等都关系到软件运行的效率,本文一一介绍 1.窗体的显示 从一个窗体打 ...

  4. Winform 窗体的操作

    原文:http://www.cnblogs.com/Billy-rao/archive/2012/05/16/2503437.html 怎样能使winform窗体的大小固定住,不能调整其大小 窗体Fo ...

  5. WinForm窗体嵌入

    一.在winform窗体上添加两个控件 1.容器>Panel 2.添加 SideBar.dll (下载链接:http://pan.baidu.com/s/1o6qhf9w) (1)将SideBa ...

  6. C#中WinForm窗体事件的执行次序

    C#中WinForm窗体事件的执行次序如下: 当 Windows Form 应用程序启动时,会以下列顺序引发主要表单的启动事件:        System.Windows.Forms.Control ...

  7. C# winform窗体设计-通过条件查询数据

    在winform 数据库设计中,有时候需要通过条件查询对应的数据,并且将数据显示在文本框(or 富文本框)中,下面,小编将讲述通过一个条件: 首先,我们需要对数据库建立连接,并且执行数据库命令,在此之 ...

  8. Winform窗体事件发生顺序

    Form 和Control 类公开了一组与应用程序启动和关闭相关联的事件.当Windows 窗体应用程序启动时,主窗体的启动事件按以下顺序引发: System.Windows.Forms.Contro ...

  9. 小例子(二)、winform窗体间的关系

    写一个关于winform窗体间的关系 1.登陆,思路:登陆后隐藏登陆窗体,关闭Form2时结束整个应用程序. //登陆窗体 private void button2_Click(object send ...

随机推荐

  1. 更改路由器的外网IP

    此方法适用于通过路由器拨号上网的宽带,若宽带通过光猫拨号上网则需要将光猫改为桥接模式并在路由器中配置宽带账号和密码 测试环境: 路由器:TP-LINK TL-WDR7800千兆版 硬件版本:1.0 软 ...

  2. 【python爬虫】Xpath

    一.xml是什么 1.定义:可扩展标记性语言 2.特点:xml的是具有自描述结构的半结构化数据. 3.作用:xml主要设计宗旨是用来传输数据的.他还可以作为配置文件. 二.xml和html的区别 1. ...

  3. python-paramiko对远程服务器终端的操作

    1.with open写文件到本地 2.paramiko SFTPClient将文件推到salt服务端 3.paramiko SSHClient通过salt-cp将文件分发给目标服务器 1. with ...

  4. ASP.NET Core 3.0 gRPC 配置使用HTTP

    前言 gRPC是基于http/2,是同时支持https和http协议的,我们在gRPC实际使用中,在内网通讯场景下,更多的是走http协议,达到更高的效率,下面介绍如何在 .NET Core 3.0 ...

  5. CreateWindowW()函数

    函数原型为: 该函数利用已经注册的窗口类 创建一个窗口,并返回该窗口的句柄 HWND CreateWindow( LPCTSTR lpClassName, //窗口类名称,也可以是控件名称 LPCTS ...

  6. Spring MVC的注解二

    概述 Spring从2.5版本开始引入注解,虽然版本不断变化,但是注解的特性一直被延续下来并不断进行扩展,这里就来记录一下Spring MVC中常用的注解,本文承接前文继续记录@PathVariabl ...

  7. 用XHR简单封装一个axios

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. Ubuntu16.04 安装 JDK

    1.到Oracle官网下载 地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html ...

  9. Linux iotop工具简介

    iotop的简介: iotop是一款开源.免费的用来监控磁盘I/O使用状况的类似top命令的工具,iotop可以监控进程的I/O信息.它是Python语言编写的,与iostat工具比较,iostat是 ...

  10. 好用的性能检测工具-性能监控工具- Glances

    平常我经常使用 htop 工具来进行对主机进行性能检测.但是它只能对 进行进行管理.并简要显示 进程和cpu和内存使用信息:性能监控工具: glances 是比较好的性能检测工具.相比较htop还能显 ...