Showing posts with label DwmExtendFrameIntoClientArea. Show all posts
Showing posts with label DwmExtendFrameIntoClientArea. Show all posts

Thursday, March 31, 2011

Qt Windows 7 extend frame into client area with transparency

I wanted to have something similar to these below:


Making the window transparent did not help me much. I was getting this:

I could not get rid of the margins.

After some research I figured out, and the result can be seen below:




To get merge the margins with the window frame it is enough to call DwmExtendFrameIntoClientArea with the margins value set to -1.

void ExtendFrameIntoClientArea(QWidget* widget) {
    MARGINS margins = {-1};

    DwmExtendFrameIntoClientArea(widget->winId(), &margins);
}


The transparency part is easy, it was published long time ago:

long EnableBlurBehindWidget(QWidget* widget, bool enable)
{
    HWND hwnd = widget->winId();
    HRESULT hr = S_OK;

    widget->setAttribute(Qt::WA_TranslucentBackground, enable);
    widget->setAttribute(Qt::WA_NoSystemBackground, enable);

    // Create and populate the Blur Behind structure
    DWM_BLURBEHIND bb = {0};

    bb.dwFlags = DWM_BB_ENABLE;
    bb.fEnable = enable;
    bb.hRgnBlur = NULL;

    DwmEnableBlurBehindWindow(hwnd, &bb);
    return hr;
}

I have managed to compile this using MINGW. The DwmEnableBlurBehindWindow and DwmExtendFrameIntoClientArea are loaded directly from dwmapi.dll.

#include <windows.h>

#define DWM_BB_ENABLE                 0x00000001  // fEnable has been specified

typedef struct _DWM_BLURBEHIND
{
    DWORD dwFlags;
    BOOL fEnable;
    HRGN hRgnBlur;
    BOOL fTransitionOnMaximized;
} DWM_BLURBEHIND, *PDWM_BLURBEHIND;

typedef struct _MARGINS
{
    int cxLeftWidth;      // width of left border that retains its size
    int cxRightWidth;     // width of right border that retains its size
    int cyTopHeight;      // height of top border that retains its size
    int cyBottomHeight;   // height of bottom border that retains its size
} MARGINS, *PMARGINS;

extern "C"
{
    typedef HRESULT (WINAPI *t_DwmEnableBlurBehindWindow)(HWND hWnd, const DWM_BLURBEHIND* pBlurBehind);
    typedef HRESULT (WINAPI *t_DwmExtendFrameIntoClientArea)(HWND hwnd, const MARGINS *pMarInset);
}

void DwmExtendFrameIntoClientArea(HWND hwnd, const MARGINS *pMarInset) {
    HMODULE shell;

    shell = LoadLibrary(L"dwmapi.dll");
    if (shell) {
        t_DwmExtendFrameIntoClientArea set_window_frame_into_client_area = reinterpret_cast<t_DwmExtendFrameIntoClientArea>(GetProcAddress (shell, "DwmExtendFrameIntoClientArea"));
        set_window_frame_into_client_area(hwnd, pMarInset);

        FreeLibrary (shell);
    }

}

void DwmEnableBlurBehindWindow(HWND hwnd, const DWM_BLURBEHIND* pBlurBehind) {
    HMODULE shell;

    shell = LoadLibrary(L"dwmapi.dll");
    if (shell) {
        t_DwmEnableBlurBehindWindow set_window_blur = reinterpret_cast<t_DwmEnableBlurBehindWindow>(GetProcAddress (shell, "DwmEnableBlurBehindWindow"));
        set_window_blur(hwnd, pBlurBehind);

        FreeLibrary (shell);
    }
}

The project can be downloaded from here.