몇 초 후 MessageBoxClose
메시지를 표시하기 위해 MessageBox를 표시하는 Windows Forms 응용 프로그램 VS2010 C #이 있습니다.
괜찮아요 버튼이 있는데, 만약 그들이 떠나면 시간 초과를하고 5 초 후에 메시지 상자를 닫고 메시지 상자를 자동으로 닫고 싶습니다.
사용자 지정 MessageBox (Form에서 상 속됨) 또는 다른 리포터 Forms가 흥미로울 것입니다.
제안 된 제안이나 샘플이 있습니까?
업데이트 :
WPF의 경우
C #에서 자동으로 메시지 상자 닫기
Custom 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
Scrollable MessageBox C #의 스크롤 가능한
MessageBox
예외 기자
https://stackoverflow.com/questions/49224/good-crash-reporting-library-in-c-sharp
http://www.codeproject.com/Articles/6895/A-Reusable-Flexible-Error-Reporting-Framework
해결책 :
아마도 Form을 사용하지 않고 다음 답변이 좋은 해결책이라고 생각합니다.
https://stackoverflow.com/a/14522902/206730
https://stackoverflow.com/a/14522952/206730
다음 접근 방식을 시도하십시오.
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 가지 에서 );
-새 팩토리 () API는 MessageBox 표시에 대한 모든 권한을 제공합니다.
WinForms에서 작동하는 솔루션 :
var w = new Form() { Size = new Size(0, 0) };
Task.Delay(TimeSpan.FromSeconds(10))
.ContinueWith((t) => w.Close(), TaskScheduler.FromCurrentSynchronizationContext());
MessageBox.Show(w, message, caption);
메시지 상자를 소유 한 양식을 닫는 효과에 따라 상자도 닫습니다.
Windows Forms 컨트롤에는 필요한 것이 있습니다. 을 사용 TaskScheduler.FromCurrentSynchronizationContext()
하면 위의 예제 코드가 실행된다고 가정합니다. 코드가 스레드 풀 (예 : 타이머 콜백) 또는 작업 풀 (예 : 기본 매개 변수로 생성 TaskFactory.StartNew
되거나 Task.Run
기본 매개 변수로 생성 된 작업)에서 스레드에서 실행되는 경우 예제가 제대로 작동하지 않습니다 .
AppActivate!
문헌을 조금 참고 헷갈 리게해도 괜찮다-plane Microsoft.Visualbasic,
이 방법을 아주 짧은 방법으로 포함 하고 사용할 수 있습니다 .
MessageBox 표시
(new System.Threading.Thread(CloseIt)).Start();
MessageBox.Show("HI");
CloseIt 기능 :
public void CloseIt()
{
System.Threading.Thread.Sleep(2000);
Microsoft.VisualBasic.Interaction.AppActivate(
System.Diagnostics.Process.GetCurrentProcess().Id);
System.Windows.Forms.SendKeys.SendWait(" ");
}
이제 손을 씻으세요!
System.Windows.MessageBox.Show () 메소드에는 소유자 Window를 첫 번째 매개 변수로 사용하는 오버로드가 있습니다. 표시 않는 소유자 창을 만든 시간 후에 닫으면 메시지 상자도 닫힙니다.
Window owner = CreateAutoCloseWindow(dialogTimeout);
MessageBoxResult result = MessageBox.Show(owner, ...
여태대로 그런대로 잘됐다. 하지만 UI 표준가 메시지 상자에 의해 차단되고 프로그램에서 UI 컨트롤에 액세스 할 수없는 경우 어떻게 창을 닫을까요? 대답은-소유자 창 핸들에 WM_CLOSE 메시지를 메시지를 것입니다.
Window CreateAutoCloseWindow(TimeSpan timeout)
{
Window window = new Window()
{
WindowStyle = WindowStyle.None,
WindowState = System.Windows.WindowState.Maximized,
Background = System.Windows.Media.Brushes.Transparent,
AllowsTransparency = true,
ShowInTaskbar = false,
ShowActivated = true,
Topmost = true
};
window.Show();
IntPtr handle = new WindowInteropHelper(window).Handle;
Task.Delay((int)timeout.TotalMilliseconds).ContinueWith(
t => NativeMethods.SendMessage(handle, 0x10 /*WM_CLOSE*/, IntPtr.Zero, IntPtr.Zero));
return window;
}
다음은 SendMessage Windows API 메서드에 대한 가져 오기입니다.
static class NativeMethods
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
}
이를 시도해 볼 수 있습니다.
[DllImport("user32.dll", EntryPoint="FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.Dll")]
static extern int PostMessage(IntPtr hWnd, UInt32 msg, int wParam, int lParam);
private const UInt32 WM_CLOSE = 0x0010;
public void ShowAutoClosingMessageBox(string message, string caption)
{
var timer = new System.Timers.Timer(5000) { AutoReset = false };
timer.Elapsed += delegate
{
IntPtr hWnd = FindWindowByCaption(IntPtr.Zero, caption);
if (hWnd.ToInt32() != 0) PostMessage(hWnd, WM_CLOSE, 0, 0);
};
timer.Enabled = true;
MessageBox.Show(message, caption);
}
CodeProject의 RogerB 는이 답변에 대한 가장 솔루션 중 하나를 가지고 있고, 그는 '04 년에 그렇게했습니다.
기본적으로 여기에서 그의 프로젝트로 이동하여 CS 파일을 다운로드합니다 . 링크가 죽는 경우를 대비하여 여기에 백업 요점이 있습니다. 프로젝트에 CS 파일을 추가하거나 원하는 경우 코드를 복사 / 붙여 넣기하십시오.
그런 다음 전환하기 만하면됩니다.
DialogResult result = MessageBox.Show("Text","Title", MessageBoxButtons.CHOICE)
...에
DialogResult result = MessageBoxEx.Show("Text","Title", MessageBoxButtons.CHOICE, timer_ms)
그리고 당신은 갈 수 있습니다.
CodeProject의 프로젝트 사용 가능한이 여기 이 functuanility을 제공합니다.
SO 및 기타 보드의 많은 스레드를 따라 가면 일반 MessageBox로는 수행 할 수 없습니다.
편집하다:
조금 음 .. 네 ..
타이머를 사용하고 MessageBox가 나타나면 시작하십시오. MessageBox가 OK 버튼 만 듣는 경우 (하나만 가능) OnTick-Event를 사용하여 ESC-Press를 에뮬레이트 한 SendKeys.Send("{ESC}");
다음 타이머를 중지합니다.
DMitryG의 코드 "기본의 반환 값 가져 오기 MessageBox
"에는 버그가 있으므로 timerResult는 실제로 올바르게 반환되지 않습니다 ( MessageBox.Show
호출은 AFTER OnTimerElapsed
완료 후 반환 ). 내 수정 사항은 다음과 같습니다.
public class TimedMessageBox {
System.Threading.Timer _timeoutTimer;
string _caption;
DialogResult _result;
DialogResult _timerResult;
bool timedOut = false;
TimedMessageBox(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);
if (timedOut) _result = _timerResult;
}
public static DialogResult Show(string text, string caption, int timeout, MessageBoxButtons buttons = MessageBoxButtons.OK, DialogResult timerResult = DialogResult.None) {
return new TimedMessageBox(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();
timedOut = true;
}
const int WM_CLOSE = 0x0010;
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
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);
}
Vb.net 라이브러리에는이를 위해 상호 작용 클래스를 사용하는 간단한 솔루션이 있습니다.
void MsgPopup(string text, string title, int secs = 3)
{
dynamic intr = Microsoft.VisualBasic.Interaction.CreateObject("WScript.Shell");
intr.Popup(text, secs, title);
}
bool MsgPopupYesNo(string text, string title, int secs = 3)
{
dynamic intr = Microsoft.VisualBasic.Interaction.CreateObject("WScript.Shell");
int answer = intr.Popup(text, secs, title, (int)Microsoft.VisualBasic.Constants.vbYesNo + (int)Microsoft.VisualBasic.Constants.vbQuestion);
return (answer == 6);
}
user32.dll에 MessageBoxTimeout ()이라는 문서화되지 않은 API가 있지만 Windows XP 이상이 필요합니다.
EndDialog
보내는 대신 사용 WM_CLOSE
:
[DllImport("user32.dll")]
public static extern int EndDialog(IntPtr hDlg, IntPtr nResult);
이렇게 했어요
var owner = new Form { TopMost = true };
Task.Delay(30000).ContinueWith(t => {
owner.Invoke(new Action(()=>
{
if (!owner.IsDisposed)
{
owner.Close();
}
}));
});
var dialogRes = MessageBox.Show(owner, msg, "Info", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
참고 URL : https://stackoverflow.com/questions/14522540/close-a-messagebox-after-several-seconds
'ProgramingTip' 카테고리의 다른 글
데이터베이스에서 h : selectOneMenu 옵션을 채우는 방법은 무엇입니까? (0) | 2020.11.03 |
---|---|
Coffeescript의 조건부 연산자 (0) | 2020.11.03 |
ProGuard : 참조 된 클래스 com.google.android.gms.R을 사용할 수 없습니다. (0) | 2020.11.03 |
pandas.qcut과 pandas.cut의 차이점은 무엇입니까? (0) | 2020.11.03 |
Visual Studio Code 상태 표시 줄 색상 (0) | 2020.11.03 |