Direct2D 简单实现窗口透明
不需要设置多余的WS_EX_XXX样式,主要就两步
第一步是开启DWM的Alpha透明混合,
也就是创建窗口后,调用EnableAlphaCompositing这个函数,
这个函数是glfw里面的(updateFramebufferTransparency),具体可以去看做了什么。
第二步要配置Direct2D RenderTarget的props,也就是设置
D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED)
支持Alpha混合模式
这样就可以设置Direct2D的alpha值来控制窗口的透明度了,窗口边框之类的,自行修改样式解决。
1 #include <d2d1.h> 2 #include <dwmapi.h> 3 #include <versionhelpers.h> 4 #pragma comment(lib, "dwmapi") 5 #pragma comment(lib, "d2d1.lib") 6 7 8 static ID2D1Factory* sg_pID2D1Factory = nullptr; 9 static ID2D1HwndRenderTarget* sg_pRenderTarget = nullptr; 10 11 12 // https://github.com/glfw/glfw/blob/master/src/win32_window.c#L368C27-L368C27 13 bool EnableAlphaCompositing(HWND hWnd) 14 { 15 if (!::IsWindowsVistaOrGreater()) { return false; } 16 17 BOOL is_composition_enable = false; 18 ::DwmIsCompositionEnabled(&is_composition_enable); 19 if (!is_composition_enable) { return true; } 20 21 DWORD current_color = 0; 22 BOOL is_opaque = false; 23 ::DwmGetColorizationColor(¤t_color, &is_opaque); 24 25 if (!is_opaque || IsWindows8OrGreater()) 26 { 27 HRGN region = ::CreateRectRgn(0, 0, -1, -1); 28 DWM_BLURBEHIND bb = { 0 }; 29 bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; 30 bb.hRgnBlur = region; 31 bb.fEnable = TRUE; 32 ::DwmEnableBlurBehindWindow(hWnd, &bb); 33 ::DeleteObject(region); 34 return true; 35 } 36 else // For Window7 37 { 38 DWM_BLURBEHIND bb = { 0 }; 39 bb.dwFlags = DWM_BB_ENABLE; 40 ::DwmEnableBlurBehindWindow(hWnd, &bb); 41 return false; 42 } 43 } 44 45 46 LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 47 { 48 if (uMsg == WM_PAINT) 49 { 50 sg_pRenderTarget->BeginDraw(); 51 sg_pRenderTarget->Clear(D2D1::ColorF(0.2f, 0.3f, 0.5f, 0.5f)); 52 sg_pRenderTarget->EndDraw(); 53 } 54 55 return DefWindowProcW(hWnd, uMsg, wParam, lParam); 56 } 57 58 59 int main() 60 { 61 // 窗口类定义 62 WNDCLASSEXW wcx = { 0 }; 63 wcx.cbSize = sizeof(wcx); 64 wcx.lpfnWndProc = WindowProc; 65 wcx.lpszClassName = L"Test Class"; 66 wcx.hInstance = GetModuleHandleW(nullptr); 67 68 // 注册窗口类 69 ::RegisterClassExW(&wcx); 70 71 //创建窗口 72 HWND hwnd = ::CreateWindowExW 73 ( 74 NULL, wcx.lpszClassName, L"Main Window", WS_OVERLAPPEDWINDOW, 75 CW_USEDEFAULT, CW_USEDEFAULT, 1280, 720, 76 nullptr, nullptr, wcx.hInstance, nullptr 77 ); 78 79 // 开启Alpha通道混合 80 EnableAlphaCompositing(hwnd); 81 82 // 创建Direct2D资源 83 { 84 D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &sg_pID2D1Factory); 85 86 RECT rc = { 0 }; 87 GetClientRect(hwnd, &rc); 88 D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top); 89 90 D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties 91 ( 92 D2D1_RENDER_TARGET_TYPE_DEFAULT, 93 D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED) 94 ); 95 sg_pID2D1Factory->CreateHwndRenderTarget(props, D2D1::HwndRenderTargetProperties(hwnd, size), &sg_pRenderTarget); 96 } 97 98 // 显示窗口 99 ShowWindow(hwnd, SW_NORMAL); 100 101 // 消息循环 102 MSG msg = { 0 }; 103 while (GetMessageW(&msg, nullptr, 0, 0)) 104 { 105 ::TranslateMessage(&msg); 106 ::DispatchMessageW(&msg); 107 } 108 109 // 清理Direct2D资源 110 sg_pRenderTarget->Release(); 111 sg_pID2D1Factory->Release(); 112 113 // 注销窗口类 114 UnregisterClassW(wcx.lpszClassName, wcx.hInstance); 115 }