C# MessageBox自动关闭
本文以一个简单的小例子,介绍如何让MessageBox弹出的对话框,在几秒钟内自动关闭。特别是一些第三方插件(如:dll)弹出的对话框,最为适用。本文仅供学习分享使用,如有不足之处,还请指正。
概述
在程序中MessageBox弹出的对话框,用于向用户展示消息,这是一个模式窗口,可阻止应用程序中的其他操作,直到用户将其关闭。但是有时候在自动化程序中,如果弹出对话框,程序将会中断,等待人工的干预,这是一个非常不好的交互体验,如果程序能够自动帮我们点击其中一个按钮,让对话框消失,该有多好。
原理
通过对话框的标题查找对话框,获取对话框的句柄,然后对话框发送指令。
涉及知识点
- MessageBox 显示消息窗口(也称为对话框)向用户展示消息。这是一个模式窗口,可阻止应用程序中的其他操作,直到用户将其关闭。System.Windows.Forms.MessageBox可包含通知并指示用户的文本、按钮和符号。
- Thread 创建和控制线程,设置其优先级并获取其状态。本例子主要创建一个线程,查找弹出的窗口。
- WIN32 API 也就是Microsoft Windows 32位平台的应用程序编程接口。每一个服务,就是一个函数,用于和Windows进行交互。
- MessageBoxButtons 是一个Enum,表示对话框上显示哪些按钮。
- PostMessage 是Windows API(应用程序接口)中的一个常用函数,用于将一条消息放入到消息队列中。消息队列里的消息通过调用GetMessage和PeekMessage取得。
示例截图如下:

关键代码
核心代码如下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace DemoMessageBox
{
/// <summary>
/// 作者:Alan.hsiang
/// 日期:2018-04-18
/// 描述:通过WinAPI进行查找窗口,并对窗口进行操作
/// </summary>
public class MessageBoxHelper
{
/// <summary>
/// 查找窗口
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <param name="title">窗口标题</param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr FindWindow(IntPtr hwnd, string title); /// <summary>
/// 移动窗口
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <param name="x">起始位置X</param>
/// <param name="y">起始位置Y</param>
/// <param name="nWidth">窗口宽度</param>
/// <param name="nHeight">窗口高度</param>
/// <param name="rePaint">是否重绘</param>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern void MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, bool rePaint); /// <summary>
/// 获取窗口矩形
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <param name="rect"></param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern bool GetWindowRect(IntPtr hwnd, out Rectangle rect); /// <summary>
/// 向窗口发送信息
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <param name="msg">信息</param>
/// <param name="wParam">高字节</param>
/// <param name="lParam">低字节</param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int PostMessage(IntPtr hwnd, int msg, uint wParam, uint lParam); public const int WM_CLOSE = 0x10; //关闭命令 public const int WM_KEYDOWN = 0x0100;//按下键 public const int WM_KEYUP = 0x0101;//按键起来 public const int VK_RETURN = 0x0D;//回车键 public static bool IsWorking = false; /// <summary>
/// 对话框标题
/// </summary>
public static string[] titles = new string[] { "请选择", "提示", "错误", "警告" }; /// <summary>
/// 查找和移动窗口
/// </summary>
/// <param name="title">窗口标题</param>
/// <param name="x">起始位置X</param>
/// <param name="y">起始位置Y</param>
public static void FindAndMoveWindow(string title, int x, int y)
{
Thread t = new Thread(() =>
{
IntPtr msgBox = IntPtr.Zero;
while ((msgBox = FindWindow(IntPtr.Zero, title)) == IntPtr.Zero) ;
Rectangle r = new Rectangle();
GetWindowRect(msgBox, out r);
MoveWindow(msgBox, x, y, r.Width - r.X, r.Height - r.Y, true);
});
t.Start();
} /// <summary>
/// 查找和关闭窗口
/// </summary>
/// <param name="title">标题</param>
private static void FindAndKillWindow(string title)
{
IntPtr ptr = FindWindow(IntPtr.Zero, title);
if (ptr != IntPtr.Zero)
{
int ret = PostMessage(ptr, WM_CLOSE, , );
Thread.Sleep();
ptr = FindWindow(IntPtr.Zero, title);
if (ptr != IntPtr.Zero)
{
PostMessage(ptr, WM_KEYDOWN, VK_RETURN, );
PostMessage(ptr, WM_KEYUP, VK_RETURN, );
}
}
} /// <summary>
/// 查找和关闭窗口
/// </summary>
public static void FindAndKillWindow()
{
Thread t = new Thread(() =>
{
while (IsWorking)
{
//按标题查找
foreach (string title in titles)
{
FindAndKillWindow(title);
}
Thread.Sleep();
}
});
t.Start();
}
}
}
备注
关于源码,请点击链接自行下载。
关于PostMessage和SendMessage的区分,请点链接
C# MessageBox自动关闭的更多相关文章
- 设置MessageBox自动关闭
通过设置定时器,让定时器的Tick事件模拟往MessageBox发送一个Enter按钮代替用鼠标点击MessageBox上的确定按钮,来实现MessageBox的自动关闭,实现代码如下: System ...
- winform messagebox自动关闭
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- C# - WinFrm应用程序MessageBox自动关闭小实验
概述 在程序中MessageBox弹出的对话框,用于向用户展示消息,这是一个模式窗口,可阻止应用程序中的其他操作,直到用户将其关闭.但是有时候在自动化程序中,如果弹出对话框,程序将会中断,等待人工的干 ...
- C#MessageBox 自动关闭窗口
1:MessageBox弹出的模式窗口会先阻塞掉它的父级线程.所以我们可以考虑在MessageBox前先增加一个用于"杀"掉MessageBox窗口的线程.因为需要在规定时间内&q ...
- 定时自动关闭messagebox
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- c#自动关闭 MessageBox 弹出的窗口
我们都知道,MessageBox弹出的窗口是模式窗口,模式窗口会自动阻塞父线程的.所以如果有以下代码: MessageBox.Show("内容',"标题"); 则只有关闭 ...
- WinForm中使MessageBox实现可以自动关闭功能
WinForm 下我们可以调用MessageBox.Show 来显示一个消息对话框,提示用户确认等操作.在有些应用中我们需要通过程序来自动关闭这个消息对话框而不是由用户点击确认按钮来关闭.然而.Net ...
- c# winform 自动关闭messagebox 模拟回车
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- 延时并自动关闭MessageBox
信息提示框(MessageBox)是微软NET自带的一个用于弹出警告.错误或者讯息一类的“模式”对话框.此类对话框一旦开启,则后台窗体无法再被激活(除非当前的MessageBox被点击或者关闭取消). ...
随机推荐
- java 23种设计模式 深入理解【转】
以下是学习过程中查询的资料,别人总结的资料,比较容易理解(站在各位巨人的肩膀上,望博主勿究) 创建型抽象工厂模式 http://www.cnblogs.com/java-my-life/archive ...
- emWin酿造机过程演示,含uCOS-III和FreeRTOS两个版本
第2期:酿造机过程演示 配套例子:V6-902_STemWin提高篇实验_酿造机过程演示(uCOS-III)V6-903_STemWin提高篇实验_酿造机过程演示(FreeRTOS) 例程下载地址:h ...
- 【DFS】素数环问题
题目: 输入正整数n,对1-n进行排列,使得相邻两个数之和均为素数,输出时从整数1开始,逆时针排列.同一个环应恰好输出一次.n<=16 如输入: 6 输出: 1 4 3 2 5 6 1 6 5 ...
- [Swift]LeetCode37. 解数独 | Sudoku Solver
Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy ...
- [Swift]LeetCode334. 递增的三元子序列 | Increasing Triplet Subsequence
Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the ar ...
- [Swift]LeetCode528. 按权重随机选择 | Random Pick with Weight
Given an array w of positive integers, where w[i] describes the weight of index i, write a function ...
- [Swift]LeetCode883. 三维形体投影面积 | Projection Area of 3D Shapes
On a N * N grid, we place some 1 * 1 * 1 cubes that are axis-aligned with the x, y, and z axes. Each ...
- JS异步解析
同步和异步 举个
- Spring中你可能不知道的事(二)
在上一节中,我介绍了Spring中极为重要的BeanPostProcessor BeanFactoryPostProcessor Import ImportSelector,还介绍了一些其他的零碎知识 ...
- java线程阻塞唤醒的四种方式
java在多线程情况下,经常会使用到线程的阻塞与唤醒,这里就为大家简单介绍一下以下几种阻塞/唤醒方式与区别,不做详细的介绍与代码分析 suspend与resume Java废弃 suspend() 去 ...