Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17


Attempt to call XVIRTUALSCREEN yielding build error

Posted on 2006-06-24
Medium Priority
Last Modified: 2012-06-21
In my programming, I realized I need to start polling SM_CXVIRTUALSCREEN rather than SM_CXSCREEN in order to support users with multiple monitors.
However, when I tried to GetSystemMetrics (SM_CYVIRTUALSCREEN)) I got a build error and took advice from the Web that I needed to add multimon.h to my code.
So I got that file and added it to my source folder, and added
#include "multimon.h"
at the top of the source file that includes the GetSystemMetrics call.
And I added multimon.h to the project using Project | Add To Project | Files .
However when I try to build I get
"error LNK2001: unresolved external symbol _xGetSystemMetrics@4"

Question by:reggieperrin
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 2
  • +1
LVL 48

Expert Comment

ID: 16977935
What build error exactly did you get when added GetSystemMetrics (SM_CYVIRTUALSCREEN) call?
Notice that SM_CXVIRTUALSCREEN and SM_CYVIRTUALSCREEN constants are not supported in Win95 and NT. For every function and definition which is not supported in all operating systems, refer to the following article:

Author Comment

ID: 16978534
"error C2065: 'SM_CYVIRTUALSCREEN' : undeclared identifier"

PS.  Thank you for pointing out the 95/NT issue. Does that mean that once I get multimon.h running properly, I will have to do the following?

if ((ver.dwPlatformId==VER_PLATFORM_WIN32_NT) || (ver.dwPlatformId==VER_PLATFORM_WIN32_95))
    GetSystemMetrics (SM_CXSCREEN);
    GetSystemMetrics (SM_CXVIRTUALSCREEN);

LVL 48

Expert Comment

ID: 16978617
No, this means that you need to add line:
#define _WIN32_WINNT 0x0500
before including windows.h. I don't think that you need multimon.h fot compiling SM_CXVIRTUALSCREEN.
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.


Author Comment

ID: 16978707
So, to make sure I understand, you are saying:
1. adding line: #define _WIN32_WINNT 0x0500 before the line #include "windows.h" in the 6 places that line occurs in my code will fix my build error.
2. adding line: #define _WIN32_WINNT 0x0500 before the line #include "windows.h" in the 6 places that line occurs in my code will ensure that my .exe runs on NT and 95.
3. I don't need to #include multimon.h at all, nor add it to my project.

Have I got this right? Thank you.
LVL 48

Accepted Solution

AlexFM earned 1000 total points
ID: 16978791
Add lines
#define _WIN32_WINNT 0x0500
#define WIN32_WINDOWS 0x0410
#define WINVER  0x0500

before the line #include "windows.h", at least in the file where you use SM_CYVIRTUALSCREEN. This will fix your compilation error. You can see the following lines in winuser.h file:

#if(WINVER >= 0x0500)
#define SM_XVIRTUALSCREEN       76
#define SM_YVIRTUALSCREEN       77
#define SM_CXVIRTUALSCREEN      78
#define SM_CYVIRTUALSCREEN      79

This is the reason your code is not compiled now.

Your application can run on Win95/NT, because it calls function GetSystemMetrics which is supported in these OS. But result of call with SM_CYVIRTUALSCREEN is unpredictable, because this parameter is not supported. You need to do something on these operating systems, like show message that program doesn't support them. BTW, I don't think that virtual screens are supported on these OS.

So, your only problem is to say to compiler "Minimal target OS is W2K/98", and this is done by using these constants.

multimon.h is not related to this problem, maybe you need it for something else, I don't know.
LVL 39

Expert Comment

ID: 16985359
>>>> Add lines
>>>> #define _WIN32_WINNT 0x0500
>>>> #define WIN32_WINDOWS 0x0410
>>>> #define WINVER  0x0500

It's better to add these macros via Project Settings especially if using Precompiled Headers  (PCH). In that case, define statements prior to including stdafx.h (or whatever is the name of your PCH) were ignored.

You can add the macros in the Preprocessor settings of the C++ tab bei adding

    _WIN32_WINNT=0x0500 WIN32_WINDOWS=0x0410,WINVER=0x0500

to the existing preprocessor macros (e. g. WIN32).

Regards, Alex


Author Comment

ID: 16995921
Thank you. I want my application to continue to be able to work on Win95 and WinNT.
You are correct that these platforms do non support multiple monitors (and I am fine if my application doesn't support multiple monitors for those OS, but I still want it run on those OS because we still have users on those OS).

Author Comment

ID: 17237023
The answers have been helpful. However I was still hoping for clarity as to whether implementing the advice will result in failure of my application on Win95 and WinNT (as opposed to Win95 and WinNT users simply not getting optimal performance on multiple monitors).
LVL 39

Assisted Solution

itsmeandnobodyelse earned 1000 total points
ID: 17239787
>>>> I was still hoping for clarity as to whether implementing the advice will result in
>>>> failure of my application on Win95 and WinNT

GetSystemMetrics returns zero if the argument is unknown. You need to check the return value and perform some alternative code if 'virtual screen' options were not supported. You might read the following article to learn more:

So, there is no problem as long as you make sure to not calling functions that were not supported by W9x or NT, such as EnumDisplayMonitors. By defining the macros you make some more functions available which can be called on newer  Windows versions but would crash - cause they are not available - on the older versions. So, whenever using a WINAPI function where you don't know for sure that it is available on all platforms check the MSDN and do not call it on older platforms.

Regards, Alex


Author Comment

ID: 17438358
Yes, I would rather we leave it open... sorry for the delay: I was out of town for a bit. I will test the final advice and then confirm whether it can be cleanly pointed and closed, if that is okay with you.
LVL 20

Expert Comment

ID: 17549854
Any news here? It will get abandoned again in 3 days...

Author Comment

ID: 17686824
Sorry about that. Thank you for splitting the points and closing it.

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

715 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question