2015-09-17 8 views
9

Gibt es ein Windows-API, um zu erkennen, ob ein Laptopdeckel geschlossen ist (= integrierter Laptopbildschirm ist ausgeschaltet)?Erkennen, ob der Laptopdeckel geschlossen ist/der integrierte Bildschirm ist aus


Es gibt bereits die „gleiche“ Frage gestellt:
Get current laptop lid state

Obwohl die (Selbst-) akzeptierte Antwort auf einem integrierten Bildschirm „Gerät“ beruht entfernt wird, wenn der Deckel geschlossen wird. Aber das passiert nicht auf allen Laptops. Einige halten den Bildschirm für das System "verfügbar" (obwohl nichts tatsächlich angezeigt wird), selbst wenn der Deckel geschlossen ist. Dies bedeutet, dass sich der Windows-Desktop immer noch über den geschlossenen Bildschirm erstreckt (wenn die Einstellung "Mehrere Bildschirme" auf "Diese Anzeigen erweitern" eingestellt ist).

Ich habe noch nicht bestimmt, wenn dieses Verhalten konfiguriert werden kann, oder ob es Treiber spezifisch:
Remove closed laptop screen from Windows desktop

Aber auch auf solchen Systemen kennen die OS, dass der Deckel geschlossen, so kann es shutdown/Schlaf die Maschine, wenn sie es tut. Und es sendet eine Benachrichtigung (WM_POWERBROADCAST):
Detect laptop lid closure and opening


Hintergrund: Ich habe eine Anwendung, die auf demselben Display beginnt, wo es das letzte Mal geschlossen wurde. Wenn es beim nächsten Start der Anwendung auf dem integrierten Laptop-Bildschirm geschlossen wurde und der Deckel geschlossen ist (weil der Benutzer jetzt einen externen Monitor verwendet), startet meine Anwendung auf dem jetzt unsichtbaren integrierten Laptop-Bildschirm.

Daher möchte ich erkennen, dass der Deckel geschlossen ist und die Anwendung auf einen externen Monitor zwingen.

Also ich suche entweder nach einer Möglichkeit zu erkennen, ob der Deckel geschlossen ist. Oder für eine Möglichkeit zu erkennen, dass ein bestimmter Bildschirm ausgeschaltet ist (was wäre eine sauberere Lösung).

+0

Hast du diese: http://stackoverflow.com/questions/4486674/capturing-laptop-lid-closing -ereignis-in-windows? – theB

+0

@theB Sicher. Es ist eigentlich die gleiche wie [Detect Laptop-Deckel Schließen und Öffnen] (http://stackoverflow.com/q/4486674/850848), die ich in meiner Anfrage beziehen. Ich suche den aktuellen Deckelzustand, nicht für eine Änderungsbenachrichtigung. –

+0

Scheinbar versagt mir das Leseverstehen heute Morgen. – theB

Antwort

2

Klingt so, als ob es Ihnen egal ist, ob der Deckel geschlossen ist oder nicht und Sie möchten nur wissen, ob der Bildschirmbereich, auf dem Sie Ihre Anwendung starten möchten, verfügbar ist oder nicht.

Wenn das Betriebssystem den ausgeschalteten Bildschirm weiterhin für seinen erweiterten Desktop verwendet, bedeutet dies (aus der Sicht des Betriebssystems), dass der Bildschirm für Anwendungen verfügbar ist. Mit anderen Worten - Ihre Bewerbung wäre nicht die einzige, die unter diesem Problem leidet. Obwohl ich sagen muss, habe ich nie beobachtet, dass bestimmte Verhalten aus erster Hand.

Wenn Sie Ihre Anwendung verschieben müssen, während sie ausgeführt wird, können Sie sich für die RegisterPowerSettingNotification registrieren und darauf reagieren.

Allerdings, wenn Sie starten und wissen müssen, wenn der Bildschirm ein- oder ausgeschaltet ist, haben Sie zwei Möglichkeiten:

EnumDisplayDevices

Dies wird Ihnen die Informationen darüber geben, ob Ihr Bildschirm zu einem Desktop angebracht ist und ist aktiv.Das ist „Systeminformationen“, die Sie von der API erhalten in User32.dll

DISPLAY_DEVICE ddi; 
ddi.cb = sizeof(ddi); 
DWORD iDevNum = 0; // or iterate 0..15 
EnumDisplayDevices(NULL, iDevNum, &ddi, /*EDD_GET_DEVICE_INTERFACE_NAME*/0); 
if((ddi.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) == 0 && 
    (ddi.StateFlags & DISPLAY_DEVICE_ACTIVE) != 0){...} 

DXGI (DX11)

Dies gibt Ihnen grundsätzlich die gleichen Informationen wie oben, aber mit einem modernen Ansatz (und möglicherweise weniger False Positives). Natürlich, die Sie verknüpfen in DXGI erfordern würde für diesen und den Header enthalten arbeiten, die Ihre Anwendung Größe erhöhen:

#include <atltypes.h> 

IDXGIAdapter * pAdapter; 
std::vector <IDXGIAdapter*> vAdapters; 
IDXGIFactory* pFactory = NULL; 
// Create a DXGIFactory object. 
if(FAILED(CreateDXGIFactory(__uuidof(IDXGIFactory) ,(void**)&pFactory))) 
{ 
    return; 
} 
for(UINT i = 0; pFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND; ++i){ 
    DXGI_ADAPTER_DESC ad = {0}; 
    if(SUCCEEDED(pAdapter->GetDesc(&ad))){ 
     UINT j = 0; 
     IDXGIOutput * pOutput; 
     while(pAdapter->EnumOutputs(j, &pOutput) != DXGI_ERROR_NOT_FOUND) 
     { 
      DXGI_OUTPUT_DESC od = {0}; 
      if(SUCCEEDED(pOutput->GetDesc(&od))){ 
       // in here you can access od.DesktopCoordinates 
       // od.AttachedToDesktop tells you if the screen is attached 
      } 
      pOutput->Release(); 
      ++j; 
     } 
    } 
    pAdapter->Release(); 
} 

if(pFactory) 
{ 
    pFactory->Release(); 
} 

Hoffnung, das hilft.

Direct3D9

Dieses Verfahren stellt auch Anzeigeinformationen aber auf eine etwas andere Art und Weise - über eine Liste von Adaptern und Monitore an diesen Adapter angebracht. Denken Sie daran, zu verknüpfen-in d3d9 Bibliothek für diese arbeiten:

void d3d_adapterInfo(IDirect3D9 * _pD3D9, UINT _n) 
{ 
    D3DADAPTER_IDENTIFIER9 id; 
    const DWORD flags = 0; 
    if(SUCCEEDED(_pD3D9->GetAdapterIdentifier(_n, flags, &id))){ 
     // id provides info on Driver, Description, Name 
     HMONITOR hm = _pD3D9->GetAdapterMonitor(_n); 
     // and based on that hm you get the same monitor info as 
     // with the first method 
    } 
} 

void d3d_enumDisplays() 
{ 
    cout << endl << "--- Information by Direct3D9 ---" << endl; 
    IDirect3D9 * pD3D9 = Direct3DCreate9(D3D_SDK_VERSION); 
    const auto nAdapters = pD3D9->GetAdapterCount(); 
    cout << "A total of " << nAdapters << " adapters are listed by Direct3D9" << endl; 
    for(UINT i = 0; i < nAdapters; ++i){ 
     d3d_adapterInfo(pD3D9, i); 
    } 
    pD3D9->Release(); 
} 

Alle 3-Code-Schnipsel sind von einigen meiner Projekte, so dass Sie nur den Code kopieren und einfügen können und es sollte funktionieren (einige kleinere Korrekturen für fehlende Funktionen entblößte oder Variablen wie ich den Code wurde modifiziert on-the-fly seine Größe zu reduzieren, wenn es hier gepostet)

+0

Danke für Ihre Antwort. Sie haben Recht, dass ich tatsächlich aussehen für eine Bildschirm Verfügbarkeit anstatt den Deckel Zustand (ich erwähnt, dass ich im letzten Absatz meiner Frage). Das Problem ist, dass die betroffenen Systeme glauben, dass der geschlossene Lib-Bildschirm verfügbar ist. Hätte es nicht, würde es wahrscheinlich den Bildschirm vom Desktop selbst entfernen. Alle drei Methoden zeigen also auch den integrierten Bildschirm an, der bei geschlossenem Deckel leider verfügbar ist. –