C# MessageBox.Show()超時後 自動關閉

請高手幫忙,好比我作出一個響應,彈出一個MessageBox。
怎麼作讓它3秒後自動關閉,點擊上面的肯定也能夠手動關閉、、、、、、、、、、、、、、、、、、、、?
謝謝

看網上有說寫一個MessageBox繼承System.Windows.Form,而後添加一個Timer。
能不能有點實例代碼,學習一下。代碼最好簡潔點,要否則看的太亂了。html

---------------編程

寫好了,如下是截圖和部分源碼,完整的源碼在附件中:ide

1.指定要彈出的消息以及定時的時間(單位秒)函數

2.彈出後,對話框上的肯定按鈕上會動態倒計時,當時間爲0時自動關閉,也能夠經過點擊肯定按鈕關閉post

核心代碼:學習

 

 

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|所需財富值:5ui

 

出處:https://zhidao.baidu.com/question/575559071.htmlthis

=================================================================================spa

本文以一個簡單的小例子,介紹如何讓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
相關文章
相關標籤/搜索