用CreateFile打开显示时,正确的路径是什么?

What is the correct path when opening a Display with CreateFile?

本文关键字:路径 是什么 CreateFile 显示      更新时间:2023-10-16

大多数最小示例:

#include <Windows.h>
#include <ntddvdeo.h>
#include <string>

std::string GetLastErrorAsString()
{
    LPSTR msgBuffer = nullptr;
    DWORD errorMessageID = ::GetLastError();
    std::string msg("No Error");
    if(errorMessageID != 0)
    {
        size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                                     FORMAT_MESSAGE_FROM_SYSTEM |
                                     FORMAT_MESSAGE_IGNORE_INSERTS,
                                     NULL,
                                     errorMessageID,
                                     MAKELANGID(LANG_NEUTRAL, 
                                     SUBLANG_DEFAULT),
                                     (LPSTR)&msgBuffer,
                                     0,
                                     NULL);
        msg = std::string(msgBuffer, size);
        //Free buffer
        LocalFree(msgBuffer);
    }
    return msg;
}
int APIENTRY wWinMain(  _In_ HINSTANCE hInstance,
                        _In_opt_ HINSTANCE hPrevInstance,
                        _In_ LPWSTR    lpCmdLine,
                        _In_ int       nCmdShow)
{
    DWORD nOutBufferSize = 0;
    DWORD result = NULL;
    typedef struct _DISPLAY_BRIGHTNESS {
       UCHAR ucDisplayPolicy;
       UCHAR ucACBrightness;
       UCHAR ucDCBrightness;
    } DISPLAY_BRIGHTNESS, *PDISPLAY_BRIGHTNESS;
    DISPLAY_BRIGHTNESS displayBrightness;
    displayBrightness.ucDisplayPolicy = 0;
    displayBrightness.ucACBrightness = 50;
    displayBrightness.ucDCBrightness = 0;
    nOutBufferSize = sizeof(displayBrightness);
    HANDLE h = CreateFile(  L"\\.\DISPLAY2",
                            GENERIC_READ | GENERIC_WRITE,
                            0, NULL,
                            OPEN_EXISTING,
                            0, NULL);
    if (h == INVALID_HANDLE_VALUE) {
        MessageBoxA(NULL, GetLastErrorAsString().c_str(), "Test", 
                    MB_OK | MB_ICONERROR);
        return false;
    }    
    return true;
}

即使以管理员的身份运行Visual Studio,我也总是在CreateFile之后获得"访问拒绝"。因此,问题是,如果未识别\.DISPLAY2,Windows在那里还接受什么,作为设备名称/路径?但是,这是我从EnumDisplayMonitors获得的确切设备名称:

Found Monitor with 1920x1080 called \.DISPLAY1 located at 0:00
Found Monitor with 1680x1050 called \.DISPLAY2 located at -1680:240

如果您想要一个物理监视器的句柄,则从EnumDisplayMonitors的回调中获取HMONITOR并将其用作GetPhysicalMonitorsFromHMONITOR的参数。

将为您提供PHYSICAL_MONITOR对象中的HANDLE。您可以使用该句柄来例如调用这些功能

,但是,正如先前建议的 - 也许您想获得的是设备上下文的处理方式?然后使用createC, CreateFile在这里无法使用。


编辑:

如果要更改亮度,请尝试第一种方法 - 获取物理监视器HANDLE并使用setMonitorBrightness

edit2:

好吧,此代码对我有用,实际上,从EnumDisplayMonitors返回的设备路径也对我不起作用。我不是这个代码的作者,我在这里找到了它(我自己无法弄清楚)

DISPLAY_DEVICE ddAdapter;
ddAdapter.cb = sizeof(DISPLAY_DEVICE);
for (DWORD dwAdapterNum = 0; EnumDisplayDevices(NULL, dwAdapterNum, &ddAdapter, 0); dwAdapterNum++)
{
    if ((ddAdapter.StateFlags & (DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_MIRRORING_DRIVER)) == DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
    {
        DISPLAY_DEVICE ddMonitor;
        ddMonitor.cb = sizeof(DISPLAY_DEVICE);
        for (DWORD dwMonitorNum = 0; EnumDisplayDevices(ddAdapter.DeviceName, dwMonitorNum, &ddMonitor, EDD_GET_DEVICE_INTERFACE_NAME); dwMonitorNum++)
        {
            if (ddMonitor.StateFlags & DISPLAY_DEVICE_ACTIVE)
            {
                HANDLE hMonitor = CreateFile(ddMonitor.DeviceID, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
                // ...
                CloseHandle(hMonitor);
            }
        }
    }
}