Search code examples
winapiunicodeprintfmessagebox

I cant print a number inside a formatted MessageBox


The following code does not work as it should. %i does not connect with its variable.

#include<Windows.h>
#include<stdio.h>
#include<tchar.h>

/*       SCREENSIZE.C

    This project contains the code that Programming Windows
    book by Charles Petzold is using.

*/


int cdecl MessageBoxPrintfW(TCHAR *msgBoxTitle, TCHAR *msgBoxFormat, ...)
{
    //define buffer
    TCHAR msgBoxBuffer[1024];

    //define iteration pointer
    va_list argPtr;

    //start iteration
    va_start(argPtr, msgBoxFormat);

    /*int _vsnwprintf_s(
    wchar_t *const _Buffer,
    const size_t _BufferCount,
    const size_t _MaxCount,
    const wchar_t *const _Format,
    va_list _ArgList)
    */

    _vsntprintf_s(msgBoxBuffer, sizeof(msgBoxBuffer) / sizeof(TCHAR), (sizeof(msgBoxBuffer) / sizeof(TCHAR)) - 1, msgBoxFormat, argPtr);

    //end iteration 
    va_end(argPtr);

    //Use return type to pass preconfigured MessageBox(0,"Text","Title",MB_OKCANCEL);
    //Whe we use L before a string example: L"text" it is considered UNICODE format.

    return(MessageBox(0, msgBoxFormat, msgBoxTitle, MB_OKCANCEL));
}

int WINAPI WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR pCmdLine,
    int iCmdShow)
{
    int cxScreen, cyScreen;
    cxScreen = GetSystemMetrics(SM_CXSCREEN);
    cyScreen = GetSystemMetrics(SM_CYSCREEN);

    MessageBoxPrintfW(TEXT ("SCREENSIZE"), TEXT("The screen is %i pixels wide by %i pixels high."), cxScreen, cyScreen);

    return(0);
}

Why does this happen?

Below is the output that I get:

output


Solution

  • TCHAR msgBoxBuffer[1024];
    _vsntprintf_s(msgBoxBuffer,...
    ...
    return(MessageBox(0, msgBoxFormat, msgBoxTitle, MB_OKCANCEL));
    

    Note that you are writting to msgBoxBuffer, but you never use msgBoxBuffer. So your message box doesn't change anything. Try the following instead:

    int MessageBoxPrintfW(const TCHAR *msgBoxTitle, const TCHAR* msgBoxFormat, ...)
    {
        va_list args;
        va_start(args, msgBoxFormat);
    
        int len = _vsctprintf(msgBoxFormat, args) + 1; // add terminating '\0'
        TCHAR *buf = new TCHAR[len];
        _vstprintf_s(buf, len, msgBoxFormat, args);
    
        int result = MessageBox(0, buf, msgBoxTitle, MB_OKCANCEL);
    
        delete[]buf;
    
        return result;
    }
    

    For C version use malloc(len * sizeof(TCHAR)) instead of new, and use free instead of delete[]