概述

在程序中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 MessageBoxTest
{
/// <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();
}
}
}

原博客地址:

C# - WinFrm应用程序MessageBox自动关闭小实验的更多相关文章

  1. 1.4 Crack小实验

    0_day 第一章 基础知识 1.4 Crack小实验 <0day_2th>王清 著 电子书 下载链接:https://pan.baidu.com/s/11TgibQSC3-kYwCInm ...

  2. Hadoop之词频统计小实验

    声明:    1)本文由我原创撰写,转载时请注明出处,侵权必究. 2)本小实验工作环境为Ubuntu操作系统,hadoop1-2-1,jdk1.8.0. 3)统计词频工作在单节点的伪分布上,至于真正实 ...

  3. 秒懂JVM的三大参数类型,就靠这十个小实验了

    秒懂JVM的三大参数类型,就靠这十个小实验了 你好,我是悟空哥,「7年项目开发经验,全栈工程师,开发组长,超喜欢图解编程底层原理」.手写了2个小程序,Java刷题小程序,PMP刷题小程序,已发布到公众 ...

  4. 基于 Source Generators 做个 AOP 静态编织小实验

    0. 前言 上接:用 Roslyn 做个 JIT 的 AOP 作为第二篇,我们基于Source Generators做个AOP静态编织小实验. 内容安排如下: source generators 是什 ...

  5. PBR综合小实验视频-狮子XL

    这个是上学时候录的一个策略路由小实验

  6. ubuntu下格式化内存当硬盘使的小实验

    内存虚拟硬盘(ramdisk)是指通过软件技术,将物理内存进行分割,将一部分内存通过虚拟技术转变为硬盘以较大幅度提升计算机数据读取速度和保护硬盘. 在ubuntu下的dev下有ram相关的文件,这些文 ...

  7. MongoDB 主从复制小实验

    MongoDB 主从复制小实验 操作环境描述:WIN8  64位操作系统,内装虚拟机为CentOS 5.5 32位系统. 操作描述:跟其他关系型数据库类似,在主库进行数据操作,将数据同步到从节点,从节 ...

  8. 张小龙的野心:用小程序重构web|小程序好处及可能的不足

    一:张小龙的野心:用小程序重构web 一 很多年以前,张小龙写了一款软件:Foxmail. 这款软件当年有数百万用户,这是一个相当庞大的量,因为彼时网民也只有千万当量级的规模. 我是一个非常忠实的用户 ...

  9. PS小实验-去除水印

    PS小实验-去除水印 水印是一些品牌商覆盖在图片或视频上的一个商标logo或小文本,比如大家最讨厌的百度logo,作者本人也是比较讨厌水印的,让好端端的一张图片变得美中不足. 个人觉得用photosh ...

随机推荐

  1. Elasticsearch索引按月划分以及获取所有索引数据

    项目中数据库根据月份水平划分,由于没有用数据库中间件,没办法一下查询所有订单信息,所有用Elasticsearch做订单检索. Elasticsearch索引和数据库分片同步,也是根据月份来建立索引. ...

  2. [Muxi_k] Manjaro安装WPS过程

    Manjaro安装WPS过程 首先安装WPS: sudo pacman -S wps-office 1一条命令解决安装好后就可以在显示应用程序这里看到图标了 笔者在安装的时候出了点问题,就是下载了一短 ...

  3. 【重拾基础】耐人寻味的CSS属性white-space

    <耐人寻味的CSS属性white-space>,本文说的white-space是一个控制换行和空白处理的CSS属性.我曾经被这个属性烦死,一直没记住,今天决定还是写下来好好琢磨下. 属性值 ...

  4. Xcode 中配置 clang-format 格式化 C++ 代码

    Xcode 自带的代码格式化功能(control + I)很有限,其 "格式化" 仅限于设置缩进,代码里面的格式是不会处理的.所以需要借助额外的工具来完成代码的美化. clang- ...

  5. goweb-http协议

    先链接到一个我的另一篇有关HTTP的博客 第一次访问时会有些慢~~~ http协议 因为编写 Web 应用必须对 HTTP 有所了解,所以我们对 HTTP 进行介绍 HTTP 协议简介 HTTP 超文 ...

  6. 基于JWT的Token登录认证

    1.JWT简介   JSON Web Token(缩写 JWT),是目前最流行的跨域认证解决方案. 2.JWT的原理        JWT的原理是,服务器认证以后,生成一个JSON格式的对象,发回给客 ...

  7. Specify Action Settings 指定按钮设置

    In this lesson, you will learn how to modify Action properties. The ClearTasks Action will be used. ...

  8. ArcGIS以数据库作为数据源作为source发布服务步骤详解(以Postgresql为例)及各种发布问题

    创建企业级数据库 Data Management Tools-->Geodatabase Administration-->Create Enterprise Geodatabase 按如 ...

  9. udp协议,进程(同步,异步)

    udp协议与进程 一.udp协议 QQ聊天室 #- sever import socket #socket.SOCK_DGRAM--->UPD协议 sever = socket.socket(t ...

  10. sqlserver实现分隔字符串

    sqlserver 使用函数实现分隔字符串 create function dbo.fn_split ( @str_source nvarchar(max), ) ) returns @temp ta ...