LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C# MessageBox自动关闭

admin
2021年1月29日 18:20 本文热度 3100

本文以一个简单的小例子,介绍如何让MessageBox弹出的对话框,在几秒钟内自动关闭。特别是一些第三方插件(如:dll)弹出的对话框,最为适用。本文仅供学习分享使用,如有不足之处,还请指正。

概述

在程序中MessageBox弹出的对话框,用于向用户展示消息,这是一个模式窗口,可阻止应用程序中的其他操作,直到用户将其关闭。但是有时候在自动化程序中,如果弹出对话框,程序将会中断,等待人工的干预,这是一个非常不好的交互体验,如果程序能够自动帮我们点击其中一个按钮,让对话框消失,该有多好。

原理

通过对话框的标题查找对话框,获取对话框的句柄,然后对话框发送指令。

涉及知识点

  • MessageBox   显示消息窗口(也称为对话框)向用户展示消息。这是一个模式窗口,可阻止应用程序中的其他操作,直到用户将其关闭。System.Windows.Forms.MessageBox可包含通知并指示用户的文本、按钮和符号。
  • Thread 创建和控制线程,设置其优先级并获取其状态。本例子主要创建一个线程,查找弹出的窗口。
  • WIN32 API 也就是Microsoft Windows 32位平台的应用程序编程接口。每一个服务,就是一个函数,用于和Windows进行交互。
  • MessageBoxButtons 是一个Enum,表示对话框上显示哪些按钮。
  • PostMessage 是Windows API(应用程序接口)中的一个常用函数,用于将一条消息放入到消息队列中。消息队列里的消息通过调用GetMessage和PeekMessage取得。

示例截图如下:


关键代码

核心代码如下:

1 using System; 2 using System.Collections.Generic; 3 using System.Drawing; 4 using System.Linq; 5 using System.Runtime.InteropServices; 6 using System.Text; 7 using System.Threading; 8 using System.Threading.Tasks; 9 10 namespace DemoMessageBox 11 { 12 /// <summary> 13 /// 作者:Alan.hsiang 14 /// 日期:2018-04-18 15 /// 描述:通过WinAPI进行查找窗口,并对窗口进行操作 16 /// </summary> 17 public class MessageBoxHelper 18 { 19 /// <summary> 20 /// 查找窗口 21 /// </summary> 22 /// <param name="hwnd">窗口句柄</param> 23 /// <param name="title">窗口标题</param> 24 /// <returns></returns> 25 [DllImport("user32.dll", CharSet = CharSet.Auto)] 26 static extern IntPtr FindWindow(IntPtr hwnd, string title); 27 28 /// <summary> 29 /// 移动窗口 30 /// </summary> 31 /// <param name="hwnd">窗口句柄</param> 32 /// <param name="x">起始位置X</param> 33 /// <param name="y">起始位置Y</param> 34 /// <param name="nWidth">窗口宽度</param> 35 /// <param name="nHeight">窗口高度</param> 36 /// <param name="rePaint">是否重绘</param> 37 [DllImport("user32.dll", CharSet = CharSet.Auto)] 38 static extern void MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, bool rePaint); 39 40 /// <summary> 41 /// 获取窗口矩形 42 /// </summary> 43 /// <param name="hwnd">窗口句柄</param> 44 /// <param name="rect"></param> 45 /// <returns></returns> 46 [DllImport("user32.dll", CharSet = CharSet.Auto)] 47 static extern bool GetWindowRect(IntPtr hwnd, out Rectangle rect); 48 49 /// <summary> 50 /// 向窗口发送信息 51 /// </summary> 52 /// <param name="hwnd">窗口句柄</param> 53 /// <param name="msg">信息</param> 54 /// <param name="wParam">高字节</param> 55 /// <param name="lParam">低字节</param> 56 /// <returns></returns> 57 [DllImport("user32.dll", CharSet = CharSet.Auto)] 58 static extern int PostMessage(IntPtr hwnd, int msg, uint wParam, uint lParam); 59 60 public const int WM_CLOSE = 0x10; //关闭命令 61 62 public const int WM_KEYDOWN = 0x0100;//按下键 63 64 public const int WM_KEYUP = 0x0101;//按键起来 65 66 public const int VK_RETURN = 0x0D;//回车键 67 68 public static bool IsWorking = false; 69 70 /// <summary> 71 /// 对话框标题 72 /// </summary> 73 public static string[] titles = new string[4] { "请选择", "提示", "错误", "警告" }; 74 75 /// <summary> 76 /// 查找和移动窗口 77 /// </summary> 78 /// <param name="title">窗口标题</param> 79 /// <param name="x">起始位置X</param> 80 /// <param name="y">起始位置Y</param> 81 public static void FindAndMoveWindow(string title, int x, int y) 82 { 83 Thread t = new Thread(() => 84 { 85 IntPtr msgBox = IntPtr.Zero; 86 while ((msgBox = FindWindow(IntPtr.Zero, title)) == IntPtr.Zero) ; 87 Rectangle r = new Rectangle(); 88 GetWindowRect(msgBox, out r); 89 MoveWindow(msgBox, x, y, r.Width - r.X, r.Height - r.Y, true); 90 }); 91 t.Start(); 92 } 93 94 /// <summary> 95 /// 查找和关闭窗口 96 /// </summary> 97 /// <param name="title">标题</param> 98 private static void FindAndKillWindow(string title) 99 { 100 IntPtr ptr = FindWindow(IntPtr.Zero, title); 101 if (ptr != IntPtr.Zero) 102 { 103 int ret = PostMessage(ptr, WM_CLOSE, 0, 0); 104 Thread.Sleep(1000); 105 ptr = FindWindow(IntPtr.Zero, title); 106 if (ptr != IntPtr.Zero) 107 { 108 PostMessage(ptr, WM_KEYDOWN, VK_RETURN, 0); 109 PostMessage(ptr, WM_KEYUP, VK_RETURN, 0); 110 } 111 } 112 } 113 114 /// <summary> 115 /// 查找和关闭窗口 116 /// </summary> 117 public static void FindAndKillWindow() 118 { 119 Thread t = new Thread(() => 120 { 121 while (IsWorking) 122 { 123 //按标题查找 124 foreach (string title in titles) 125 { 126 FindAndKillWindow(title); 127 } 128 Thread.Sleep(3000); 129 } 130 }); 131 t.Start(); 132 } 133 } 134 }

备注

关于源码,请点击链接自行下载。

关于PostMessage和SendMessage的区分,请点链接


该文章在 2021/1/29 18:20:42 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved