1

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++.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Mr. CLOWN
  • 67
  • 5
  • pls tell me how to make the function GetSystemMetrics(SM_CYSCREEN); return the correct value – Mr. CLOWN Mar 13 '22 at 16:20
  • i am giving wchar_t * because i need strings on which i will put placeholders %i and then put the int resolutions of screen obtained from getsystemmetrics() – Mr. CLOWN Mar 13 '22 at 16:49
  • One more thing i am beginner , can u clear one more doubt , why and when and where we use TCHAR . I know its generic way so that we dont have problem with ASI and UTF-16 but in its definition it also says that UNICODE should be defined first , so my question in that when import window.h file does that #if UNICODE .... comes automatically so then i can use TCHAR ? – Mr. CLOWN Mar 13 '22 at 16:52
  • If you *know* you want to use `wchar_t` throughout, then just skip all `TCHAR` references and headers, and use `#include ` instead of the `tchar.h` header. – Adrian Mole Mar 13 '22 at 16:57
  • okay , but pls can u tell me in easy words when should i use TCHAR and if possible give a reference website to understand TCHAR pls (other than msdn reference) – Mr. CLOWN Mar 13 '22 at 16:59
  • Google is your friend! :) But also, here: https://stackoverflow.com/q/40887567/10871073 Or, even better, this one: https://stackoverflow.com/q/234365/10871073 – Adrian Mole Mar 13 '22 at 17:00

1 Answers1

2

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);
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83