• C# MessageBox.Show()超时后 自动关闭


    请高手帮忙,比如我做出一个响应,弹出一个MessageBox。
    怎么做让它3秒后自动关闭,点击上面的确定也可以手动关闭、、、、、、、、、、、、、、、、、、、、?
    谢谢

    看网上有说写一个MessageBox继承System.Windows.Form,然后添加一个Timer。
    能不能有点实例代码,学习一下。代码最好简洁点,要不然看的太乱了。

    ---------------

    写好了,以下是截图和部分源码,完整的源码在附件中:

    1.指定要弹出的消息以及定时的时间(单位秒)

    2.弹出后,对话框上的确定按钮上会动态倒计时,当时间为0时自动关闭,也可以通过点击确定按钮关闭

    核心代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     public partial class TimingMessageBox : Form
        {
            // 自动关闭的时间限制,如3为3秒后自动关闭
            private int second;
            // 计数器,用以判断当前窗口弹出后持续的时间
            private int counter;
     
            // 构造函数
            public TimingMessageBox(string message, int second)
            {
                InitializeComponent();
                // 显示消息
                this.labelMessage.Text = message;
                // 获得时间限制
                this.second = second;
                // 初始化计数器
                this.counter = 0;
                // 初始化按钮的文本
                this.buttonOK.Text = string.Format("确定({0})"this.second - this.counter);
                // 激活并启动timer,设置timer的触发间隔为1000毫秒(1秒)
                this.timer1.Enabled = true;
                this.timer1.Interval = 1000;
                this.timer1.Start();
            }
     
            private void timer1_Tick(object sender, EventArgs e)
            {
                // 如果没有到达指定的时间限制
                if (this.counter <= this.second)
                {
                    // 刷新按钮的文本
                    this.buttonOK.Text = string.Format("确定({0})"this.second - this.counter);
                    this.Refresh();
                    // 计数器自增
                    this.counter++;
                }
                // 如果到达时间限制
                else
                {
                    // 关闭timer
                    this.timer1.Enabled = false;
                    this.timer1.Stop();
                    // 关闭对话框
                    this.Close();
                }
            }
     
            private void buttonOK_Click(object sender, EventArgs e)
            {
                // 单击确定按钮,关闭对话框
                this.Close();
            }
        }

    然后在主窗体中调用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
     
            private void buttonShowMessageBox_Click(object sender, EventArgs e)
            {
                string message = this.textBoxMessage.Text.Trim();
                int second = Convert.ToInt32(this.textBoxSecond.Text.Trim());
                TimingMessageBox messageBox=new TimingMessageBox(message,second);
                messageBox.ShowDialog();
            }
        }

    TimingMessageBox.zip大小:52.33K|所需财富值:5

    出处:https://zhidao.baidu.com/question/575559071.html

    =================================================================================

    本文以一个简单的小例子,介绍如何让MessageBox弹出的对话框,在几秒钟内自动关闭。

    特别是一些第三方插件(如:dll)弹出的对话框,最为适用。本文仅供学习分享使用,如有不足之处,还请指正。

    概述

    在程序中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 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 }
    复制代码

    备注

    关于源码,请点击链接自行下载。

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

    出处:https://www.cnblogs.com/hsiang/p/8878093.html

    ====================================================

    优化

    根据上面的提醒,自己重新优化下,尽量让项目做较少的改动嘛!~

    调用Win32的没有变化,只是把关闭窗口的方法精简了以些:

        public class Win32Helper
        {
    
            /*先调用GetForegroundWindow然后调用GetWindowFromHwnd*/
    
    
            //GetForegroundWindow API
            [DllImport("user32.dll")]
            static extern IntPtr GetForegroundWindow();
    
    
            //从Handle中获取Window对象
            private static Form GetWindowFromHwnd(IntPtr hwnd)
            {
                return Form.FromHandle(hwnd) as Form;
            }
    
    
            /// <summary>
            /// 获取当前顶级窗体,若获取失败则返回主窗体
            /// </summary>
            public static Form GetTopWindow()
            {
                var hwnd = GetForegroundWindow();
                if (hwnd == IntPtr.Zero)
                {
                    Process p = Process.GetCurrentProcess();
                    hwnd = p.MainWindowHandle;
                }
    
                return GetWindowFromHwnd(hwnd);
            }
    
    
            /// <summary>
            /// 查找窗口
            /// </summary>
            /// <param name="hwnd">窗口句柄</param>
            /// <param name="title">窗口标题</param>
            /// <returns></returns>
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr FindWindow(IntPtr hwnd, string title);
    
    
            public const int WM_CLOSE = 0x10; //关闭命令
            public const int WM_KEYDOWN = 0x0100;//按下键
            public const int WM_KEYUP = 0x0101;//按键起来
            public const int VK_RETURN = 0x0D;//回车键
            /// <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)]
            public static extern int PostMessage(IntPtr hwnd, int msg, uint wParam, uint lParam);
    
        }
    
    
        //弹出消息框
        public class MsgBoxHelper
        {
    
            private static log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    
            public static DialogResult ShowDialog(string msg, IWin32Window win = null, TimeSpan? outTime = null, MessageBoxButtons messageBoxButtons = MessageBoxButtons.OK, MessageBoxIcon messageBoxIcon = MessageBoxIcon.Information)
            {
                DialogResult dr = DialogResult.None;
                var fm = Win32Helper.GetTopWindow();
                if (fm.InvokeRequired)
                {
                    fm.Invoke(new EventHandler(delegate { ShowDialog(msg, win, outTime, messageBoxButtons, messageBoxIcon); }));
                }
                else
                {
                    string strTitle = "消息";
                    win = win == null ? fm : win;
                    outTime = outTime == null ? TimeSpan.FromSeconds(5) : outTime;
                    new Thread(() =>
                    {
                        _log.Info($"ShowDialog : 已启动超时退出。超时时间:{outTime.Value.TotalSeconds}");
                        Thread.Sleep((int)outTime.Value.TotalMilliseconds);
                        FindAndKillWindow(strTitle);
                    }).Start();
                    _log.Info("ShowDialog : Title = " + strTitle + Environment.NewLine + "Msg = " + msg);
                    dr = MessageBox.Show(win, msg, strTitle, messageBoxButtons,
                        messageBoxIcon, MessageBoxDefaultButton.Button1);
                }
                return dr;
            }
    
    
    
            /// <summary>
            /// 查找和关闭窗口
            /// </summary>
            /// <param name="title">标题</param>
            private static void FindAndKillWindow(string title)
            {
                IntPtr ptr = Win32Helper.FindWindow(IntPtr.Zero, title);
                _log.Info($"FindAndKillWindow : 查找窗口标题 = {title},窗口句柄 = " + ptr);
                if (ptr != IntPtr.Zero)
                {
                    int ret = Win32Helper.PostMessage(ptr, Win32Helper.WM_CLOSE, 0, 0);
    
                    Thread.Sleep(1000);
                    ptr = Win32Helper.FindWindow(IntPtr.Zero, title);
                    _log.Info($"FindAndKillWindow : 发送关闭窗口命令结果 = {ret},再次查找[{title}]窗口结果 = " + ptr);
                    if (ptr != IntPtr.Zero)
                    {
                        Win32Helper.PostMessage(ptr, Win32Helper.WM_KEYDOWN, Win32Helper.VK_RETURN, 0);
                        Win32Helper.PostMessage(ptr, Win32Helper.WM_KEYUP, Win32Helper.VK_RETURN, 0);
                    }
                }
            }
    
        }
    View Code
  • 相关阅读:
    CentOS 8配置神奇的自动挂载光驱文件夹misc
    Linux预定义通配符及实例
    history历史记录增加显示时间和用户
    CentOS 8 命令行更改系统语言
    使用screen实现多终端同步显示
    在MobaXtrem使用CentOS 上的图形工具
    CentOS中id前10的用户
    添加硬盘后不重启使系统识别新硬盘
    bash默认启用的内部命令
    九、分页查询
  • 原文地址:https://www.cnblogs.com/mq0036/p/12611736.html
Copyright © 2020-2023  润新知