C# MessageBox自动关闭

匿名 (未验证) 提交于 2019-12-02 22:10:10

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

概述

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

原理

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

涉及知识点

  • 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 }
View Code

备注

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!