C# - WinFrm应用程序MessageBox自动关闭小实验

2021-01-28 09:12

阅读:627

标签:img   using   help   move   kill   drawing   cti   show   按键   

概述

在程序中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 MessageBoxTest
 11 {
 12     /// 
 13     /// 作者:Alan.hsiang
 14     /// 日期:2018-04-18
 15     /// 描述:通过WinAPI进行查找窗口,并对窗口进行操作
 16     /// 
 17     public class MessageBoxHelper
 18     {
 19         /// 
 20         /// 查找窗口
 21         /// 
 22         /// 窗口句柄
 23         /// 窗口标题
 24         /// 
 25         [DllImport("user32.dll", CharSet = CharSet.Auto)]
 26         static extern IntPtr FindWindow(IntPtr hwnd, string title);
 27 
 28         /// 
 29         /// 移动窗口
 30         /// 
 31         /// 窗口句柄
 32         /// 起始位置X
 33         /// 起始位置Y
 34         /// 窗口宽度
 35         /// 窗口高度
 36         /// 是否重绘
 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         /// 
 41         /// 获取窗口矩形
 42         /// 
 43         /// 窗口句柄
 44         /// 
 45         /// 
 46         [DllImport("user32.dll", CharSet = CharSet.Auto)]
 47         static extern bool GetWindowRect(IntPtr hwnd, out Rectangle rect);
 48 
 49         /// 
 50         /// 向窗口发送信息
 51         /// 
 52         /// 窗口句柄
 53         /// 信息
 54         /// 高字节
 55         /// 低字节
 56         /// 
 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         /// 
 71         /// 对话框标题
 72         /// 
 73         public static string[] titles = new string[4] { "请选择", "提示", "错误", "警告" };
 74 
 75         /// 
 76         /// 查找和移动窗口
 77         /// 
 78         /// 窗口标题
 79         /// 起始位置X
 80         /// 起始位置Y
 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         /// 
 95         /// 查找和关闭窗口
 96         /// 
 97         /// 标题
 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         /// 
115         /// 查找和关闭窗口
116         /// 
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 
132             t.Start();
133         }
134     }
135 }
View Code

原博客地址:

技术图片

C# - WinFrm应用程序MessageBox自动关闭小实验

标签:img   using   help   move   kill   drawing   cti   show   按键   

原文地址:https://www.cnblogs.com/jeremywucnblog/p/11905054.html


评论


亲,登录后才可以留言!