Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

MessageBoxTimeout API

0.00/5 (No votes)
6 Aug 2004 1  
An article on using the non documented MessageBoxTimeout API.

Introduction

For reasons unknown, Microsoft has never documented the MessageBoxTimeout API located in user32.dll, so here it is for those seeking a Message Box that times out and auto closes if the user does not respond to it first.

Using the code

The code is usable for both UNICODE and MBCS, simply add the following to a source (cpp) file:

#include <windows.h>

#include <tchar.h>


//Functions & other definitions required-->

typedef int (__stdcall *MSGBOXAAPI)(IN HWND hWnd, 
        IN LPCSTR lpText, IN LPCSTR lpCaption, 
        IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);
typedef int (__stdcall *MSGBOXWAPI)(IN HWND hWnd, 
        IN LPCWSTR lpText, IN LPCWSTR lpCaption, 
        IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);

int MessageBoxTimeoutA(IN HWND hWnd, IN LPCSTR lpText, 
    IN LPCSTR lpCaption, IN UINT uType, 
    IN WORD wLanguageId, IN DWORD dwMilliseconds);
int MessageBoxTimeoutW(IN HWND hWnd, IN LPCWSTR lpText, 
    IN LPCWSTR lpCaption, IN UINT uType, 
    IN WORD wLanguageId, IN DWORD dwMilliseconds);

#ifdef UNICODE
    #define MessageBoxTimeout MessageBoxTimeoutW
#else
    #define MessageBoxTimeout MessageBoxTimeoutA
#endif 

#define MB_TIMEDOUT 32000

int MessageBoxTimeoutA(HWND hWnd, LPCSTR lpText, 
    LPCSTR lpCaption, UINT uType, WORD wLanguageId, 
    DWORD dwMilliseconds)
{
    static MSGBOXAAPI MsgBoxTOA = NULL;

    if (!MsgBoxTOA)
    {
        HMODULE hUser32 = GetModuleHandle(_T("user32.dll"));
        if (hUser32)
        {
            MsgBoxTOA = (MSGBOXAAPI)GetProcAddress(hUser32, 
                                      "MessageBoxTimeoutA");
            //fall through to 'if (MsgBoxTOA)...'

        }
        else
        {
            //stuff happened, add code to handle it here 

            //(possibly just call MessageBox())

            return 0;
        }
    }

    if (MsgBoxTOA)
    {
        return MsgBoxTOA(hWnd, lpText, lpCaption, 
              uType, wLanguageId, dwMilliseconds);
    }

    return 0;
}

int MessageBoxTimeoutW(HWND hWnd, LPCWSTR lpText, 
    LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD dwMilliseconds)
{
    static MSGBOXWAPI MsgBoxTOW = NULL;

    if (!MsgBoxTOW)
    {
        HMODULE hUser32 = GetModuleHandle(_T("user32.dll"));
        if (hUser32)
        {
            MsgBoxTOW = (MSGBOXWAPI)GetProcAddress(hUser32, 
                                      "MessageBoxTimeoutW");
            //fall through to 'if (MsgBoxTOW)...'

        }
        else
        {
            //stuff happened, add code to handle it here 

            //(possibly just call MessageBox())

            return 0;
        }
    }

    if (MsgBoxTOW)
    {
        return MsgBoxTOW(hWnd, lpText, lpCaption, 
               uType, wLanguageId, dwMilliseconds);
    }

    return 0;
}
//End required definitions <--

Call the function as follows:

//you must load user32.dll before calling the function

HMODULE hUser32 = LoadLibrary(_T("user32.dll"));
    
if (hUser32)
{
    int iRet = 0;
    UINT uiFlags = MB_OK|MB_SETFOREGROUND|MB_SYSTEMMODAL|MB_ICONINFORMATION;
    
    iRet = MessageBoxTimeout(NULL, _T("Test a timeout of 2 seconds."), 
                      _T("MessageBoxTimeout Test"), uiFlags, 0, 2000);
    //iRet will = 1


    uiFlags = MB_YESNO|MB_SETFOREGROUND|MB_SYSTEMMODAL|MB_ICONINFORMATION;

    iRet = MessageBoxTimeout(NULL, _T("Test a timeout of 5 seconds."), 
                      _T("MessageBoxTimeout Test"), uiFlags, 0, 5000);
    //iRet will = MB_TIMEDOUT if no buttons pressed, button values otherwise

        
    //only unload user32.dll when you have no further need 

    //for the MessageBoxTimeout function

    FreeLibrary(hUser32);
}

The function will return an integer value of either a MB_TIMEDOUT value indicating the timeout period was reached and the Message Box auto closed, or a value representing the button the user clicked. Note that when a Message Box with only an OK button (MB_OK Flag) is used, the return value is always 1.

The sample code provided is for Visual Studio .NET 2003 but can easily be used in other compilers.

Points of Interest

You may be thinking what reassurances exist that someday Microsoft may remove this function. In all honesty, there are none, however, it's interesting to note that internally, all the documented MessageBox* functions call the MessageBoxTimeout API and simply pass 0xFFFFFFFF as the timeout period (a very long time), so the probability of it being removed is minimal.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here