C# - WinFrm应用程序MessageBox自动关闭小实验
标签: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
评论