2012-07-11 16 views
5

Sto creando un'applicazione Qt/C++ che utilizza QML per alcune parti. Sotto Windows vorrei fare uso delle finestre traslucide usando ExtendFrameIntoClientArea come visto in questo frammento della mia classe di finestre.QT Finestra traslucida e desktop remoto

#ifdef Q_WS_WIN 
    if (QSysInfo::windowsVersion() == QSysInfo::WV_VISTA || 
     QSysInfo::windowsVersion() == QSysInfo::WV_WINDOWS7) 
    { 
     EnableBlurBehindWidget(this, true); 
     ExtendFrameIntoClientArea(this); 
    } 
#else 

il codice sta lavorando bene con una sola eccezione. Se il sistema di finestre trasparenti viene disattivato, lo sfondo diventa nero e, poiché la mia interfaccia utente è trasparente, diventa scuro. La stessa cosa accade quando si accede a un computer remoto che esegue l'applicazione, anche se il sistema di finestre trasparenti viene reinizializzato immediatamente lo sfondo rimane nero fino a quando il codice sopra non viene eseguito nuovamente. Questo è dimostrato in questa immagine: Comparison of failed rendering (in background) and correct (in front).

Il problema è trovare un segnale per connettersi alla reinizializzazione della finestra trasparente, o ancora meglio per rilevare quando le finestre sono disegnate in modo trasparente e disegnare l'interfaccia utente di conseguenza. Sono anche benvenute eventuali soluzioni alternative.

risposta

2

Dopo aver scavato in entrambe le Qt e MSDN Aero documentation, ho trovato una soluzione in due passaggi. Sovrascrivendo il metodo winEvent della mia finestra principale, sono stato in grado di ricevere il segnale che viene attivato ogni volta che il sistema di finestre traslucide è abilitato o disabilitato.

#define WM_DWMCOMPOSITIONCHANGED  0x031E 

bool MainWindow::winEvent(MSG *message, long *result) { 
    if (message->message == WM_DWMCOMPOSITIONCHANGED) { 
     // window manager signaled change in composition 
     return true; 
    } 
    return false; 
} 

Questo mi ha portato piuttosto vicino, ma non mi ha detto se DWM stava attualmente disegnando finestre trasparenti o meno. Utilizzando dwmapi.dll sono stato in grado di trovare un metodo che fa esattamente questo, ed è possibile accedervi come di seguito:

// QtDwmApi.cpp 
extern "C" 
{ 
    typedef HRESULT (WINAPI *t_DwmIsCompositionEnabled)(BOOL *pfEnabled); 
} 

bool DwmIsCompositionEnabled() { 
    HMODULE shell; 

    shell = LoadLibrary(L"dwmapi.dll"); 
    if (shell) { 
     BOOL enabled; 
     t_DwmIsCompositionEnabled is_composition_enabled = \ 
       reinterpret_cast<t_DwmIsCompositionEnabled>(
        GetProcAddress (shell, "DwmIsCompositionEnabled") 
       ); 
     is_composition_enabled(&enabled); 

     FreeLibrary (shell); 

     if (enabled) { 
      return true; 
     } else { 
      return false; 
     } 
    } 
    return false; 
} 

mia implementazione è ora in grado di reagire ai cambiamenti di Aero e disegnare l'interfaccia grafica di conseguenza. Quando si accede tramite desktop remoto, la finestra viene disegnata utilizzando anche la trasparenza, se disponibile.

0
The function should be written as follows to avoid the GPA failure 

// QtDwmApi.cpp 
extern "C" 
{ 
    typedef HRESULT (WINAPI *t_DwmIsCompositionEnabled)(BOOL *pfEnabled); 
} 

bool DwmIsCompositionEnabled() { 
    HMODULE shell; 
    BOOL enabled=false; 

    shell = LoadLibrary(L"dwmapi.dll"); 
    if (shell) { 
     t_DwmIsCompositionEnabled is_composition_enabled = \ 
       reinterpret_cast<t_DwmIsCompositionEnabled>(
        GetProcAddress (shell, "DwmIsCompositionEnabled") 
       ); 
     if (is_composition_enabled) 
      is_composition_enabled(&enabled); 

     FreeLibrary (shell); 
    } 
    return enabled; 
} 
Problemi correlati