一尘不染

几秒钟后关闭MessageBox

c#

我有一个Windows Forms应用程序VS2010 C#,在其中显示一个MessageBox以显示消息。

我有一个好的按钮,但是如果他们走开,我想超时并关闭消息框,例如说5秒钟,然后自动关闭消息框。

有自定义的MessageBox(从Form继承)或另一个报告程序Forms,但是有趣的是不必使用Form。

有任何建议或样品吗?

更新:

对于WPF,
在C#中自动关闭消息框

自定义MessageBox(使用表单继承)
http://www.codeproject.com/Articles/17253/A-Custom-Message-
Box

http://www.codeproject.com/Articles/327212/Custom-Message-Box-in-
VC

http://tutplusplus.blogspot.com.es/2010/07/c-tutorial-create-your-own-
custom.html

http://medmondson2011.wordpress.com/2010/04/07/easy-to-use-custom-c-message-
box-with-a-configurable-
checkbox/

可滚动
的消息框C#中的可滚动的消息框

异常报告器
https://stackoverflow.com/questions/49224/good-crash-reporting-library-in-c-
sharp

http://www.codeproject.com/Articles/6895/A-Reusable-Flexible-Error-Reporting-
Framework

解:

也许我认为以下答案是很好的解决方案,无需使用表格。

https://stackoverflow.com/a/14522902/206730

https://stackoverflow.com/a/14522952/206730


阅读 397

收藏
2020-05-19

共1个答案

一尘不染

请尝试以下方法:

AutoClosingMessageBox.Show("Text", "Caption", 1000);

AutoClosingMessageBox类实现如下:

public class AutoClosingMessageBox {
    System.Threading.Timer _timeoutTimer;
    string _caption;
    AutoClosingMessageBox(string text, string caption, int timeout) {
        _caption = caption;
        _timeoutTimer = new System.Threading.Timer(OnTimerElapsed,
            null, timeout, System.Threading.Timeout.Infinite);
        using(_timeoutTimer)
            MessageBox.Show(text, caption);
    }
    public static void Show(string text, string caption, int timeout) {
        new AutoClosingMessageBox(text, caption, timeout);
    }
    void OnTimerElapsed(object state) {
        IntPtr mbWnd = FindWindow("#32770", _caption); // lpClassName is #32770 for MessageBox
        if(mbWnd != IntPtr.Zero)
            SendMessage(mbWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
        _timeoutTimer.Dispose();
    }
    const int WM_CLOSE = 0x0010;
    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
}

更新: 如果希望在超时之前选择某些内容时要获取基础MessageBox的返回值,则可以使用以下版本的代码:

var userResult = AutoClosingMessageBox.Show("Yes or No?", "Caption", 1000, MessageBoxButtons.YesNo);
if(userResult == System.Windows.Forms.DialogResult.Yes) { 
    // do something
}
...
public class AutoClosingMessageBox {
    System.Threading.Timer _timeoutTimer;
    string _caption;
    DialogResult _result;
    DialogResult _timerResult;
    AutoClosingMessageBox(string text, string caption, int timeout, MessageBoxButtons buttons = MessageBoxButtons.OK, DialogResult timerResult = DialogResult.None) {
        _caption = caption;
        _timeoutTimer = new System.Threading.Timer(OnTimerElapsed,
            null, timeout, System.Threading.Timeout.Infinite);
        _timerResult = timerResult;
        using(_timeoutTimer)
            _result = MessageBox.Show(text, caption, buttons);
    }
    public static DialogResult Show(string text, string caption, int timeout, MessageBoxButtons buttons = MessageBoxButtons.OK, DialogResult timerResult = DialogResult.None) {
        return new AutoClosingMessageBox(text, caption, timeout, buttons, timerResult)._result;
    }
    void OnTimerElapsed(object state) {
        IntPtr mbWnd = FindWindow("#32770", _caption); // lpClassName is #32770 for MessageBox
        if(mbWnd != IntPtr.Zero)
            SendMessage(mbWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
        _timeoutTimer.Dispose();
        _result = _timerResult;
    }
    const int WM_CLOSE = 0x0010;
    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
}

另一个更新

我用YesNo按钮检查了@Jack的情况,发现发送WM_CLOSE消息的方法根本不起作用。
我将在单独的AutoclosingMessageBox库的上下文中提供一个
修复程序 。该库包含重新设计的方法,我认为这对某人可能有用。
也可以通过NuGet包获得

Install-Package AutoClosingMessageBox

发行说明(v1.0.0.2):
-新的Show(IWin32Owner)API支持大多数流行的场景(在#1的上下文中);
-新的Factory()API提供对MessageBox显示的完全控制;

2020-05-19