2012-07-11 22 views
5

QMLを使用してQtを使用してQt/C++アプリケーションを作成しています。ウィンドウの下では、ウィンドウクラスのこのスニペットに見られるように、ExtendFrameIntoClientAreaを使用して半透明ウィンドウを使用したいと思います。QT半透明のウィンドウとリモートデスクトップ

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

コードは1つの例外を除いてうまく機能しています。透過ウィンドウシステムがオフになっていると背景が黒くなり、UIの一部が透明になるので暗くなります。透明なウィンドウシステムがすぐに再初期化されても、アプリケーションを実行しているリモートコンピュータにログインすると、同じコードが実行されます。 Comparison of failed rendering (in background) and correct (in front).

問題は、トランスペアレントウィンドウを再初期化するための信号を見つけることです。または、ウィンドウが透過的に描画されたことを検出し、それに応じてUIを描画する方が良いでしょう。代替ソリューションも歓迎します。

答えて

2

QtとMSDN Aero documentationの両方を掘り起こした後、私は2段階の解決策を思いついた。メインウィンドウのwinEventメソッドをオーバーライドすることで、半透明ウィンドウシステムが有効または無効になるたびにトリガされる信号を受け取ることができました。

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

私はかなり近かったが、DWMが現在透明なウィンドウを描画しているかどうかは教えてくれなかった。 dwmapi.dllを使用することにより、私はまさにその方法を見つけることができた、そしてそれは以下のようにアクセスすることができます。

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

私の実装は今エアロの変化に反応し、それに応じてGUIを描画することができます。リモートデスクトップにログインすると、透明性を利用してウィンドウが描画されます。

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; 
} 
関連する問題