| 1 | #include <windows.h>
|
|---|
| 2 | #include <windowsx.h>
|
|---|
| 3 | #include <tchar.h>
|
|---|
| 4 | #include <uxtheme.h>
|
|---|
| 5 | #include <dwmapi.h>
|
|---|
| 6 | #include <assert.h>
|
|---|
| 7 | #include <richedit.h>
|
|---|
| 8 |
|
|---|
| 9 | struct Dll {
|
|---|
| 10 | decltype(&DwmExtendFrameIntoClientArea) DwmExtendFrameIntoClientArea;
|
|---|
| 11 | decltype(&DwmIsCompositionEnabled) DwmIsCompositionEnabled;
|
|---|
| 12 | decltype(&DwmEnableBlurBehindWindow) DwmEnableBlurBehindWindow;
|
|---|
| 13 | decltype(&DwmGetColorizationColor) DwmGetColorizationColor;
|
|---|
| 14 | decltype(&DwmGetWindowAttribute) DwmGetWindowAttribute;
|
|---|
| 15 | decltype(&BeginBufferedPaint) BeginBufferedPaint;
|
|---|
| 16 | decltype(&BufferedPaintInit) BufferedPaintInit;
|
|---|
| 17 | decltype(&BufferedPaintUnInit) BufferedPaintUnInit;
|
|---|
| 18 | decltype(&EndBufferedPaint) EndBufferedPaint;
|
|---|
| 19 | decltype(&BufferedPaintSetAlpha) BufferedPaintSetAlpha;
|
|---|
| 20 | } dll = {};
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 | struct BlurStatus {
|
|---|
| 24 | BlurStatus() :
|
|---|
| 25 | capture(false),
|
|---|
| 26 | focus(false),
|
|---|
| 27 | dc_width_max(0),
|
|---|
| 28 | dc_width(0),
|
|---|
| 29 | dc_height_max(0),
|
|---|
| 30 | dc_height(0),
|
|---|
| 31 | dc_changed(false),
|
|---|
| 32 | dc1(NULL),
|
|---|
| 33 | dc2(NULL)
|
|---|
| 34 | {
|
|---|
| 35 | black_brush = (HBRUSH)GetStockObject(BLACK_BRUSH);
|
|---|
| 36 |
|
|---|
| 37 | blend_function.BlendOp = AC_SRC_OVER;
|
|---|
| 38 | blend_function.BlendFlags = 0;
|
|---|
| 39 | blend_function.AlphaFormat = 0; //AC_SRC_ALPHA
|
|---|
| 40 | blend_function.SourceConstantAlpha = 255;
|
|---|
| 41 |
|
|---|
| 42 | bp_paintparams.cbSize = sizeof(bp_paintparams);
|
|---|
| 43 | bp_paintparams.dwFlags = 0;
|
|---|
| 44 | bp_paintparams.prcExclude = NULL;
|
|---|
| 45 | bp_paintparams.pBlendFunction = &blend_function;
|
|---|
| 46 | }
|
|---|
| 47 | WNDPROC DefaultWindowProceduer;
|
|---|
| 48 | bool capture;
|
|---|
| 49 | bool focus;
|
|---|
| 50 | HBRUSH black_brush;
|
|---|
| 51 | int dc_width_max;
|
|---|
| 52 | int dc_height_max;
|
|---|
| 53 | int dc_width;
|
|---|
| 54 | int dc_height;
|
|---|
| 55 | bool dc_changed;
|
|---|
| 56 | HDC dc1;
|
|---|
| 57 | HDC dc2;
|
|---|
| 58 | BLENDFUNCTION blend_function;
|
|---|
| 59 | BP_PAINTPARAMS bp_paintparams;
|
|---|
| 60 | } blur;
|
|---|
| 61 |
|
|---|
| 62 | LRESULT CALLBACK BlurEditWndProc(
|
|---|
| 63 | HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
|---|
| 64 |
|
|---|
| 65 | WNDPROC wp = BlurEditWndProc;
|
|---|
| 66 | (void)wp;
|
|---|
| 67 |
|
|---|
| 68 | // TODO: �}�E�X�h���b�O���ɁA�I��͂�������
|
|---|
| 69 | // �����AWM_ERASEBKGND�Ƃ��A������M_PAINT����ɏ����ĕ`�悵�₪�� // �f�o�C�X�R���e�L�X�g���w�������������ǂ���������
|
|---|
| 70 |
|
|---|
| 71 | if (message == WM_SETFOCUS) {
|
|---|
| 72 | blur.focus = true;
|
|---|
| 73 | InvalidateRect(hWnd, 0, FALSE);
|
|---|
| 74 | }
|
|---|
| 75 |
|
|---|
| 76 | if (message == WM_KILLFOCUS) {
|
|---|
| 77 | blur.focus = false;
|
|---|
| 78 | InvalidateRect(hWnd, 0, FALSE);
|
|---|
| 79 | }
|
|---|
| 80 |
|
|---|
| 81 | if (message == WM_LBUTTONDOWN) {
|
|---|
| 82 | InvalidateRect(hWnd, 0, FALSE);
|
|---|
| 83 | }
|
|---|
| 84 |
|
|---|
| 85 | if (message == WM_LBUTTONDBLCLK) {
|
|---|
| 86 | InvalidateRect(hWnd, 0, FALSE);
|
|---|
| 87 | }
|
|---|
| 88 |
|
|---|
| 89 | if (message == WM_CAPTURECHANGED) {
|
|---|
| 90 | if ((HWND)lParam != hWnd && blur.capture) {
|
|---|
| 91 | ReleaseCapture();
|
|---|
| 92 | blur.capture = false;
|
|---|
| 93 | InvalidateRect(hWnd, 0, FALSE);
|
|---|
| 94 | }
|
|---|
| 95 | }
|
|---|
| 96 |
|
|---|
| 97 | if (message == WM_SIZE) {
|
|---|
| 98 | blur.dc_width = LOWORD(lParam);
|
|---|
| 99 | blur.dc_height = HIWORD(lParam);
|
|---|
| 100 | blur.dc_changed = true;
|
|---|
| 101 | }
|
|---|
| 102 |
|
|---|
| 103 | if (message == WM_WINDOWPOSCHANGED || message == WM_WINDOWPOSCHANGING) {
|
|---|
| 104 | const WINDOWPOS* pos = (WINDOWPOS*)lParam;
|
|---|
| 105 | if (!(pos->flags & SWP_NOSIZE)) {
|
|---|
| 106 | blur.dc_width = pos->cx;
|
|---|
| 107 | blur.dc_height = pos->cy;
|
|---|
| 108 | blur.dc_changed = true;
|
|---|
| 109 | }
|
|---|
| 110 | }
|
|---|
| 111 |
|
|---|
| 112 | if (message == WM_MOUSEMOVE) {
|
|---|
| 113 | // �}�E�X���E�B���h�E�����݂��邩�`�F�b�N
|
|---|
| 114 | bool redraw = false;
|
|---|
| 115 | RECT rect = {};
|
|---|
| 116 | POINT p = {};
|
|---|
| 117 | p.x = GET_X_LPARAM(lParam);
|
|---|
| 118 | p.y = GET_Y_LPARAM(lParam);
|
|---|
| 119 | if (!(wParam & MK_LBUTTON) &&
|
|---|
| 120 | (p.x < 0 ||
|
|---|
| 121 | p.y < 0 ||
|
|---|
| 122 | !GetWindowRect(hWnd, &rect) ||
|
|---|
| 123 | p.x >= (rect.right - rect.left) ||
|
|---|
| 124 | p.y >= (rect.bottom - rect.top)
|
|---|
| 125 | )) {
|
|---|
| 126 | // �f�[�^�擾���s���A�J�[�\�����E�B���h�E�O�ɂ��� if (blur.capture) {
|
|---|
| 127 | ReleaseCapture();
|
|---|
| 128 | blur.capture = false;
|
|---|
| 129 | redraw = true;
|
|---|
| 130 | }
|
|---|
| 131 | } else {
|
|---|
| 132 | // �J�[�\�����E�B���h�E������ if (!blur.capture) {
|
|---|
| 133 | SetCapture(hWnd);
|
|---|
| 134 | blur.capture = true;
|
|---|
| 135 | redraw = true;
|
|---|
| 136 | }
|
|---|
| 137 | }
|
|---|
| 138 |
|
|---|
| 139 | if (wParam & MK_LBUTTON) {
|
|---|
| 140 | redraw = true;
|
|---|
| 141 | }
|
|---|
| 142 |
|
|---|
| 143 | if (redraw) {
|
|---|
| 144 | InvalidateRect(hWnd, 0, FALSE);
|
|---|
| 145 | }
|
|---|
| 146 | }
|
|---|
| 147 |
|
|---|
| 148 |
|
|---|
| 149 | if (message == WM_PAINT) {
|
|---|
| 150 | BYTE alpha = 0;
|
|---|
| 151 | if (blur.focus) {
|
|---|
| 152 | alpha = 0xff;
|
|---|
| 153 | } else if (blur.capture) {
|
|---|
| 154 | alpha = 0xbb;
|
|---|
| 155 | } else {
|
|---|
| 156 | alpha = 0x88;
|
|---|
| 157 | }
|
|---|
| 158 |
|
|---|
| 159 | PAINTSTRUCT ps = {};
|
|---|
| 160 | HDC hdc = BeginPaint(hWnd, &ps);
|
|---|
| 161 | HDC mem_dc1 = NULL;
|
|---|
| 162 | HPAINTBUFFER paint_buffer1 = dll.BeginBufferedPaint(hdc, &ps.rcPaint, BPBF_TOPDOWNDIB, NULL, &mem_dc1);
|
|---|
| 163 | if (paint_buffer1 == 0) {
|
|---|
| 164 | EndPaint(hWnd, &ps);
|
|---|
| 165 | return CallWindowProc(blur.DefaultWindowProceduer, hWnd, message, wParam, lParam);
|
|---|
| 166 | }
|
|---|
| 167 |
|
|---|
| 168 | if (alpha == 255) {
|
|---|
| 169 | // �s�����̏ꍇ
|
|---|
| 170 | CallWindowProc(blur.DefaultWindowProceduer, hWnd, WM_PRINTCLIENT, (WPARAM)mem_dc1, PRF_CLIENT);
|
|---|
| 171 | dll.BufferedPaintSetAlpha(paint_buffer1, 0, 255);
|
|---|
| 172 | } else {
|
|---|
| 173 | // �����̏ꍇ�A�������f�o�C�X�R���e�L�X�g��������ăA���t�@�u�����h���� blur.blend_function.SourceConstantAlpha = alpha;
|
|---|
| 174 |
|
|---|
| 175 | HDC mem_dc2 = 0;
|
|---|
| 176 | HPAINTBUFFER paint_buffer2 = dll.BeginBufferedPaint(mem_dc1, &ps.rcPaint, BPBF_TOPDOWNDIB, &blur.bp_paintparams, &mem_dc2);
|
|---|
| 177 | if (paint_buffer2 == 0) {
|
|---|
| 178 | dll.EndBufferedPaint(paint_buffer1, FALSE);
|
|---|
| 179 | EndPaint(hWnd, &ps);
|
|---|
| 180 | return CallWindowProc(blur.DefaultWindowProceduer, hWnd, message, wParam, lParam);
|
|---|
| 181 | }
|
|---|
| 182 | CallWindowProc(blur.DefaultWindowProceduer, hWnd, WM_PRINTCLIENT, (WPARAM)mem_dc2, PRF_CLIENT);
|
|---|
| 183 | dll.BufferedPaintSetAlpha(paint_buffer2, 0, 255);
|
|---|
| 184 | FillRect(mem_dc1, &ps.rcPaint, blur.black_brush);
|
|---|
| 185 | dll.EndBufferedPaint(paint_buffer2, TRUE);
|
|---|
| 186 | }
|
|---|
| 187 |
|
|---|
| 188 | dll.EndBufferedPaint(paint_buffer1, TRUE);
|
|---|
| 189 | EndPaint(hWnd, &ps);
|
|---|
| 190 |
|
|---|
| 191 | return 0;
|
|---|
| 192 | }
|
|---|
| 193 |
|
|---|
| 194 | return CallWindowProc(blur.DefaultWindowProceduer, hWnd, message, wParam, lParam);
|
|---|
| 195 | }
|
|---|
| 196 |
|
|---|
| 197 | LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
|---|
| 198 | WNDPROC wp = WndProc;
|
|---|
| 199 | (void)wp;
|
|---|
| 200 |
|
|---|
| 201 | if (message == WM_COMMAND) {
|
|---|
| 202 | int wID = LOWORD(wParam);
|
|---|
| 203 | int wNotifyCode = HIWORD(wParam);
|
|---|
| 204 | HWND hwndControl = (HWND)lParam;
|
|---|
| 205 | if (hwndControl == (HWND)GetProp(hWnd, _T("my editbox"))) {
|
|---|
| 206 | if (wNotifyCode == EN_UPDATE) {
|
|---|
| 207 | InvalidateRect(hwndControl, 0, FALSE);
|
|---|
| 208 | }
|
|---|
| 209 | }
|
|---|
| 210 | }
|
|---|
| 211 |
|
|---|
| 212 | if (message == WM_DESTROY) {
|
|---|
| 213 | PostQuitMessage(0);
|
|---|
| 214 | return 0;
|
|---|
| 215 | }
|
|---|
| 216 |
|
|---|
| 217 | return DefWindowProc(hWnd, message, wParam, lParam);
|
|---|
| 218 | }
|
|---|
| 219 |
|
|---|
| 220 | #define SET_DLL_ADDRESS(module, name) \
|
|---|
| 221 | { \
|
|---|
| 222 | dll.name = (decltype(&name))GetProcAddress(module, #name); \
|
|---|
| 223 | }
|
|---|
| 224 |
|
|---|
| 225 | int APIENTRY _tWinMain(HINSTANCE hInstance,
|
|---|
| 226 | HINSTANCE hPrevInstance,
|
|---|
| 227 | LPTSTR lpCmdLine,
|
|---|
| 228 | int nCmdShow) {
|
|---|
| 229 | UNREFERENCED_PARAMETER(hPrevInstance);
|
|---|
| 230 | UNREFERENCED_PARAMETER(lpCmdLine);
|
|---|
| 231 |
|
|---|
| 232 | assert(LoadLibrary(_T("msftedit.dll")));
|
|---|
| 233 | assert(LoadLibrary(_T("riched20.dll")));
|
|---|
| 234 | assert(LoadLibrary(_T("riched32.dll")));
|
|---|
| 235 |
|
|---|
| 236 | HMODULE dwmapi_dll = LoadLibrary(_T("dwmapi.dll"));
|
|---|
| 237 | assert(dwmapi_dll);
|
|---|
| 238 |
|
|---|
| 239 | SET_DLL_ADDRESS(dwmapi_dll, DwmExtendFrameIntoClientArea);
|
|---|
| 240 | SET_DLL_ADDRESS(dwmapi_dll, DwmIsCompositionEnabled);
|
|---|
| 241 | SET_DLL_ADDRESS(dwmapi_dll, DwmEnableBlurBehindWindow);
|
|---|
| 242 | SET_DLL_ADDRESS(dwmapi_dll, DwmGetColorizationColor);
|
|---|
| 243 | SET_DLL_ADDRESS(dwmapi_dll, DwmGetWindowAttribute);
|
|---|
| 244 |
|
|---|
| 245 | HMODULE uxtheme_dll = LoadLibrary(_T("uxtheme.dll"));
|
|---|
| 246 | assert(uxtheme_dll);
|
|---|
| 247 | SET_DLL_ADDRESS(uxtheme_dll, BeginBufferedPaint);
|
|---|
| 248 | SET_DLL_ADDRESS(uxtheme_dll, BufferedPaintInit);
|
|---|
| 249 | SET_DLL_ADDRESS(uxtheme_dll, BufferedPaintUnInit);
|
|---|
| 250 | SET_DLL_ADDRESS(uxtheme_dll, EndBufferedPaint);
|
|---|
| 251 | SET_DLL_ADDRESS(uxtheme_dll, BufferedPaintSetAlpha);
|
|---|
| 252 |
|
|---|
| 253 | assert(dll.BufferedPaintInit() == S_OK);
|
|---|
| 254 |
|
|---|
| 255 | MSG msg = {};
|
|---|
| 256 | TCHAR szWindowClass[] = _T("hoge");
|
|---|
| 257 |
|
|---|
| 258 | WNDCLASS wc = {};
|
|---|
| 259 | wc.style = CS_HREDRAW | CS_VREDRAW;
|
|---|
| 260 | wc.lpfnWndProc = WndProc;
|
|---|
| 261 | wc.cbClsExtra = 0;
|
|---|
| 262 | wc.cbWndExtra = 0;
|
|---|
| 263 | wc.hInstance = hInstance;
|
|---|
| 264 | wc.hIcon = NULL;
|
|---|
| 265 | wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|---|
| 266 | wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
|
|---|
| 267 | wc.lpszMenuName = NULL;
|
|---|
| 268 | wc.lpszClassName = szWindowClass;
|
|---|
| 269 |
|
|---|
| 270 | assert(RegisterClass(&wc));
|
|---|
| 271 |
|
|---|
| 272 | TCHAR szTitle[] = _T("hige");
|
|---|
| 273 | DWORD style = WS_OVERLAPPEDWINDOW;
|
|---|
| 274 |
|
|---|
| 275 | RECT r;
|
|---|
| 276 | r.top = 0;
|
|---|
| 277 | r.left = 0;
|
|---|
| 278 | r.right = 300;
|
|---|
| 279 | r.bottom = 300;
|
|---|
| 280 | assert(AdjustWindowRectEx(&r, style, FALSE, 0));
|
|---|
| 281 |
|
|---|
| 282 | HWND hWnd = CreateWindow(
|
|---|
| 283 | szWindowClass, szTitle, style,
|
|---|
| 284 | 50, 50, r.right - r.left, r.bottom - r.top,
|
|---|
| 285 | NULL, NULL, hInstance, NULL);
|
|---|
| 286 | assert(hWnd);
|
|---|
| 287 |
|
|---|
| 288 | DWM_BLURBEHIND bb = {};
|
|---|
| 289 | bb.dwFlags = DWM_BB_ENABLE;
|
|---|
| 290 | bb.fEnable = TRUE;
|
|---|
| 291 | assert(dll.DwmEnableBlurBehindWindow(hWnd, &bb) == S_OK);
|
|---|
| 292 |
|
|---|
| 293 | MARGINS margins = {};
|
|---|
| 294 | margins.cxLeftWidth = 50;
|
|---|
| 295 | margins.cxRightWidth = 50;
|
|---|
| 296 | margins.cyBottomHeight = 100;
|
|---|
| 297 | margins.cyTopHeight = 100;
|
|---|
| 298 |
|
|---|
| 299 | assert(dll.DwmExtendFrameIntoClientArea(hWnd, &margins) == S_OK);
|
|---|
| 300 |
|
|---|
| 301 | HWND hEdit = CreateWindow(
|
|---|
| 302 | _T("EDIT"),
|
|---|
| 303 | _T("hage"),
|
|---|
| 304 | WS_CHILD | WS_VISIBLE /*| WS_BORDER */,
|
|---|
| 305 | 50,
|
|---|
| 306 | 100,
|
|---|
| 307 | 200,
|
|---|
| 308 | 100,
|
|---|
| 309 | hWnd,
|
|---|
| 310 | NULL,
|
|---|
| 311 | hInstance,
|
|---|
| 312 | NULL);
|
|---|
| 313 |
|
|---|
| 314 | assert(hEdit);
|
|---|
| 315 | assert(SetProp(hWnd, _T("my editbox"), (HANDLE)hEdit) != 0);
|
|---|
| 316 |
|
|---|
| 317 | //HANDLE wp = (HANDLE)GetWindowLongPtr(hEdit, GWLP_WNDPROC);
|
|---|
| 318 | //assert(SetProp(hEdit, _T("my default wndproc"), wp) != 0);
|
|---|
| 319 |
|
|---|
| 320 | blur.DefaultWindowProceduer = (WNDPROC)GetWindowLongPtr(hEdit, GWLP_WNDPROC);
|
|---|
| 321 | SetWindowLong(hEdit, GWLP_WNDPROC, (LONG_PTR)BlurEditWndProc);
|
|---|
| 322 |
|
|---|
| 323 | ShowWindow(hWnd, nCmdShow);
|
|---|
| 324 | UpdateWindow(hWnd);
|
|---|
| 325 |
|
|---|
| 326 | while (GetMessage(&msg, NULL, 0, 0)) {
|
|---|
| 327 | TranslateMessage(&msg);
|
|---|
| 328 | DispatchMessage(&msg);
|
|---|
| 329 | }
|
|---|
| 330 |
|
|---|
| 331 | return (int) msg.wParam;
|
|---|
| 332 | }
|
|---|
| 333 |
|
|---|
| 334 |
|
|---|