From 5796b966bf76716137c74a1eb07c75d7b3a9e9ed Mon Sep 17 00:00:00 2001 From: Christopher Pelloux Date: Tue, 23 Feb 2016 23:40:22 -0500 Subject: [PATCH] add transparent window support for Windows Vista and up --- examples/gears.c | 1 + src/win32_init.c | 2 ++ src/win32_platform.h | 12 ++++++++++++ src/win32_window.c | 13 +++++++++++++ 4 files changed, 28 insertions(+) diff --git a/examples/gears.c b/examples/gears.c index c5897dcca..7e3ca4391 100644 --- a/examples/gears.c +++ b/examples/gears.c @@ -314,6 +314,7 @@ int main(int argc, char *argv[]) glfwWindowHint(GLFW_DEPTH_BITS, 16); glfwWindowHint(GLFW_ALPHA_BITS, 8); glfwWindowHint(GLFW_TRANSPARENT, GLFW_TRUE); + glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL ); if (!window) diff --git a/src/win32_init.c b/src/win32_init.c index 57acdb3ae..8029999a1 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -97,6 +97,8 @@ static GLFWbool loadLibraries(void) GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); _glfw.win32.dwmapi.DwmFlush = (DWMFLUSH_T) GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush"); + _glfw.win32.dwmapi.DwmEnableBlurBehindWindow = (DWMENABLEBLURBEHINDWINDOW_T) + GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow"); } _glfw.win32.shcore.instance = LoadLibraryA("shcore.dll"); diff --git a/src/win32_platform.h b/src/win32_platform.h index 47b4999a6..eabf40376 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -120,21 +120,32 @@ typedef enum PROCESS_DPI_AWARENESS } PROCESS_DPI_AWARENESS; #endif /*DPI_ENUMS_DECLARED*/ +typedef struct _DWM_BLURBEHIND +{ + DWORD dwFlags; + BOOL fEnable; + HRGN hRgnBlur; + BOOL fTransitionOnMaximized; +} DWM_BLURBEHIND, *PDWM_BLURBEHIND; + // winmm.dll function pointer typedefs typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T)(UINT,LPJOYCAPS,UINT); typedef MMRESULT (WINAPI * JOYGETPOS_T)(UINT,LPJOYINFO); typedef MMRESULT (WINAPI * JOYGETPOSEX_T)(UINT,LPJOYINFOEX); typedef DWORD (WINAPI * TIMEGETTIME_T)(void); +typedef HRESULT(WINAPI * DWMENABLEBLURBEHINDWINDOW_T)(HWND, const DWM_BLURBEHIND*); #define _glfw_joyGetDevCaps _glfw.win32.winmm.joyGetDevCaps #define _glfw_joyGetPos _glfw.win32.winmm.joyGetPos #define _glfw_joyGetPosEx _glfw.win32.winmm.joyGetPosEx #define _glfw_timeGetTime _glfw.win32.winmm.timeGetTime +#define _glfw_DwmEnableBlurBehindWindow _glfw.win32.dwmapi.DwmEnableBlurBehindWindow // user32.dll function pointer typedefs typedef BOOL (WINAPI * SETPROCESSDPIAWARE_T)(void); typedef BOOL (WINAPI * CHANGEWINDOWMESSAGEFILTEREX_T)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT); #define _glfw_SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware #define _glfw_ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx +#define _glfw_DwmEnableBlurBehindWindow _glfw.win32.dwmapi.DwmEnableBlurBehindWindow // dwmapi.dll function pointer typedefs typedef HRESULT (WINAPI * DWMISCOMPOSITIONENABLED_T)(BOOL*); @@ -237,6 +248,7 @@ typedef struct _GLFWlibraryWin32 HINSTANCE instance; DWMISCOMPOSITIONENABLED_T DwmIsCompositionEnabled; DWMFLUSH_T DwmFlush; + DWMENABLEBLURBEHINDWINDOW_T DwmEnableBlurBehindWindow; } dwmapi; // shcore.dll diff --git a/src/win32_window.c b/src/win32_window.c index 5bbd04096..13375bdf3 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -732,6 +732,19 @@ static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) window->win32.numer = GLFW_DONT_CARE; window->win32.denom = GLFW_DONT_CARE; + // Accelerated transparent windows + // It currently doesn't support decorated windows. + // If decorated is required we just return an opaque window. + // Since DwmEnableBlurBehindWindow is supported since Vista, + // previous versions will simply get an opaque window. + if (!window->decorated && _glfw_DwmEnableBlurBehindWindow && window->transparent) { + DWM_BLURBEHIND bb = { 0 }; + bb.dwFlags = 3; // DWM_BB_ENABLE | DWM_BB_BLURREGION + bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1); // an invalid hRgnBlur makes the the window transparent + bb.fEnable = TRUE; + _glfw_DwmEnableBlurBehindWindow(window->win32.handle, &bb); + } + return GLFW_TRUE; }