zoukankan      html  css  js  c++  java
  • 自动关闭messagebox

    WinForm 下我们可以调用MessageBox.Show 来显示一个消息对话框,提示用户确认等操作。在有些应用中我们需要通过程序来自动关闭这个消息对话框而不是由用户点击确认按钮来关闭。然而.Net framework 没有为我们提供自动关闭MessageBox 的方法,要实现这个功能,我们需要使用Window API 来完成。

          首先我们需要找到这个消息对话框的窗口句柄,一个比较简单的方法就是用 FindWindow API 来查找对应的窗体句柄。

            [DllImport("user32.dll", SetLastError = true)]
            static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    这个API调用可以通过窗口的类名或者窗口标题的名字来查找窗口句柄。

          接下来我们还需要找到一个 API 来关闭对话框,这里我使用 EndDialog

            [DllImport("user32.dll")]
            static extern bool EndDialog(IntPtr hDlg, out IntPtr nResult);

    有了这两个API函数,我们就可以来关闭消息对话框了。思路是在调用MessageBox.Show 前启动一个后台工作线程,这个工作线程等待一定时间后开始查找消息对话框的窗口句柄,找到后调用EndDialog API 函数关闭这个消息对话框。不过这个方法有个问题,就是如果同时又多个同名的消息对话框(可能不一定是这个应用的),这样做可能会关错窗口,如何解决这个问题,我还没有想出比较好的方法,如果大家有更好的方法解决这个问题,不妨一起讨论讨论。
        
          我根据这个思路编写了延时关闭消息对话框的函数

            public void ShowMessageBoxTimeout(string text, string caption, 
                MessageBoxButtons buttons, int timeout)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(CloseMessageBox), 
                    new CloseState(caption, timeout));
                MessageBox.Show(text, caption,buttons);
            }

    这个函数中timeout 参数单位是毫秒,其他参数和MessageBox.Show的参数含义是一样的,这里不再详细说明。

      这个函数中首先利用线程池调用一个工作线程 CloseMessageBox ,并将对话框的标题和延时时间通过CloseState这个类传递给CloseMessageBox函数。

      CloseState 的定义如下:

              private class CloseState
            {
                private int _Timeout;
    
                /**//// <summary>
                /// In millisecond
                /// </summary>
                public int Timeout
                {
                    get
                    {
                        return _Timeout;
                    }
                }
    
                private string _Caption;
    
                /**//// <summary>
                /// Caption of dialog
                /// </summary>
                public string Caption
                {
                    get
                    {
                        return _Caption;
                    }
                }
    
                public CloseState(string caption, int timeout)
                {
                    _Timeout = timeout;
                    _Caption = caption;
                }
            }

    最后就是CloseMessageBox函数了,直接看代码吧

            private void CloseMessageBox(object state)
            {
                CloseState closeState = state as CloseState;
    
                Thread.Sleep(closeState.Timeout);
                IntPtr dlg = FindWindow(null, closeState.Caption);
    
                if (dlg != IntPtr.Zero)
                {
                    IntPtr result;
                    EndDialog(dlg, out result);
                }
            }
  • 相关阅读:
    Heritrix源码分析(三) 修改配置文件order.xml加快你的抓取速度
    Heritrix源码分析(四) 各个类说明(二)
    Heritrix源码分析(二) 配置文件order.xml介绍
    Error running Tomcat 6: Address localhost:8080 is already in use
    NLP常用开源/免费工具
    Error: Read from storage 0 bytes, but requested 12 bytes 的解决方法
    Inproc 和 Outproc 的区别
    最搞怪面试问题TOP10:你也来试试看 (大家一起来做题)
    [废弃]想写一个玩魔方的游戏
    C++template中typename 和class有什么区别?
  • 原文地址:https://www.cnblogs.com/ArRan/p/2818942.html
Copyright © 2011-2022 走看看