VC创建定时关闭的MessageBox

简介: 1、第一种方法:用微软提供的官方文档From : http://support.microsoft.com/kb/181934/en-us/ Generally, when you want to display a message box for a limited amount ...

1、第一种方法:用微软提供的官方文档

From : http://support.microsoft.com/kb/181934/en-us/

Generally, when you want to display a message box for a limited amount of time, you must implement a regular dialog box that closes itself after a specified amount of time. The problem with this method is that you lose the standard message box functionality that Windows provides.

The following example shows how to use the MessageBox function to create a message box that automatically closes after a specified amount of time. Note the following about the example:

  • The example uses a Windows timer that fires an event after the specified amount of time has elapsed.
  • When the timer event occurs, the PostQuitMessage API is used to break out of the modal message loop that MessageBox uses.
  • Note The WM_QUIT message must be removed from the message queue to prevent it from being retrieved in the main message queue.

  1. /***********************************************************************
  2.    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3.    ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4.    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5.    PARTICULAR PURPOSE.
  6.    Copyright 1998 Microsoft Corporation.  All Rights Reserved.
  7. ***********************************************************************/ 
  8.  
  9. /***********************************************************************
  10. *
  11. *  MsgBox.c
  12. *
  13. *  Abstract:
  14. *
  15. *      Sample program to demonstrate how a program can display a
  16. *      timed message box.
  17. *
  18. ***********************************************************************/ 
  19.  
  20. #define STRICT 
  21. #include <windows.h> 
  22.  
  23. /***********************************************************************
  24. *
  25. *      Overview
  26. *
  27. *      The key to creating a timed message box is exiting the dialog
  28. *      box message loop internal to the message box. Because the
  29. *      message loop for a message box is part of USER, you cannot
  30. *      modify the message loop without using hooks and other such methods.
  31. *
  32. *
  33. *      However, all message loops exit when they receive a
  34. *      WM_QUIT message. Additionally, if a nested message loop
  35. *      receives a WM_QUIT message, the nested message loop must break
  36. *      the loop and then re-post the quit message so that the next
  37. *      outer layer can process it.
  38. *
  39. *      Therefore, you can make the nested message loop exit by
  40. *      calling the PostQuitMessage function. The nested message loop will
  41. *      clean up and post a new quit message. When the MessageBox
  42. *      returns, you peek to see if there is a quit message. If so,
  43. *      it means that the message loop was abnormally terminated.
  44. *      You also consume the WM_QUIT message instead of re-posting it
  45. *      so that the application continues to run.
  46. *
  47. *      Essentially, you have "tricked" the nested message loop into
  48. *      determining that the application is terminating. When the quit message
  49. *      returns, you consume the quit message. This method effectively cancels
  50. *      the fake quit message that you generated.
  51. *
  52. ***********************************************************************/ 
  53.  
  54. /***********************************************************************
  55. *
  56. *  Global variables
  57. *
  58. ***********************************************************************/ 
  59.  
  60. HWND g_hwndTimedOwner; 
  61. BOOL g_bTimedOut; 
  62.  
  63. /***********************************************************************
  64. *
  65. *  MessageBoxTimer
  66. *
  67. *      The timer callback function that posts the fake quit message.
  68. *      This function causes the message box to exit because the message box
  69. *      has determined that the application is exiting.
  70. *
  71. ***********************************************************************/ 
  72. void CALLBACK MessageBoxTimer(HWND hwnd,  
  73.                               UINT uiMsg,  
  74.                               UINT idEvent,  
  75.                               DWORD dwTime) 
  76.    g_bTimedOut = TRUE; 
  77.    if (g_hwndTimedOwner) 
  78.       EnableWindow(g_hwndTimedOwner, TRUE); 
  79.    PostQuitMessage(0); 
  80.  
  81. /***********************************************************************
  82. *
  83. *  TimedMessageBox
  84. *
  85. *      The same as the standard MessageBox, except that TimedMessageBox
  86. *      also accepts a timeout. If the user does not respond within the
  87. *      specified timeout, the value 0 is returned instead of one of the
  88. *      ID* values.
  89. *
  90. ***********************************************************************/ 
  91. int TimedMessageBox(HWND hwndOwner, 
  92.                     LPCTSTR pszMessage, 
  93.                     LPCTSTR pszTitle, 
  94.                     UINT flags, 
  95.                     DWORD dwTimeout) 
  96.    UINT idTimer; 
  97.    int iResult; 
  98.  
  99.    g_hwndTimedOwner = NULL; 
  100.    g_bTimedOut = FALSE; 
  101.  
  102.    if (hwndOwner && IsWindowEnabled(hwndOwner)) 
  103.       g_hwndTimedOwner = hwndOwner; 
  104.  
  105.    // Set a timer to dismiss the message box. 
  106.    idTimer = SetTimer(NULL, 0, dwTimeout, (TIMERPROC)MessageBoxTimer); 
  107.  
  108.    iResult = MessageBox(hwndOwner, pszMessage, pszTitle, flags); 
  109.  
  110.    // Finished with the timer. 
  111.    KillTimer(NULL, idTimer); 
  112.  
  113.    // See if there is a WM_QUIT message in the queue if we timed out. 
  114.    // Eat the message so we do not quit the whole application. 
  115.    if (g_bTimedOut) 
  116.    { 
  117.       MSG msg; 
  118.       PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE); 
  119.       iResult = -1; 
  120.    } 
  121.  
  122.    return iResult; 
  123.  
  124. /***********************************************************************
  125. *
  126. *  WinMain
  127. *
  128. *      Program entry point. Demonstrate TimedMessageBox().
  129. *
  130. ***********************************************************************/ 
  131. int WINAPI WinMain(HINSTANCE hinst, 
  132.                    HINSTANCE hinstPrev, 
  133.                    LPSTR pszCmdLine, 
  134.                    int nCmdShow) 
  135.  
  136.       UINT uiResult; 
  137.  
  138.       // Ask the user a question. Give the user five seconds to 
  139.       // answer the question. 
  140.       uiResult = TimedMessageBox(NULL,  
  141.                                  "Does a triangle have three sides?"
  142.                                  "Quiz",  
  143.                                  MB_YESNO, 
  144.                                  // NULL first parameter is important. 
  145.                                  5000);  
  146.  
  147.       switch (uiResult) { 
  148.       case IDYES: 
  149.          MessageBox(NULL,  
  150.                      "That's right!",  
  151.                      "Result",  
  152.                      MB_OK); 
  153.          break
  154.  
  155.       case IDNO: 
  156.          MessageBox(NULL,  
  157.                      "Believe it or not, triangles " 
  158.                      "really do have three sides.",  
  159.                      "Result"
  160.                      MB_OK); 
  161.          break
  162.  
  163.       case -1: 
  164.          MessageBox(NULL,  
  165.                      "I sensed some hesitation there.  " 
  166.                      "The correct answer is Yes.",  
  167.                      "Result",  
  168.                      MB_OK); 
  169.          break
  170.       } 
  171.  
  172.       return 0; 
/*********************************************************************** THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. Copyright 1998 Microsoft Corporation. All Rights Reserved. ***********************************************************************/ /*********************************************************************** * * MsgBox.c * * Abstract: * * Sample program to demonstrate how a program can display a * timed message box. * ***********************************************************************/ #define STRICT #include <windows.h> /*********************************************************************** * * Overview * * The key to creating a timed message box is exiting the dialog * box message loop internal to the message box. Because the * message loop for a message box is part of USER, you cannot * modify the message loop without using hooks and other such methods. * * * However, all message loops exit when they receive a * WM_QUIT message. Additionally, if a nested message loop * receives a WM_QUIT message, the nested message loop must break * the loop and then re-post the quit message so that the next * outer layer can process it. * * Therefore, you can make the nested message loop exit by * calling the PostQuitMessage function. The nested message loop will * clean up and post a new quit message. When the MessageBox * returns, you peek to see if there is a quit message. If so, * it means that the message loop was abnormally terminated. * You also consume the WM_QUIT message instead of re-posting it * so that the application continues to run. * * Essentially, you have "tricked" the nested message loop into * determining that the application is terminating. When the quit message * returns, you consume the quit message. This method effectively cancels * the fake quit message that you generated. * ***********************************************************************/ /*********************************************************************** * * Global variables * ***********************************************************************/ HWND g_hwndTimedOwner; BOOL g_bTimedOut; /*********************************************************************** * * MessageBoxTimer * * The timer callback function that posts the fake quit message. * This function causes the message box to exit because the message box * has determined that the application is exiting. * ***********************************************************************/ void CALLBACK MessageBoxTimer(HWND hwnd, UINT uiMsg, UINT idEvent, DWORD dwTime) { g_bTimedOut = TRUE; if (g_hwndTimedOwner) EnableWindow(g_hwndTimedOwner, TRUE); PostQuitMessage(0); } /*********************************************************************** * * TimedMessageBox * * The same as the standard MessageBox, except that TimedMessageBox * also accepts a timeout. If the user does not respond within the * specified timeout, the value 0 is returned instead of one of the * ID* values. * ***********************************************************************/ int TimedMessageBox(HWND hwndOwner, LPCTSTR pszMessage, LPCTSTR pszTitle, UINT flags, DWORD dwTimeout) { UINT idTimer; int iResult; g_hwndTimedOwner = NULL; g_bTimedOut = FALSE; if (hwndOwner && IsWindowEnabled(hwndOwner)) g_hwndTimedOwner = hwndOwner; // Set a timer to dismiss the message box. idTimer = SetTimer(NULL, 0, dwTimeout, (TIMERPROC)MessageBoxTimer); iResult = MessageBox(hwndOwner, pszMessage, pszTitle, flags); // Finished with the timer. KillTimer(NULL, idTimer); // See if there is a WM_QUIT message in the queue if we timed out. // Eat the message so we do not quit the whole application. if (g_bTimedOut) { MSG msg; PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE); iResult = -1; } return iResult; } /*********************************************************************** * * WinMain * * Program entry point. Demonstrate TimedMessageBox(). * ***********************************************************************/ int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR pszCmdLine, int nCmdShow) { UINT uiResult; // Ask the user a question. Give the user five seconds to // answer the question. uiResult = TimedMessageBox(NULL, "Does a triangle have three sides?", "Quiz", MB_YESNO, // NULL first parameter is important. 5000); switch (uiResult) { case IDYES: MessageBox(NULL, "That's right!", "Result", MB_OK); break; case IDNO: MessageBox(NULL, "Believe it or not, triangles " "really do have three sides.", "Result", MB_OK); break; case -1: MessageBox(NULL, "I sensed some hesitation there. " "The correct answer is Yes.", "Result", MB_OK); break; } return 0; }

 

2、第二种方法:使用手动创建的对话框

新建一个对话框,添加一个静态文本控件(显示内容),如下图:

定时自动关闭MessageBox

将Static控件关联CString类型变量为m_strText、并为该对话框添加新类CMSGBox,再添加WM_TIMER消息:

  1. void CMSGBox::OnTimer(UINT nIDEvent)  
  2.     // TODO: Add your message handler code here and/or call default 
  3.     if(1 == nIDEvent) 
  4.     { 
  5.         KillTimer(1); 
  6.         EndDialog(IDOK); 
  7.     } 
  8.     CDialog::OnTimer(nIDEvent); 
void CMSGBox::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(1 == nIDEvent) { KillTimer(1); EndDialog(IDOK); } CDialog::OnTimer(nIDEvent); }

 

PS:我觉得此处代码可以改成这样,就可以设定多个定时器(我可没测试

  1. void CMSGBox::OnTimer(UINT nIDEvent)  
  2.     // TODO: Add your message handler code here and/or call default 
  3.     if(nIDEvent>=1) 
  4.     { 
  5.         EndDialog(IDOK); 
  6.     } 
  7.     CDialog::OnTimer(nIDEvent); 
void CMSGBox::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(nIDEvent>=1) { EndDialog(IDOK); } CDialog::OnTimer(nIDEvent); }

 

引入头文件,在主对话框中调用代码:

  1. void CMFCDlg::OnOK()  
  2.     // TODO: Add extra validation here 
  3.     CMSGBox *dlg = new CMSGBox(); 
  4.     dlg->Create(IDD_MSGBOX,NULL); 
  5.     dlg->SetWindowText(_T("提示")); 
  6.     dlg->m_strText = _T("3秒后自动关闭..."); 
  7.     dlg->UpdateData(FALSE); 
  8.     dlg->SetTimer(1,3000,NULL); 
  9.     dlg->CenterWindow(); 
  10.     dlg->ShowWindow(SW_SHOWNORMAL); 
  11.     dlg->UpdateWindow(); 
  12.     dlg = NULL; 
void CMFCDlg::OnOK() { // TODO: Add extra validation here CMSGBox *dlg = new CMSGBox(); dlg->Create(IDD_MSGBOX,NULL); dlg->SetWindowText(_T("提示")); dlg->m_strText = _T("3秒后自动关闭..."); dlg->UpdateData(FALSE); dlg->SetTimer(1,3000,NULL); dlg->CenterWindow(); dlg->ShowWindow(SW_SHOWNORMAL); dlg->UpdateWindow(); dlg = NULL; }

 

运行效果如下:

效果

这种山寨版的效果,确实看起来有些猥琐....

3、源码下载(SDK、MFC共两种)

     官方下载:http://download.csdn.net/source/1808835

     网盘下载:http://www.rayfile.com/files/c07e4600-ce99-11de-82ad-0014221b798a/

 

from:

http://blog.csdn.net/wangningyu/article/details/4798538
目录
相关文章
Qt窗口关闭和应用程序停止是否调用析构函数的一些说明
Qt窗口关闭和应用程序停止是否调用析构函数的一些说明
Qt窗口关闭和应用程序停止是否调用析构函数的一些说明
|
Windows
教你彻底关闭win10的自动更新
最近的windows10更新是越来越可怕了。不仅常驻后台偷吃资源和网络,还不让关闭。
3190 0
教你彻底关闭win10的自动更新
|
Windows
MFC中修改默认启动对话框方法
// CMyAppEApp 初始化BOOL CMyAppEApp::InitInstance(){// 如果一个运行在 Windows XP 上的应用程序清单指定要// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,//则需要 InitCommonControls()。
1366 0
|
Windows
Win10如何关闭自动更新服务
原文:Win10如何关闭自动更新服务 第一步: 小娜搜索“gpedit.msc”,进入本地计算机策略设置。 第二步: 找到策略位置:本地计算机策略-计算机配置-管理模板-Windows 组件-Windows 更新-配置自动更新 第三步: 双击打开“配置自动更新”,设置为“已禁用”状态,确定退出即可。
932 0
|
安全 数据安全/隐私保护 Windows
|
安全
winform关闭窗口 取消关闭操作
医药遇到一个bug就是 关闭窗口 弹出后点击取消 程序还是结束了 于是百度了一下代码 粘贴上就可以取消 ,然后继续对程序的操作。
941 0