QT半透明窗口和远程桌面

hg.*_*hg. 5 c++ windows qt aero qml

我正在为某些部分使用QML创建一个Qt/C++应用程序.在windows下我想使用ExtendFrameIntoClientArea的半透明窗口,如我的窗口类的这个片段所示.

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

代码运行良好,但有一个例外.如果关闭透明窗口系统,背景将变为黑色,并且由于我的UI的一部分是透明的,它也会变暗.登录到运行应用程序的远程计算机时会发生同样的事情,即使透明窗口系统立即重新初始化,背景保持黑色,直到再次执行上述代码.在此图像中演示了这一点:渲染失败(在背景中)和正确(在前面)的比较.

问题是找到一个连接重新初始化透明窗口的信号,或者更好地检测何时透明地绘制窗口并相应地绘制UI.任何替代解决方案也欢迎.

hg.*_*hg. 2

在深入研究 Qt 和MSDN Aero 文档后,我想出了一个两步解决方案。通过重写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;
}
Run Code Online (Sandbox Code Playgroud)

这让我非常接近,但它没有告诉我 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;
}
Run Code Online (Sandbox Code Playgroud)

我的实现现在能够对 Aero 中的更改做出反应并相应地绘制 GUI。通过远程桌面登录时,窗口也会使用透明度绘制(如果可用)。