Below is the main code, the problems encountered, and how they were resolved
***.h
std::list<DISPLAY_DEVICE> m_vDisplayDevice_list;
std::list<DEVMODE> m_vDevmode_list;
int m_nDisplayScreen;
***.cpp
std::list<DISPLAY_DEVICE> devices;
std::list<DEVMODE> modes;
int devId = 0;
BOOL ret = false; // bool ret = false;
bool isPrimary = false;
//list all DisplayDevices (Monitors)
do
{
DISPLAY_DEVICE displayDevice;
ZeroMemory(&displayDevice, sizeof(DISPLAY_DEVICE));
displayDevice.cb = sizeof(displayDevice);
ret = EnumDisplayDevices(NULL, devId, &displayDevice, 0);
if (ret != 0) // reinterpret_cast
{
// 有‘DISPLAY_DEVICE_ATTACHED_TO_DESKTOP’标志的显示设备
if ((displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) == DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
{
devices.push_back(displayDevice);
isPrimary = ((displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) == DISPLAY_DEVICE_PRIMARY_DEVICE);
}
}
devId ;
} while (ret);
m_vDisplayDevice_list = devices;
std::list<DISPLAY_DEVICE>::iterator it;
for (it = m_vDisplayDevice_list.begin(); it != m_vDisplayDevice_list.end(); it )
{
DEVMODE deviceMode;
deviceMode.dmSize = sizeof(DEVMODE);
deviceMode.dmFields = DM_PELSWIDTH | // dmPelsWidth
DM_PELSHEIGHT | //dmPelsHeight
DM_BITSPERPEL |
DM_POSITION |
DM_DISPLAYFREQUENCY |
DM_DISPLAYFLAGS; // | DM_DISPLAYORIENTATION;
EnumDisplaySettings((const char*)(it->DeviceName), (int)ENUM_REGISTRY_SETTINGS, &deviceMode);
modes.push_back(deviceMode);
}
m_vDevmode_list = modes;
I used this function to open the Windows desktop shortcut:
ShellExecute(NULL,
NULL,
_T("C:\\Users\\Administrator\\Desktop\\BasePointV - ***.lnk"),
NULL,
NULL,
SW_SHOWNORMAL);
I have a problem!!!
--------Configuration: Display - Win32 Release--------
Linking...
***.obj : error LNK2001: unresolved external symbol __imp__EnumDisplayDevicesA@16
Debug/***.exe : fatal error LNK1120: 1 unresolved externals
***.exe - 1 error(s), 0 warning(s)
The project I built is MFC AppWinzard(exe);
Environment is:Windows10 VC 6.0
Online solutions include:
Define WINVER 0x0500
Add user32.DLL
There are many good solutions, but the linking problem is not solved yet! Although I am a novice, I would like to further collect some solutions
I hope to get your help to discuss and learn with you
CodePudding user response:
Your linkage error concerning _EnumDisplayDevices
says it all.
My psychic powers suggests that since Visual Studio 6.0 (released in 1998) predates the availability of EnumDisplayDevices
(Windows 2000), you are trying to pre-declare the API yourself. You probably predeclared EnumDisplayDevices
manually yourself. Something like this:
BOOL EnumDisplayDevices(
LPCSTR lpDevice,
DWORD iDevNum,
PDISPLAY_DEVICEA lpDisplayDevice,
DWORD dwFlags
);
There's two problems with this approach.
First, there's no API called EnumDisplayDevices
. There is however, two APIs called EnumDisplayDevicesA
and EnumDisplayDevicesW
for both Unicode and ANSI builds. The Windows SDK will use a macro to map either one to the thing you can to invoke:
#ifdef UNICODE
#define EnumDisplayDevices EnumDisplayDevicesW
#else
#define EnumDisplayDevices EnumDisplayDevicesA
#endif // !UNICODE
Second, the actual declaration of EnumDisplayDevicesA
and EnumDisplayDevicesW
will are declared as stdcall
calling type, like most Win32 APIs. Your declaration is likely missing this detail.
Hence, you want to declare this:
BOOL __stdcall EnumDisplayDevicesW(
LPCWSTR lpDevice,
DWORD iDevNum,
PDISPLAY_DEVICEW lpDisplayDevice,
DWORD dwFlags);
And this:
BOOL __stdcall EnumDisplayDevicesA(
LPCSTR lpDevice,
DWORD iDevNum,
PDISPLAY_DEVICEA lpDisplayDevice,
DWORD dwFlags);
If you manually declared DISPLAY_DEVICE
and PDISPLAY_DEVICE
yourself, you may also need to fixup your declaration as well. That's addressed in the sample code below.
Finally, even after you fix this, you still won't have a lib to link with since your version of user32.lib
doesn't know anything about this API that came later.
You could find a newer version of the Windows SDK that still works with VC 6.0. But a simpler approach might to LoadLibrary
the API directly at runtime. So putting it all together, here's a complete solution in which we'll dynamically load the EnumDisplayDevicesW
and EnumDisplayDevicesA
functions at runtime. Sample invocation as well:
#include <windows.h>
// BORROWED THIS FROM THE WINDOWS SDK - uncomment it if you need it
#if 0
typedef struct _DISPLAY_DEVICEA {
DWORD cb;
CHAR DeviceName[32];
CHAR DeviceString[128];
DWORD StateFlags;
CHAR DeviceID[128];
CHAR DeviceKey[128];
} DISPLAY_DEVICEA, *PDISPLAY_DEVICEA, *LPDISPLAY_DEVICEA;
typedef struct _DISPLAY_DEVICEW {
DWORD cb;
WCHAR DeviceName[32];
WCHAR DeviceString[128];
DWORD StateFlags;
WCHAR DeviceID[128];
WCHAR DeviceKey[128];
} DISPLAY_DEVICEW, *PDISPLAY_DEVICEW, *LPDISPLAY_DEVICEW;
#ifdef UNICODE
typedef DISPLAY_DEVICEW DISPLAY_DEVICE;
typedef PDISPLAY_DEVICEW PDISPLAY_DEVICE;
typedef LPDISPLAY_DEVICEW LPDISPLAY_DEVICE;
#else
typedef DISPLAY_DEVICEA DISPLAY_DEVICE;
typedef PDISPLAY_DEVICEA PDISPLAY_DEVICE;
typedef LPDISPLAY_DEVICEA LPDISPLAY_DEVICE;
#endif // UNICODE
#endif // if 0
// Declare the function types for EnumDisplayDevices
typedef BOOL(__stdcall* FN_EDD_W)(LPCWSTR, DWORD, PDISPLAY_DEVICEW, DWORD);
typedef BOOL(__stdcall* FN_EDD_A)(LPCSTR, DWORD, PDISPLAY_DEVICEA, DWORD);
int main()
{
FN_EDD_W fnEnumDisplayDevicesW;
FN_EDD_A fnEnumDisplayDevicesA;
// Dynamically load EnumDisplayDevices
HMODULE hMod = LoadLibraryW(L"user32.dll");
fnEnumDisplayDevicesW = (FN_EDD_W)GetProcAddress(hMod, "EnumDisplayDevicesW");
fnEnumDisplayDevicesA = (FN_EDD_A)GetProcAddress(hMod, "EnumDisplayDevicesA");
// now invoke the loaded API function
DISPLAY_DEVICEW device = {};
device.cb = sizeof(device);
fnEnumDisplayDevicesW(NULL, 0, &device, 0); // equivalent to EnumDisplayDevicesW
}