From af16fcac2fadb78a137934171d021b4242563d7e Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Tue, 1 Apr 2014 15:37:40 +0200 Subject: Windows DWM support --- test/Makefile | 4 ++-- test/layered.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++--------- wglarb.c | 2 +- 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/test/Makefile b/test/Makefile index 05fd8ee..78ae707 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,6 +1,6 @@ -CC=x86_64-w64-mingw32-gcc +CC=i686-w64-mingw32-gcc CFLAGS=-static-libgcc -static-libstdc++ -I.. -LIBS=-lopengl32 -lgdi32 +LIBS=-lopengl32 -lgdi32 -lkernel32 layered.exe: layered.c $(CC) $(CFLAGS) -o layered.exe layered.c ../wglarb.c $(LIBS) diff --git a/test/layered.c b/test/layered.c index 26f0c02..41a7127 100644 --- a/test/layered.c +++ b/test/layered.c @@ -8,15 +8,24 @@ #include #include +#include LRESULT CALLBACK ViewProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); void reshape(int w,int h); void display(); -HWND hWnd; -HDC hDC; -HGLRC hRC; +HWND hWnd = NULL; +HDC hDC = NULL; +HGLRC hRC = NULL; + +HMODULE hDwmAPI_DLL = NULL; + +typedef HRESULT (WINAPI *procp_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND *); +procp_DwmEnableBlurBehindWindow impl_DwmEnableBlurBehindWindow = NULL; + +typedef HRESULT (WINAPI *procp_DwmExtendFrameIntoClientArea)(HWND, MARGINS const*); +procp_DwmExtendFrameIntoClientArea impl_DwmExtendFrameIntoClientArea = NULL; int win_width; int win_height; @@ -57,8 +66,8 @@ BOOL OpenGLWindowCreate( hWnd = CreateWindowEx( dwExStyle, wc.lpszClassName, lpszWindowName, - dwStyle, - 0,0,100,100, + dwStyle | WS_CLIPSIBLINGS|WS_CLIPCHILDREN, + 240,240,640,640, NULL,NULL, hInstance, NULL); @@ -82,7 +91,8 @@ BOOL OpenGLWindowCreate( WGL_DOUBLE_BUFFER_ARB, TRUE, WGL_SUPPORT_OPENGL_ARB, TRUE, WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, - WGL_COLOR_BITS_ARB, 24, + WGL_TRANSPARENT_ARB, TRUE, + WGL_COLOR_BITS_ARB, 32, WGL_RED_BITS_ARB, 8, WGL_GREEN_BITS_ARB, 8, WGL_BLUE_BITS_ARB, 8, @@ -93,7 +103,6 @@ BOOL OpenGLWindowCreate( }; INT iPF; - PIXELFORMATDESCRIPTOR pfd; fprintf(stderr, "choosing proper pixelformat...\n"); UINT num_formats_choosen; if( !wglarb_ChoosePixelFormatARB( @@ -106,7 +115,12 @@ BOOL OpenGLWindowCreate( fprintf(stderr, "error choosing proper pixel format\n"); return FALSE; } + if( !num_formats_choosen ) { + return FALSE; + } + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(pfd)); /* now this is a kludge; we need to pass something in the PIXELFORMATDESCRIPTOR * to SetPixelFormat; it will be ignored, mostly. OTOH we want to send something * sane, we're nice people after all - it doesn't hurt if this fails. */ @@ -138,7 +152,24 @@ BOOL OpenGLWindowCreate( /* Finally we can bind the proper OpenGL context to our window */ wglMakeCurrent(hDC, hRC); - SetLayeredWindowAttributes(hWnd, RGB(0,0,0), 0xff, LWA_ALPHA); + if( hDwmAPI_DLL ) { + if( impl_DwmEnableBlurBehindWindow ) { + DWM_BLURBEHIND bb = {0}; + bb.dwFlags = DWM_BB_ENABLE; + bb.fEnable = TRUE; + bb.hRgnBlur = NULL; + impl_DwmEnableBlurBehindWindow(hWnd, &bb); + } + + if( impl_DwmExtendFrameIntoClientArea ) { + MARGINS margins = {-1}; + impl_DwmExtendFrameIntoClientArea(hWnd, &margins); + } + } + else { + SetLayeredWindowAttributes(hWnd, 0, 0xff, LWA_ALPHA); + } + UpdateWindow(hWnd); ShowWindow(hWnd, SW_SHOW); @@ -215,7 +246,7 @@ void display() win_width, win_height); - glClearColor(0., 0., 0., 0.25); + glClearColor(0., 0., 0., 0.); glClearDepth(1.); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -235,6 +266,9 @@ void display() 0., sin60, 0., 0., 1. }; + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); @@ -244,6 +278,7 @@ void display() glDrawArrays(GL_TRIANGLES, 0, 3); SwapBuffers(hDC); + glFinish(); } int CALLBACK WinMain( @@ -255,12 +290,23 @@ int CALLBACK WinMain( MSG msg; BOOL bRet; + hDwmAPI_DLL = LoadLibrary("dwmapi.dll"); + if( hDwmAPI_DLL ) { + impl_DwmEnableBlurBehindWindow = + (procp_DwmEnableBlurBehindWindow) + GetProcAddress(hDwmAPI_DLL, "DwmEnableBlurBehindWindow"); + + impl_DwmExtendFrameIntoClientArea = + (procp_DwmExtendFrameIntoClientArea) + GetProcAddress(hDwmAPI_DLL, "DwmExtendFrameIntoClientArea"); + } + if( !OpenGLWindowCreate( "Test", "TestWnd", ViewProc, hInstance, WS_OVERLAPPEDWINDOW, - WS_EX_APPWINDOW | WS_EX_LAYERED) ) { + WS_EX_APPWINDOW) ) { return -1; } @@ -272,6 +318,7 @@ int CALLBACK WinMain( TranslateMessage(&msg); DispatchMessage(&msg); } + display(); } return msg.wParam; } diff --git a/wglarb.c b/wglarb.c index 383b5f7..744db0b 100644 --- a/wglarb.c +++ b/wglarb.c @@ -23,7 +23,7 @@ THE SOFTWARE. #include "wglarb.h" #define WGLARB_INTERMEDIARY_CLASS "wglarb intermediary" -#define WGLARB_INTERMEDIARY_STYLE 0 +#define WGLARB_INTERMEDIARY_STYLE (WS_CLIPSIBLINGS|WS_CLIPCHILDREN) #define WGLARB_INTERMEDIARY_EXSTYLE 0 static HWND wglarb_intermediary_hWnd = 0; -- cgit v1.2.3