2012-07-11 20 views
5

Ich erstelle eine Qt/C++ - Anwendung mit QML für einige Teile. Unter Windows möchte ich die transluzente Fensterung mit ExtendFrameIntoClientArea nutzen, wie in diesem Ausschnitt meiner Fensterklasse zu sehen ist.QT Transluzentes Fenster und Remote-Desktop

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

Der Code funktioniert gut mit einer Ausnahme. Wenn das transparente Fenstersystem ausgeschaltet wird, wird der Hintergrund schwarz und als Teil meiner UI transparent wird es auch dunkel. Dasselbe passiert, wenn man sich bei einem entfernten Computer anmeldet, der die Anwendung ausführt, selbst wenn das transparente Fenstersystem sofort neu initialisiert wird, bleibt der Hintergrund schwarz, bis der obige Code erneut ausgeführt wird. Dies wird in diesem Bild gezeigt: Comparison of failed rendering (in background) and correct (in front).

Das Problem besteht darin, ein Signal zum Verbinden zu finden, um das transparente Fenster neu zu initialisieren, oder noch besser zu erkennen, wenn Fenster transparent gezeichnet werden und die Benutzeroberfläche entsprechend zu zeichnen. Alternative Lösungen sind ebenfalls willkommen.

Antwort

2

Nach dem Graben in Qt und MSDN Aero documentation kam ich mit einer zweistufigen Lösung. Durch Überschreiben der winEvent Methode meines Hauptfensters konnte ich das Signal empfangen, das jedes Mal ausgelöst wird, wenn das durchscheinende Fenstersystem aktiviert oder deaktiviert wird.

Das hat mich ziemlich nah gebracht, aber es hat mir nicht gesagt, ob DWM gerade transparente Fenster zeichnete oder nicht. Durch dwmapi.dll Verwendung konnte ich eine Methode finden, die genau das tut, und es kann wie unten zugegriffen werden:

// 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; 
} 

Meine Umsetzung nun in der Lage ist, auf Veränderungen in Aero zu reagieren und die GUI entsprechend ziehen. Wenn Sie sich über den Remote-Desktop anmelden, wird das Fenster, wo verfügbar, auch mit Transparenz gezeichnet.

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