我想模糊一个窗口,我使用了DwmEnableBlurBehindWindow()
、DwmExtendFrameIntoClientArea()
和DwmSetWindowAttribute()
(以启用工作区呈现)。然而,它没有模糊,反而使客户区域变白。
最低可复制代码:
#include <dwmapi.h>
#include <gdiplus.h>
#include <stdio.h>
#include <windows.h>
HWND hwnd;
HRESULT enableNCRendering(HWND hWnd)
{
enum DWMNCRENDERINGPOLICY ncrp = DWMNCRP_ENABLED;
HRESULT hr = DwmSetWindowAttribute(hWnd,
DWMWA_NCRENDERING_POLICY,
&ncrp,
sizeof(ncrp));
if (!SUCCEEDED(hr))
printf("Failed 0\n");
return hr;
}
HRESULT EnableBlurBehind(HWND hwnd)
{
DWM_BLURBEHIND bb = {0};
bb.dwFlags = DWM_BB_ENABLE;
bb.fEnable = true;
bb.hRgnBlur = NULL;
HRESULT hr = DwmEnableBlurBehindWindow(hwnd, &bb);
if (!SUCCEEDED(hr))
printf("Failed 1\n");
return hr;
}
HRESULT ExtendIntoClientAll(HWND hwnd)
{
MARGINS margins = {-1};
HRESULT hr = DwmExtendFrameIntoClientArea(hwnd, &margins);
if (!SUCCEEDED(hr))
printf("Failed 2\n");
return hr;
}
ATOM MyRegisterClass(HINSTANCE hInst, LPCWSTR name, UINT styles, COLORREF bkg_colour, WNDPROC proc)
{
WNDCLASSEXW wc;
wc.cbSize = sizeof(WNDCLASSEXW);
wc.style = styles;
wc.lpfnWndProc = proc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIconW(hInst, (LPCWSTR)IDI_APPLICATION);
wc.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
wc.hbrBackground = (HBRUSH)CreateSolidBrush(bkg_colour); // CreateSolidBrush(RGB(255, 0, 0))
wc.lpszMenuName = NULL;
wc.hIconSm = LoadIconW(hInst, (LPCWSTR)IDI_APPLICATION);
wc.lpszClassName = (LPCWSTR)name;
return RegisterClassExW(&wc);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch (msg)
{
case WM_NCHITTEST:
return HTCAPTION;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProcW(hwnd, msg, wp, lp);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
MyRegisterClass(hInstance, L"Main", CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, RGB(255, 0, 0), WndProc);
hwnd = CreateWindowExW(WS_EX_LAYERED, L"Main", L"main", WS_POPUP, 0, 0, 1000, 500, NULL, NULL, hInstance, NULL);
if (!hwnd)
return 1;
SetLayeredWindowAttributes(hwnd, 0, 100, LWA_ALPHA);
enableNCRendering(hwnd);
EnableBlurBehind(hwnd);
ExtendIntoClientAll(hwnd);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessageW(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return msg.wParam;
}
我也尝试过SetWindowCompositionAttributes()
,但是它在明威中还没有定义,而且我也找不到很多关于使用它的信息。它也没有达到预期的效果,而且几乎没有任何模糊:
#include <Winerror.h>
#include <dwmapi.h>
#include <gdiplus.h>
#include <stdio.h>
#include <windows.h>
HWND hwnd;
struct ACCENTPOLICY
{
int na;
int nf;
int nc;
int nA;
};
struct WINCOMPATTRDATA
{
int na;
PVOID pd;
ULONG ul;
};
typedef BOOL(WINAPI* pSetWindowCompositionAttribute)(HWND, WINCOMPATTRDATA*);
void makeBlur()
{
const HINSTANCE hm = LoadLibraryW(L"user32.dll");
if (hm)
{
const pSetWindowCompositionAttribute SetWindowCompositionAttribute = (pSetWindowCompositionAttribute)GetProcAddress(hm, "SetWindowCompositionAttribute");
if (SetWindowCompositionAttribute)
{
struct ACCENTPOLICY policy = {3, 0, 0, 0};
struct WINCOMPATTRDATA data = {19, &policy, sizeof(ACCENTPOLICY)};
SetWindowCompositionAttribute(hwnd, &data);
}
FreeLibrary(hm);
}
}
ATOM MyRegisterClass(HINSTANCE hInst, LPCWSTR name, UINT styles, COLORREF bkg_colour, WNDPROC proc)
{
WNDCLASSEXW wc;
wc.cbSize = sizeof(WNDCLASSEXW);
wc.style = styles;
wc.lpfnWndProc = proc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIconW(hInst, (LPCWSTR)IDI_APPLICATION);
wc.hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW);
wc.hbrBackground = (HBRUSH)CreateSolidBrush(bkg_colour); // CreateSolidBrush(RGB(255, 0, 0))
wc.lpszMenuName = NULL;
wc.hIconSm = LoadIconW(hInst, (LPCWSTR)IDI_APPLICATION);
wc.lpszClassName = (LPCWSTR)name;
return RegisterClassExW(&wc);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch (msg)
{
case WM_NCHITTEST:
return HTCAPTION;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProcW(hwnd, msg, wp, lp);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
//getting accent colors
DWORD color = 0;
BOOL opaque = FALSE;
DwmGetColorizationColor(&color, &opaque);
BYTE blue = color;
color = color >> 8;
BYTE green = color;
color = color >> 8;
BYTE red = color;
color = color >> 8;
BYTE alpha = color;
MyRegisterClass(hInstance, L"Main", CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, RGB(red, green, blue), WndProc);
hwnd = CreateWindowExW(WS_EX_LAYERED, L"Main", L"main", WS_POPUP, 0, 0, 1000, 500, NULL, NULL, hInstance, NULL);
if (!hwnd)
return 1;
SetLayeredWindowAttributes(hwnd, 0, 100, LWA_ALPHA);
makeBlur();
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessageW(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return msg.wParam;
}
我怎么才能把我的窗户弄模糊?
发布于 2022-11-27 05:32:19
DwmEnableBlurBehindWindow
documentation指出:
从Windows 8开始,调用此函数并不会导致模糊效果,原因是窗口呈现方式发生了样式变化。
Aero玻璃在Windows 8中正式停用。然而,由于任务栏和一些系统通知仍在使用,Aero玻璃在Windows 10中重新出现(某种程度上)。现在您必须使用无文档化的SetWindowCompositionAttribute()
API来启用模糊效果,请参见:
How do you set the glass blend colour on Windows 10?
您正在寻找ACCENT_ENABLE_BLURBEHIND
选项。
https://stackoverflow.com/questions/74582735
复制相似问题