c++ - QT半透明窗口和远程桌面

标签 c++ windows qt qml aero

我正在为某些部分使用 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

代码运行良好,但有一个异常(exception)。如果关闭透明窗口系统,背景会变成黑色,并且由于我的 UI 的一部分是透明的,它也会变暗。登录到运行应用程序的远程计算机时也会发生同样的事情,即使立即重新初始化透明窗口系统,背景也会保持黑色,直到再次执行上述代码。此图像对此进行了演示:Comparison of failed rendering (in background) and correct (in front).

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

最佳答案

在 Qt 和 MSDN Aero documentation 中深入挖掘之后我想出了一个两步解决方案。通过覆盖主窗口的 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;
}

我的实现现在能够对 Aero 中的变化使用react并相应地绘制 GUI。当通过远程桌面登录时,窗口也会在可用的情况下使用透明度绘制。

关于c++ - QT半透明窗口和远程桌面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11428597/

相关文章:

c++ - 用于 SPI 通信的互斥锁

windows - SQL Server 命令行实用程序 (sqlcmd.exe) 的 Oracle 等效项是什么?

windows - BATCH — 将命令输出存储到变量

qt - QML:当后一种方法具有优势时,是否有任何理由设置上下文属性而不是在根对象上设置属性?

c++ - 服务器端的 WebSockets 握手回复,草稿 00

c++ - spirit x3 如何将 vector 添加到 AST

c++ - 从函数和复制构造函数返回的对象

c++ - 在屏幕上移动矩形时 SFML 滞后/小口吃

windows - Ansible:检测证书是否已安装在证书存储中的最佳方法

windows - 为什么 Qt 让开发人员为每个应用程序包含他们的 dll?