2017-02-20 16 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; 
} 

は、管理者としてのVisual Studioを実行している場合でも、CreateFile後に「アクセスが拒否されました」。だから、もしも\\.\DISPLAY2が認識されないならば、Windowsはそこでデバイス名/パスとして何を受け入れますか?あなたは物理的なモニターへのハンドルをしたい場合は、EnumDisplayMonitorsのコールバックからHMONITORを取得し、GetPhysicalMonitorsFromHMONITORの引数としてそれを使用

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から取得し、正確なデバイス名です。

これは、PHYSICAL_MONITORオブジェクトにHANDLEを与えます。あなたはそのハンドルを使用して、例えばthese functions

を呼び出すことができますが、これまでと同様に、デバイスコンテキストのハンドルを取得したいのですが?その後、CreateDCCreateFileを使用するとここでは動作しません。


EDIT:あなたは明るさを変更したい場合は

、最初のアプローチを試してみてください - 物理モニター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

関連する問題