-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAcrylicWindow.cpp
More file actions
160 lines (126 loc) · 5.83 KB
/
Copy pathAcrylicWindow.cpp
File metadata and controls
160 lines (126 loc) · 5.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <dcomp.h>
#include <dwmapi.h>
#include <wrl\implements.h>
#pragma comment(lib, "dcomp")
#pragma comment(lib, "dwmapi")
using namespace Microsoft::WRL;
struct CompositionAttrData { int Attrib; void* pvData; DWORD cbData; };
class AcrylicCompositor
{
public:
HWND hwnd;
HTHUMBNAIL topLevelWindowThumbnail;
ComPtr<IDCompositionDesktopDevice> device;
ComPtr<IDCompositionTranslateTransform> translateTransform;
ComPtr<IDCompositionVisual2> rootVisual;
ComPtr<IDCompositionTarget> target;
int x = GetSystemMetrics(SM_CXSCREEN);
int y = GetSystemMetrics(SM_CYSCREEN);
RECT sourceRect{ 0, 0, x, y };
SIZE destinationSize{ x, y };
typedef HRESULT(WINAPI* DwmpCreateSharedThumbnailVisual)(IN HWND hwndDestination, IN HWND hwndSource, IN DWORD dwThumbnailFlags, IN DWM_THUMBNAIL_PROPERTIES* pThumbnailProperties, IN VOID* pDCompDevice, OUT VOID** ppVisual, OUT PHTHUMBNAIL phThumbnailId);
typedef HRESULT(WINAPI* DwmpCreateSharedMultiWindowVisual)(IN HWND hwndDestination, IN VOID* pDCompDevice, OUT VOID** ppVisual, OUT PHTHUMBNAIL phThumbnailId);
typedef HRESULT(WINAPI* DwmpUpdateSharedMultiWindowVisual)(IN HTHUMBNAIL hThumbnailId, IN HWND* phwndsInclude, IN DWORD chwndsInclude, IN HWND* phwndsExclude, IN DWORD chwndsExclude, OUT RECT* prcSource, OUT SIZE* pDestinationSize, IN DWORD dwFlags);
typedef BOOL(WINAPI* SetCompAttr)(HWND, CompositionAttrData*);
HMODULE dwmapi = LoadLibrary(L"dwmapi.dll");
DwmpCreateSharedThumbnailVisual DwmCreateSharedThumbnailVisual = (DwmpCreateSharedThumbnailVisual)GetProcAddress(dwmapi, MAKEINTRESOURCEA(147));
DwmpCreateSharedMultiWindowVisual DwmCreateSharedMultiWindowVisual = (DwmpCreateSharedMultiWindowVisual)GetProcAddress(dwmapi, MAKEINTRESOURCEA(163));
DwmpUpdateSharedMultiWindowVisual DwmUpdateSharedMultiWindowVisual = (DwmpUpdateSharedMultiWindowVisual)GetProcAddress(dwmapi, MAKEINTRESOURCEA(164));
SetCompAttr DwmSetWindowCompositionAttribute = (SetCompAttr)GetProcAddress(LoadLibrary(L"user32.dll"), "SetWindowCompositionAttribute");
void ApplyAcrylic(HWND hwnd, int radius = 70, float saturation = 1.5)
{
this->hwnd = hwnd;
int enable = 1;
CompositionAttrData CompositionAttribute{ 13, &enable, sizeof(int) };
DwmSetWindowCompositionAttribute(hwnd, &CompositionAttribute);
Initialize();
CreateBackdrop();
CreateEffects(radius, saturation);
SyncCoordinates(hwnd);
}
void Initialize() {
DCompositionCreateDevice3(NULL, __uuidof (device), &device);
device->CreateTargetForHwnd(hwnd, FALSE, &target);
device->CreateVisual(&rootVisual);
target->SetRoot(rootVisual.Get());
device->CreateTranslateTransform(&translateTransform);
rootVisual->SetTransform(translateTransform.Get());
}
void CreateEffects(int radius, float saturation) {
ComPtr<IDCompositionDevice3> device3;
device->QueryInterface(__uuidof (IDCompositionDevice3), &device3);
ComPtr<IDCompositionSaturationEffect> saturationEffect;
device3->CreateSaturationEffect(&saturationEffect);
saturationEffect->SetSaturation(saturation);
ComPtr<IDCompositionGaussianBlurEffect> blurEffect;
device3->CreateGaussianBlurEffect(&blurEffect);
blurEffect->SetBorderMode(D2D1_BORDER_MODE_HARD);
blurEffect->SetStandardDeviation(radius);
blurEffect->SetInput(0, saturationEffect.Get(), 0);
rootVisual->SetEffect(blurEffect.Get());
}
void CreateBackdrop()
{
HTHUMBNAIL desktopThumbnail = NULL;
DWM_THUMBNAIL_PROPERTIES thumbnailProperties{};
thumbnailProperties.dwFlags = DWM_TNP_VISIBLE | DWM_TNP_RECTDESTINATION;
thumbnailProperties.fVisible = TRUE;
thumbnailProperties.rcDestination = sourceRect;
ComPtr<IDCompositionVisual2> desktopWindowVisual;
HWND desktopWindow = FindWindow(L"Progman", nullptr);
DwmCreateSharedThumbnailVisual(hwnd, desktopWindow, 2, &thumbnailProperties, device.Get(), &desktopWindowVisual, &desktopThumbnail);
ComPtr<IDCompositionVisual2> topLevelWindowVisual;
DwmCreateSharedMultiWindowVisual(hwnd, device.Get(), &topLevelWindowVisual, &topLevelWindowThumbnail);
rootVisual->AddVisual(desktopWindowVisual.Get(), false, NULL);
rootVisual->AddVisual(topLevelWindowVisual.Get(), true, desktopWindowVisual.Get());
}
void SyncCoordinates(HWND hwnd)
{
RECT hostWindowRect{};
GetWindowRect(hwnd, &hostWindowRect);
translateTransform->SetOffsetX(-hostWindowRect.left - (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER)));
translateTransform->SetOffsetY(-hostWindowRect.top - GetSystemMetrics(SM_CYCAPTION));
DwmUpdateSharedMultiWindowVisual(topLevelWindowThumbnail, nullptr, 0, NULL, 0, &sourceRect, &destinationSize, 1);
device->Commit();
}
};
AcrylicCompositor compositor;
#ifdef BUILD_DLL
extern "C" __declspec(dllexport) void ApplyAcrylic(HWND hwnd, int radius, float saturation) { compositor.ApplyAcrylic(hwnd, radius, saturation); }
extern "C" __declspec(dllexport) void SyncWindowPosition(HWND hwnd) { compositor.SyncCoordinates(hwnd); }
#else
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
bool acrylicEnabled;
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = L"Acrylic Window";
RegisterClass(&wc);
HWND hwnd = CreateWindowEx(WS_EX_NOREDIRECTIONBITMAP, wc.lpszClassName, wc.lpszClassName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
compositor.ApplyAcrylic(hwnd);
acrylicEnabled = true;
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_WINDOWPOSCHANGED:
if (acrylicEnabled) compositor.SyncCoordinates(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
#endif