在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 称为 EnumDisplayDevicesAEnumDisplayDevicesW。 Windows SDK 将使用宏将其中一个映射到您可以调用的对象:

#ifdef UNICODE
#define EnumDisplayDevices  EnumDisplayDevicesW
#else
#define EnumDisplayDevices  EnumDisplayDevicesA
#endif // !UNICODE

其次,EnumDisplayDevicesAEnumDisplayDevicesW 的实际声明将被声明为 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_DEVICEPDISPLAY_DEVICE,您可能还需要修复您的声明。下面的示例代码解决了这个问题。

最后,即使你修复了这个问题,你仍然没有 link 的库,因为你的 user32.lib 版本对这个 API 一无所知后来来了。

您可以找到更新版本的 Windows SDK,它仍然适用于 VC 6.0。但是更简单的方法可能是在运行时直接 LoadLibrary API。所以把它们放在一起,这是一个完整的解决方案,我们将在运行时动态加载 EnumDisplayDevicesWEnumDisplayDevicesA 函数。调用示例:

#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
}