Close a Messagebox After Several Seconds

Close a MessageBox after several seconds

Try the following approach:

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

Where the AutoClosingMessageBox class implemented as following:

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);
}

Update:
If you want to get the return value of the underlying MessageBox when user selects something before the timeout you can use the following version of this code:

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);
}

Yet another Update

I have checked the @Jack's case with YesNo buttons and discovered that the approach with sending the WM_CLOSE message does not work at all.

I will provide a fix in the context of the separate AutoclosingMessageBox library. This library contains redesigned approach and, I believe, can be useful to someone.

It also available via NuGet package:

Install-Package AutoClosingMessageBox

Release Notes (v1.0.0.2):
- New Show(IWin32Owner) API to support most popular scenarios (in the
context of #1 );

- New Factory() API to provide full control on MessageBox showing;

Automatically close messagebox in C#

You will need to create your own Window, with the code-behind containing a loaded handler and a timer handler as follows:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
Timer t = new Timer();
t.Interval = 3000;
t.Elapsed += new ElapsedEventHandler(t_Elapsed);
t.Start();
}

void t_Elapsed(object sender, ElapsedEventArgs e)
{
this.Dispatcher.Invoke(new Action(()=>
{
this.Close();
}),null);
}

You can then make your custom message box appear by calling ShowDialog():

MyWindow w = new MyWindow();
w.ShowDialog();

Auto Close Message Box

I've used this code to Close a messagebox without creating a new form. It do works fine for me. Might help you guys also. I got it from Close a MessageBox after several seconds

 private void btnOK_Click(object sender, RoutedEventArgs e)
{
AutoClosingMessageBox.Show("Wrong Input.", "LMS", 5000);
}

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);
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(null, _caption);
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);
}

Open multiple instances of MessageBox and automatically close after several seconds

I suggest not using a MessageBox for this task. Instead, make your own custom form. Make it the size, shape, and look you want. Then, in its code-behind file, you can create a timer, unique to that window itself. That way, you can spawn as many of them as you want, and they will manage their own timers and closing themselves, and you don't have to do anything like finding the window. It's possible to make a Form look very much like a MessageBox. And because you can call ShowDialog, you can make them behave similarly to MessageBoxes as well (though that would be somewhat counterproductive, because you can only interact with one dialog at a time).

Close MessageBox on Windows Mobile application after several seconds (C#)

Ok, I solved it by adding Panel component (with Label message) that emulates Message box. So it can be set to invisible after few seconds by Timer component.

Also, I added one more action to it - it will be set as invisible if end user press it.

pyqt: messagebox automatically closing after few seconds

Try with my solution,
I have created a new type of QMessageBox with your requirements

import sys
from PyQt4 import QtCore
from PyQt4 import QtGui

class TimerMessageBox(QtGui.QMessageBox):
def __init__(self, timeout=3, parent=None):
super(TimerMessageBox, self).__init__(parent)
self.setWindowTitle("wait")
self.time_to_wait = timeout
self.setText("wait (closing automatically in {0} secondes.)".format(timeout))
self.setStandardButtons(QtGui.QMessageBox.NoButton)
self.timer = QtCore.QTimer(self)
self.timer.setInterval(1000)
self.timer.timeout.connect(self.changeContent)
self.timer.start()

def changeContent(self):
self.setText("wait (closing automatically in {0} secondes.)".format(self.time_to_wait))
self.time_to_wait -= 1
if self.time_to_wait <= 0:
self.close()

def closeEvent(self, event):
self.timer.stop()
event.accept()

class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
btn = QtGui.QPushButton('Button', self)
btn.resize(btn.sizeHint())
btn.move(50, 50)
self.setWindowTitle('Example')
btn.clicked.connect(self.warning)

def warning(self):
messagebox = TimerMessageBox(5, self)
messagebox.exec_()

def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

if __name__ == '__main__':
main()

Default DialogResult for MessageBox after timeout

I agree with the other comments, that you should just make your own message box form.

That said, if you still want to use that other approach, you should be able to get it to work by sending an appropriate message to the dialog that is recognized; e.g. Alt-I for "ignore".

Here's a version of the code you posted that does that:

class AutoClosingMessageBox
{
System.Threading.Timer _timeoutTimer;
string _caption;
static DialogResult? dialogResult_ = null;

private AutoClosingMessageBox(string text, string caption, int timeout, MessageBoxButtons msbb)
{
_caption = caption;
_timeoutTimer = new System.Threading.Timer(OnTimerElapsed,
null, timeout, System.Threading.Timeout.Infinite);

dialogResult_ = MessageBox.Show(text, caption, msbb);
}

public static DialogResult? Show(string text, string caption, int timeout, MessageBoxButtons efb)
{
new AutoClosingMessageBox(text, caption, timeout, efb);
return dialogResult_;
}

void OnTimerElapsed(object state)
{
IntPtr mbWnd = FindWindow("#32770", _caption);
if (mbWnd != IntPtr.Zero)
{
SetForegroundWindow(mbWnd);
SendKeys.SendWait("%I");
_timeoutTimer.Dispose();
}

dialogResult_ = null;
}

[DllImport("user32.dll", SetLastError = true)]
extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
extern static IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
extern static bool SetForegroundWindow(IntPtr hwnd);

}

The SendKeys class only works on the current active window, so I included a call to SetForegroundWindow() to ensure the keys get to the correct window.

Of course, the above hard-codes the Alt-I required. If you wanted a more general solution, you might include a dictionary that maps the MessageBoxButtons value to the appropriate SendKeys string needed to dismiss that dialog and/or have the caller provide that information (either force them to provide the actual SendKeys string or (nicer) have them pass an enum value indicating which button they want to use to dismiss the dialog and then have your implementation map that to the appropriate string.



Related Topics



Leave a reply



Submit