Home > Blockchain >  GetSystemMetrics(SM_CYSCREEN); | Gives wrong value| but GetSystemMetrics(SM_CXSCREEN); gives correct
GetSystemMetrics(SM_CYSCREEN); | Gives wrong value| but GetSystemMetrics(SM_CXSCREEN); gives correct

Time:03-14

I have a problem with GetSystemMetrics(SM_CYSCREEN); – the height this function returns is random each time I run the program but the width function, GetSystemMetrics(SM_CXSCREEN); gives the correct value.

Here is my code:

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

int  MessageBoxPrintf(const wchar_t * szCaption, const wchar_t * szFormat, ...) {

    wchar_t buffer[1024];
    va_list v1;
    va_start(v1, szFormat);
    wchar_t* c = va_arg(v1, wchar_t*);
    wsprintf(buffer, szFormat, c); //gives formated output to buffer
    va_end(v1);
    return MessageBox(NULL, buffer, szCaption, 0);      
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
    int cxScreen, cyScreen;
    cxScreen = GetSystemMetrics(SM_CXSCREEN);  
    cyScreen = GetSystemMetrics(SM_CYSCREEN);
    MessageBoxPrintf(TEXT("ScreenRes"), TEXT("The screen is %i pixels wide by %i pixels high"), cxScreen, cyScreen);
    return 0;
}

This program basically just is a Format string Message box with the WinAPI and C .

CodePudding user response:

The code you have posted shows (almost certainly) undefined behaviour, because of the incorrect way you handle the variadic argument list in your MessageBoxPrintf function.

In the wchar_t* c = va_arg(v1, wchar_t*); line, you are 'assuming' a single wchar_t argument – but, in your main function, you are passing two int arguments. This may or not produce meaningful results; – in your case, it seems that the first int argument is correctly interpreted by the subsequent call to wsprintf but the second is somewhat "lost in translation" (manifesting the aforementioned undefined behaviour).

To correctly handle that variadic argument list, you need to extract it, then pass it unprocessed to the vswprintf function, which can then properly interpret that argument list:

int MessageBoxPrintf(const wchar_t* szCaption, const wchar_t* szFormat, ...)
{
    wchar_t buffer[1024];
    va_list v1;
    va_start(v1, szFormat);
    vswprintf(buffer, 1024, szFormat, v1);
    va_end(v1);
    return MessageBox(NULL, buffer, szCaption, 0);
}
  • Related