在vc6.0中,使用WinAPI打开程序扩展监控的一些问题,希望得到大家的帮助与大家一起讨论
In vc6.0, using WinAPI to open the program to expand the monitor some problems, hope to get everyone's help to discuss with you
下面是主要代码,遇到的问题,以及如何解决的
***.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;
我用这个功能打开了Windows桌面快捷方式:
ShellExecute(NULL,
NULL,
_T("C:\Users\Administrator\Desktop\BasePointV - ***.lnk"),
NULL,
NULL,
SW_SHOWNORMAL);
我有问题!!!
--------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
有很多好的解决方案,但是链接问题还没有解决!虽然我是新手,但我想进一步收集一些解决方案
希望得到您的帮助,与您共同探讨学习
关于 _EnumDisplayDevices
的 link 年龄错误说明了一切。
我的灵力表明,由于 Visual Studio 6.0(1998 年发布)早于 EnumDisplayDevices
(Windows 2000)的可用性,您正在尝试 pre-declare API 你自己。您可能自己手动预先声明了 EnumDisplayDevices
。像这样:
BOOL EnumDisplayDevices(
LPCSTR lpDevice,
DWORD iDevNum,
PDISPLAY_DEVICEA lpDisplayDevice,
DWORD dwFlags
);
这种方法有两个问题。
首先,没有 API 叫作 EnumDisplayDevices
。但是,对于 Unicode 和 ANSI 构建,有两个 API 称为 EnumDisplayDevicesA
和 EnumDisplayDevicesW
。 Windows SDK 将使用宏将其中一个映射到您可以调用的对象:
#ifdef UNICODE
#define EnumDisplayDevices EnumDisplayDevicesW
#else
#define EnumDisplayDevices EnumDisplayDevicesA
#endif // !UNICODE
其次,EnumDisplayDevicesA
和 EnumDisplayDevicesW
的实际声明将被声明为 stdcall
调用类型,就像大多数 Win32 API 一样。您的声明可能缺少此详细信息。
因此,您要声明:
BOOL __stdcall EnumDisplayDevicesW(
LPCWSTR lpDevice,
DWORD iDevNum,
PDISPLAY_DEVICEW lpDisplayDevice,
DWORD dwFlags);
还有这个:
BOOL __stdcall EnumDisplayDevicesA(
LPCSTR lpDevice,
DWORD iDevNum,
PDISPLAY_DEVICEA lpDisplayDevice,
DWORD dwFlags);
如果您自己手动声明了 DISPLAY_DEVICE
和 PDISPLAY_DEVICE
,您可能还需要修复您的声明。下面的示例代码解决了这个问题。
最后,即使你修复了这个问题,你仍然没有 link 的库,因为你的 user32.lib
版本对这个 API 一无所知后来来了。
您可以找到更新版本的 Windows SDK,它仍然适用于 VC 6.0。但是更简单的方法可能是在运行时直接 LoadLibrary
API。所以把它们放在一起,这是一个完整的解决方案,我们将在运行时动态加载 EnumDisplayDevicesW
和 EnumDisplayDevicesA
函数。调用示例:
#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
}
下面是主要代码,遇到的问题,以及如何解决的
***.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;
我用这个功能打开了Windows桌面快捷方式:
ShellExecute(NULL,
NULL,
_T("C:\Users\Administrator\Desktop\BasePointV - ***.lnk"),
NULL,
NULL,
SW_SHOWNORMAL);
我有问题!!!
--------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
有很多好的解决方案,但是链接问题还没有解决!虽然我是新手,但我想进一步收集一些解决方案
希望得到您的帮助,与您共同探讨学习
关于 _EnumDisplayDevices
的 link 年龄错误说明了一切。
我的灵力表明,由于 Visual Studio 6.0(1998 年发布)早于 EnumDisplayDevices
(Windows 2000)的可用性,您正在尝试 pre-declare API 你自己。您可能自己手动预先声明了 EnumDisplayDevices
。像这样:
BOOL EnumDisplayDevices(
LPCSTR lpDevice,
DWORD iDevNum,
PDISPLAY_DEVICEA lpDisplayDevice,
DWORD dwFlags
);
这种方法有两个问题。
首先,没有 API 叫作 EnumDisplayDevices
。但是,对于 Unicode 和 ANSI 构建,有两个 API 称为 EnumDisplayDevicesA
和 EnumDisplayDevicesW
。 Windows SDK 将使用宏将其中一个映射到您可以调用的对象:
#ifdef UNICODE
#define EnumDisplayDevices EnumDisplayDevicesW
#else
#define EnumDisplayDevices EnumDisplayDevicesA
#endif // !UNICODE
其次,EnumDisplayDevicesA
和 EnumDisplayDevicesW
的实际声明将被声明为 stdcall
调用类型,就像大多数 Win32 API 一样。您的声明可能缺少此详细信息。
因此,您要声明:
BOOL __stdcall EnumDisplayDevicesW(
LPCWSTR lpDevice,
DWORD iDevNum,
PDISPLAY_DEVICEW lpDisplayDevice,
DWORD dwFlags);
还有这个:
BOOL __stdcall EnumDisplayDevicesA(
LPCSTR lpDevice,
DWORD iDevNum,
PDISPLAY_DEVICEA lpDisplayDevice,
DWORD dwFlags);
如果您自己手动声明了 DISPLAY_DEVICE
和 PDISPLAY_DEVICE
,您可能还需要修复您的声明。下面的示例代码解决了这个问题。
最后,即使你修复了这个问题,你仍然没有 link 的库,因为你的 user32.lib
版本对这个 API 一无所知后来来了。
您可以找到更新版本的 Windows SDK,它仍然适用于 VC 6.0。但是更简单的方法可能是在运行时直接 LoadLibrary
API。所以把它们放在一起,这是一个完整的解决方案,我们将在运行时动态加载 EnumDisplayDevicesW
和 EnumDisplayDevicesA
函数。调用示例:
#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
}