Monitor Handle via CreateFile, wie?



  • Hallo Community,

    Ich habe heute meinen zweiten Monitor bekommen und angeschlossen. Da ich diesen aber nur brauche, wenn ich arbeite, wechsel ich über den Grafikkartentreiber mit zwei verschiedenen Profilen immer zwischen Single und Dual Monitoring. Es macht jetzt nicht wirklich Umstände einen Rechtsklick auf den Desktop zu machen, das Kontrollzentrum der GraKa zu öffnen und dann zw. den Profilen zu wechseln. Aber es wäre schon cooler (bequemer), wenn das alles ganz automatisch passieren würde sobald ich den zweiten Monitor anschalte.

    Meine Idee war deshalb einen Service zu programmieren der genau das für mich regeln soll. Doch das soll jetzt nicht der Schwerpunkt dieses Threads sein. Mein Problem liegt darin, den Powerstate des Monitors in Erfahrung zubringen?! Es gibt eine Funktion GetDevicePowerState ( http://msdn.microsoft.com/en-us/library/ee486315.aspx ), mit der kann man wohl einsehen, ob sich ein Gerät im aktiven oder inaktiven Modus befindet. Leider soll das wohl nicht mit Monitoren funktionieren. Ich wollte es trotzdem mal versuchen 😃 nur hab ich leider keine Ahnung wie der Name des Services ist mit dem ich den Monitor ansteuere, "\.\monitor"?

    Ich hoffe ihr könnt mir da weiter helfen.

    Lg Tobi



  • Ist das beabsichtigt, dass der MSDN-Artikel für Windows CE ist?

    Die Doku für Desktop-Betriebssysteme ist hier: http://msdn.microsoft.com/en-us/library/aa372690(VS.85).aspx

    Vielleicht findest du auch hier noch etwas brauchbares.



  • Oh danke. War ich wohl etwas zu fix. Also ich hab jetzt schon einige Artikel gelesen. Unter Windows 2000, soll das wohl funktionieren mit CreateFile und als Devicehandle "\.\LCD", aber ab WinXp geht es wohl nicht mehr. Es gibt auch andere Devicenamen wie "\.\Display#". Ja was funktiniert denn nun? Gibt es evtl. irgendwo eine Liste, wo alle standardisierten Namen gelistet sind? Ich habe auch mal im Gerätemanager von Windows geschaut. Da werden ja auch beide Monitore aufgelistet, da gibt es einen Eintrag der nennt sich "Device Instance Path". Dieser scheint auch unique zu sein. Kann man den evtl. als Handle bei CreateFile benutzen?

    [EDID:]

    So ich habe mal angefangen eine kleine Anwendung zu programmieren. Dort versuche ich mit CreateFile einfach mal alle Varianten durch ("\.\lcd", "\.\display#" und "\.\monitor#"). Bei lcd und monitor liefert GetLastError immer das er das Device nicht finden konnte und mit "\.\display#" beomme ich immer ein "Access denied!". Ok also mit "\.\display#" komme ich anscheint an meine Monitore ran?! Nun muss ich nur noch das System dazu bewegen mich gewähren zu lassen. Nur wie? Mit einem SECURITY_ATTRIBUTE?

    Lg Tobi



  • Also ich komme einfach nicht an das Handle heran. Nach ein bisschen Recherche im Netz, bin ich auch auf den Grund gestoßen warum ich da nicht rankomme. Zum Systemstart holt sich Windows via' CreateFill o.ä das Handle und hält es offen und auch andere Programme davon ab sich Zugang zu verschaffen. Bleibt mir da also nur noch die Option einen Treiber zu Programmieren?

    Frohe Weihnachten :xmas1:

    Lg Tobi



  • T0bi schrieb:

    Also ich komme einfach nicht an das Handle heran. Nach ein bisschen Recherche im Netz, bin ich auch auf den Grund gestoßen warum ich da nicht rankomme. Zum Systemstart holt sich Windows via' CreateFill o.ä das Handle und hält es offen und auch andere Programme davon ab sich Zugang zu verschaffen. Bleibt mir da also nur noch die Option einen Treiber zu Programmieren?
    Frohe Weihnachten :xmas1:
    Lg Tobi

    Hallo Tobi,

    hier eine quick&durty Lösung, getestet mit Win7/64bit und WinXP/SP3 (nur über "\\\.\\LCD"). Der code ist etwas chaotisch da wild zusammenkopiert. Sollte aber reichen um zu zeigen wie es geht und DAS es geht. GetDevicePowerState erkennt NUR, ob der Monitor systemseitig im suspend ist oder nicht. Wenn er manuell abgeschaltet ist (power off) wird dies nicht erkannt. Dafür schau Dir mal RegisterDeviceNotification() an. Darüber sollte ein Event möglich sein, wenn der Monitor power bekommt (DEVICE_ARRIVAL/REMOVE). Viel Erfolg!

    #include <setupapi.h>
    #include <devguid.h>
    
       HDEVINFO hDevInfo;
       SP_DEVINFO_DATA DeviceInfoData;
       DWORD i;
    
       #define DISPLAY_IID  {0xE6F07B5F, 0xEE97, 0x4A90, {0xB0, 0x76, 0x33, 0xF5, 0x7B, 0xF4, 0xEA, 0xA7}}
    
      GUID DisplayIID = DISPLAY_IID;
    
      hDevInfo = SetupDiGetClassDevs(&DisplayIID,
                                     0,
                                     0,
                                     DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    
      HANDLE hDisplay = INVALID_HANDLE_VALUE;
    
       if(hDevInfo != INVALID_HANDLE_VALUE)
        {
          DWORD int_index = 0;
          SP_DEVICE_INTERFACE_DATA dev_int_data;
          dev_int_data.cbSize = sizeof(dev_int_data);
    
          PSP_DEVICE_INTERFACE_DETAIL_DATA detailData;
          BYTE detail_buffer[MAX_PATH + sizeof(TCHAR)];
          detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)&detail_buffer;
          detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // see MSDN remarks
    
          SP_DEVINFO_DATA dev_info_data;
    
          while(SetupDiEnumDeviceInterfaces(hDevInfo, 0, &DisplayIID, int_index++, &dev_int_data))
           {
             detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // see MSDN remarks
             dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
    
             if(SetupDiGetDeviceInterfaceDetail(hDevInfo, &dev_int_data, detailData, MAX_PATH + sizeof(TCHAR), NULL, &dev_info_data))
              {
                OutputDebugString(detailData->DevicePath);
                hDisplay = CreateFile(detailData->DevicePath,
                                      READ_CONTROL,
                                      FILE_SHARE_READ | FILE_SHARE_WRITE,
                                      NULL,
                                      OPEN_EXISTING,
                                      0,
                                      NULL);
    
                // erstes display gefunden und okay => fertig 
                if(hDisplay != INVALID_HANDLE_VALUE) break;
              }
           }
    
          //  Cleanup
          SetupDiDestroyDeviceInfoList(hDevInfo);
        }
    
       if(hDisplay == INVALID_HANDLE_VALUE)
        {
          // auf die harte tour für WinXP...
          hDisplay = CreateFile("\\\\.\\LCD",
                                 GENERIC_READ,
                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
                                 NULL,
                                 OPEN_EXISTING,
                                 0,
                                 NULL);
        }
    
       if(hDisplay != INVALID_HANDLE_VALUE)
        {
          //....read/write, what ever
          // GetDevicePowerState erkennt aber nicht, wenn der Monitor manuell abgeschaltet ist!
    
          CloseHandle(hDisplay);
        }
    

Anmelden zum Antworten