Sam Sam - 1 month ago 8
C Question

How to resolve linking error for GetSystemMetrics()?

I'm attempting to use the following to get the height & width of the main display:

#include <winuser.h>
size_t width = (size_t)GetSystemMetrics(SM_CXBORDER);
size_t height = (size_t)GetSystemMetrics(SM_CYBORDER);


However, it's failing on an unresolved externals link error (
LNK1120
). I've tried linking to user32.lib (as documented here), and received the same error, as well as linking to wmbase.lib (as documented here), and received the error that wmbase.lib does not exist! What am I doing wrong?

Note that I am only using plain-ol' C — not C++. Is this the right function to use to get the screen resolution (in pixels) of the main display?

I am attempting to compile this on MSVC at the moment, but would prefer a solution portable to other compilers.

Thanks.

Edit



So it looks like the parameters I was looking for were
SM_CXSCREEN
and
SM_CYSCREEN
, not
SM_CXBORDER
and
SM_CYBORDER
. However, I still can't manage to get this to compile.

Here is the actual error if that clarifies anything (when linked to user32.lib):

screen.obj : error LNK2019: unresolved external symbol __imp__GetSystemMetrics@4 referenced in function _getMainDisplaySize
build\lib.win32-2.6\foomodule\bitmap.pyd : fatal error LNK1120: 1 unresolved externals
error: command '"C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\link.exe"' failed with exit status 1120


(I am attempting to compile a Python/C module so that's why you see the weird directories)

Answer

You want to #include <windows.h> instead of <winuser.h>. As-is, it's probably getting some of the modifiers on the prototype wrong as it is.

Edit: since you're still having problems, perhaps we can start with a simplified test and see what you get. Fortunately, GetSystemMetrics() doesn't need a window handle or anything so e can call it from a simple console application:

#include <windows.h>
#include <iostream>

int main() { 
    size_t width = (size_t)GetSystemMetrics(SM_CXSCREEN);
    size_t height = (size_t)GetSystemMetrics(SM_CYSCREEN);

    std::cout << "width = " << width << "\n";
    std::cout << "height = " << height << std::endl; 
    return 0;
}

Here's a screen dump of compiling and running this:

D:\C\source>cl screen_res.cpp user32.lib
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

screen_res.cpp
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:screen_res.exe
screen_res.obj
user32.lib

D:\C\source>screen_res
width = 1600
height = 1200

If this doesn't compile and run, you probably have a problem with your installation. If it does, then the problem is probably somewhere in the project you're working on.