2017-02-20 57 views
3

最起码例如:使用CreateFile打开显示器时的正确路径是什么?

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

我总是收到“拒绝访问” CreateFile后,在运行Visual Studio以管理员身份时也是如此。所以问题是,如果\\.\DISPLAY2无法识别,那么Windows会在那里接受哪些设备名称/路径?然而,这是我从EnumDisplayMonitors得到确切的设备名称:

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

什么,你希望能够与这样的处理呢? – andlabs

+0

@andlabs我想用它与DeviceIoControl – BadSnowflake

回答

3

如果你想有一个手柄,物理监视器,然后从EnumDisplayMonitors回调得到HMONITOR,并用它作为GetPhysicalMonitorsFromHMONITOR参数。

这会给你在PHYSICAL_MONITOR对象。您可以使用该句柄来拨打电话these functions

但仍然如之前所建议的 - 也许您想要获得的是设备环境的句柄?然后使用CreateDC,CreateFile不会在这里工作。


编辑:

如果你想改变亮度,尝试第一种方法 - 让物理显示器HANDLE和使用SetMonitorBrightness

EDIT2:

好吧,这代码适用于我,实际上从EnumDisplayMonitors返回的设备路径也不适用于我。我不是这个代码的作者,我发现它here(无法弄清楚我自己)

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); 
      } 
     } 
    } 
} 
+0

我不需要DC,我想在DeviceIoControl中使用它来修改设备的属性。在这种情况下,亮度。我正在寻找一种方法来在某些条件满足时调暗某些设备(监视器)。 – BadSnowflake

+0

@Assylum编辑与您的问题提出的解决方案。 – mpiatek

+0

我试过这些功能。 GetMonitorCapabilities只会返回格式不正确的DDC响应,我有两台显示器:http://i.imgur.com/wMnexpS.png有人告诉我,它可能是造成它的视频驱动程序。不过,我正在使用最新的一款。这样做真的很难。我最后的手段就是使用半透明的黑色图片作为覆盖层来调暗它。 – BadSnowflake

相关问题