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