2015-09-17 47 views
9

Esiste un'API di Windows per rilevare se il coperchio del laptop è chiuso (= lo schermo del laptop integrato è spento)?Rilevamento se il coperchio del laptop è chiuso/lo schermo integrato è spento


C'è già la "stessa" questione ha chiesto:
Get current laptop lid state

Anche se la (auto) risposta accettata si basa su uno schermo "dispositivo" integrato essere rimosso, quando il coperchio si chiude. Ma questo non succede su tutti i laptop. Alcuni mantengono lo schermo "disponibile" al sistema (pur non visualizzando nulla in effetti), anche quando il coperchio è chiuso. Ciò significa che il desktop di Windows si estende ancora sullo schermo chiuso (se le impostazioni "Visualizzazioni multiple" sono impostate su "Estendi questi display").

non ho ancora determinato, se questo comportamento può essere configurato o se non é specifico driver:
Remove closed laptop screen from Windows desktop

Ma anche in tali sistemi, il sistema operativo sa che il coperchio si chiude, in quanto si può spegnere/dorme la macchina quando lo fa. E si trasmette una notifica (WM_POWERBROADCAST):
Detect laptop lid closure and opening


Background: Ho una domanda che inizia sullo stesso display, dove è stato chiuso l'ultima volta. Se è stato chiuso sullo schermo del laptop integrato e il coperchio è chiuso la prossima volta che l'applicazione si avvia (poiché l'utente sta utilizzando un monitor esterno), la mia applicazione si avvia sullo schermo del computer portatile ora invisibile.

Quindi voglio rilevare che il coperchio è chiuso e forzare l'applicazione su un monitor esterno.

Quindi sto cercando un modo per rilevare, se il coperchio è chiuso. O per un modo per rilevare, che uno schermo particolare è spento (quale sarebbe una soluzione più pulita).

+0

Hai visto questo: http://stackoverflow.com/questions/4486674/capturing-laptop-lid-closing -event-in-windows? – theB

+0

@theB Sure. In realtà è lo stesso di [Rileva la chiusura e l'apertura del coperchio del laptop] (http://stackoverflow.com/q/4486674/850848) a cui mi riferisco nella mia domanda. Sto cercando lo stato attuale del coperchio, non per una notifica di modifica. –

+0

A quanto pare la comprensione della lettura mi sta fallendo questa mattina. – theB

risposta

2

Sembra che non ti interessi se il coperchio è chiuso o meno e vuoi solo sapere se l'area dello schermo in cui stai per avviare l'applicazione è disponibile o meno.

Se il sistema operativo "utilizza ancora la schermata di spegnimento per il desktop esteso", ciò significa (dal punto di vista del sistema operativo) che lo schermo è disponibile per essere utilizzato per le applicazioni. In altre parole, la tua applicazione non sarebbe l'unica a soffrire di questo problema. Anche se devo dire che ho mai osservato quel particolare comportamento di prima mano.

Se è necessario spostare l'applicazione mentre è in esecuzione, è possibile registrarsi per il RegisterPowerSettingNotification e agire su di esso.

Tuttavia, se si sta avviando e bisogno di sapere se lo schermo è acceso o spento si hanno due opzioni:

EnumDisplayDevices

Questo vi fornirà le informazioni sul fatto che lo schermo è collegato a un desktop ed è attivo.Si tratta di "informazioni di sistema" che si ottiene dalle API 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)

Questo ti dà praticamente le stesse informazioni come sopra ma con un approccio più moderno (e potenzialmente un minor numero di falsi positivi). Certo che richiederebbe di collegare-in DXGI per far funzionare tutto questo e include l'intestazione che aumenterà il vostro dimensioni delle applicazioni:

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

Speranza che aiuta.

Direct3D9

Questo metodo fornisce anche informazioni di visualizzazione, ma in modo leggermente diverso - attraverso un elenco di adattatori e monitor collegati a tali adattatori. Ricordati di collegare-in d3d9 libreria per far funzionare tutto questo:

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(); 
} 

Tutti e 3 i frammenti di codice sono da alcuni dei miei progetti in modo da poter basta copiare-incollare il codice e dovrebbe funzionare (mettendo a nudo alcune correzioni minori per le funzioni mancanti o variabili mentre stavo modificando il codice al volo per ridurne le dimensioni quando lo ho postato qui)

+0

Grazie per la risposta. Hai ragione, che in realtà cerco la disponibilità di uno schermo piuttosto che lo stato del coperchio (menziono anch'io nell'ultimo paragrafo della mia domanda). Il problema è che i sistemi interessati ritengono che lo schermo della lib chiusa sia disponibile. Se non fosse così, probabilmente rimuoverà lo schermo dal desktop stesso. Quindi tutti i tuoi tre metodi presentano anche lo schermo integrato come disponibile quando il coperchio è chiuso, sfortunatamente. –