Полупрозрачное окно QT и удаленный рабочий стол

Я создаю приложение Qt/C++, используя QML для некоторых частей. Под окнами я хотел бы использовать полупрозрачное окно, используя ExtendFrameIntoClientArea, как показано в этом фрагменте из моего класса окна.

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

Код работает хорошо, за одним исключением. Если прозрачная оконная система отключена, фон становится черным, а поскольку часть моего пользовательского интерфейса прозрачна, он также становится темным. То же самое происходит при входе в систему на удаленном компьютере, на котором запущено приложение, даже если прозрачная оконная система повторно инициализируется немедленно, фон остается черным, пока приведенный выше код не будет выполнен снова. Это показано на этом изображении: Сравнение неудачного рендеринга (на заднем плане) и правильного (на переднем плане).< /а>

Проблема заключается в том, чтобы найти сигнал для подключения к повторной инициализации прозрачного окна или, что еще лучше, определить, когда окна отрисовываются прозрачными, и соответствующим образом отрисовать пользовательский интерфейс. Также приветствуются любые альтернативные решения.


person hg.    schedule 11.07.2012    source источник


Ответы (1)


После изучения 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;
}

Это очень близко подобрало меня, но не сказало, рисует ли 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 и соответствующим образом рисовать графический интерфейс. При входе в систему через удаленный рабочий стол окно также отображается с использованием прозрачности, где это возможно.

person hg.    schedule 23.07.2012