root/lang/objective-cplusplus/i3/trunk/tmp/dwmedit/BlurEditController.cc @ 39069

Revision 39069, 10.1 kB (checked in by saturday06, 18 months ago)

matomoni-ugoita

  • Property svn:executable set to *
Line 
1#include <windows.h>
2#include <windowsx.h>
3#include <stdio.h>
4#include <usp10.h>
5#include <utility>
6
7#include "ApiHook.h"
8#include "WindowsVersionHelp.h"
9
10#ifdef _MSC_VER
11#pragma comment(lib, "gdi32.lib")
12#pragma comment(lib, "comctl32.lib")
13#pragma comment(lib, "user32.lib")
14#pragma comment(lib, "dbghelp.lib")
15#pragma comment(lib, "dwmapi.lib")
16#pragma comment(lib, "uxtheme.lib")
17#endif
18
19using namespace api_hook;
20
21struct BlurEditController;
22extern BlurEditController self;
23struct BlurEditController {
24    LONG paint_enable; // thread guard
25    bool auto_paint_ignored; // raw
26    DWORD thread_id; // raw
27
28    WNDPROC DefaultWindowProceduer;
29    bool capture;
30    bool focus;
31    HBRUSH black_brush;
32    BLENDFUNCTION blend_function;
33    BP_PAINTPARAMS bp_paintparams;
34
35    class PaintEnable {
36        const LONG saved_paint_enable;
37        PaintEnable& operator=(const PaintEnable& that);
38    public:
39        PaintEnable() : saved_paint_enable(InterlockedExchange(&self.paint_enable, 1)) {
40        }
41        ~PaintEnable() {
42            InterlockedExchange(&self.paint_enable, saved_paint_enable);
43        }
44    };
45
46    static bool isPaintEnable() {
47        LONG paint_enable = InterlockedExchangeAdd(&self.paint_enable, 0);
48        if (paint_enable || self.thread_id != GetCurrentThreadId()) {
49            return true;
50        }
51        return false;
52    }
53
54    struct O {
55        FARPROC (WINAPI *GetProcAddress)(HINSTANCE, const CHAR*);
56        // decltype(&GetProcAddress) GetProcAddress;
57        BOOL (WINAPI *ExtTextOutW)(HDC, int, int, UINT, const RECT*, const WCHAR*, UINT, const INT*);
58        // decltype(&ExtTextOutW) ExtTextOutW;
59        HRESULT (WINAPI *DrawThemeBackground)(void*, HDC, int, int, const RECT*, const RECT*);
60        // decltype(&DrawThemeBackground) DrawThemeBackground;
61    } o;
62
63    struct H {
64        static HRESULT WINAPI DrawThemeBackground(HTHEME a, HDC b, int c, int d,
65            const RECT * e, const RECT * f) {
66            if (isPaintEnable()) {
67                return self.o.DrawThemeBackground(a, b, c, d, e, f);
68            }
69            self.auto_paint_ignored = true;
70            return  S_OK;
71        }
72        static FARPROC WINAPI GetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
73            if (lstrcmpA(lpProcName, "DrawThemeBackground") == 0) {
74                return (FARPROC)H::DrawThemeBackground;
75            }
76            return self.o.GetProcAddress(hModule, lpProcName);
77        }
78        static BOOL WINAPI ExtTextOutW(HDC hdc, int x, int y, UINT fuOptions, CONST RECT *lprc,
79            LPCTSTR lpString, UINT cbCount, CONST INT *lpDx) {
80
81            if (isPaintEnable()) {
82                return self.o.ExtTextOutW(hdc, x, y, fuOptions, lprc, lpString, cbCount, lpDx);
83            }
84
85            // ����PI�Ăяo�����E�N���b�N���j���[�`�����߂̂����𔻕�
86            // TODO ���Ə�����            static int x_ = 0;
87            static int y_ = 0;
88            static UINT fuOptions_ = 0;
89            static UINT cbCount_ = 0;
90            bool match = (x_ == x && y_ == y && fuOptions_ == fuOptions && cbCount_ == cbCount);
91            x_ = x;
92            y_ = y;
93            fuOptions_ = fuOptions;
94            cbCount_ = cbCount;
95
96            DWORD objectType = GetObjectType(hdc);
97            if (objectType != OBJ_DC || !match) {
98                // �E�N���b�N���j���[�̕`���ꍇ
99                return self.o.ExtTextOutW(hdc, x, y, fuOptions, lprc, lpString, cbCount, lpDx);
100            }
101
102            self.auto_paint_ignored = true;
103            return TRUE;
104        }
105    };
106
107    BlurEditController() {
108        o = O();
109        capture = false;
110        focus = false;
111        paint_enable = 0;
112        auto_paint_ignored = false;
113
114        black_brush = (HBRUSH)GetStockObject(BLACK_BRUSH);
115
116        blend_function.BlendOp = AC_SRC_OVER;
117        blend_function.BlendFlags = 0;
118        blend_function.AlphaFormat = 0; //AC_SRC_ALPHA
119        blend_function.SourceConstantAlpha = 255;
120
121        bp_paintparams.cbSize = sizeof(bp_paintparams);
122        bp_paintparams.dwFlags = 0;
123        bp_paintparams.prcExclude = NULL;
124        bp_paintparams.pBlendFunction = &blend_function;
125
126        thread_id = GetCurrentThreadId();
127
128        dll.init();
129
130        if (!dll.ImageDirectoryEntryToData) {
131            return;
132        }
133
134        o.GetProcAddress = (decltype(&H::GetProcAddress))GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetProcAddress");
135        if (!o.GetProcAddress) {
136            return;
137        }
138
139        o.DrawThemeBackground = (decltype(&H::DrawThemeBackground))GetProcAddress(GetModuleHandleA("uxtheme.dll"), "DrawThemeBackground");
140        if (!o.DrawThemeBackground) {
141            return;
142        }
143
144        o.ExtTextOutW = (decltype(&H::ExtTextOutW))GetProcAddress(GetModuleHandleA("gdi32.dll"), "ExtTextOutW");
145        if (!o.ExtTextOutW) {
146            return;
147        }
148
149        //ReplaceIATEntryInAllMods("gdi32.dll", o.ExtTextOutW, H::ExtTextOutW);
150        ReplaceIATEntryInOneMod("gdi32.dll", o.ExtTextOutW, H::ExtTextOutW, GetModuleHandle(_T("usp10.dll")));
151        ReplaceIATEntryInOneMod("kernel32.dll", o.GetProcAddress, H::GetProcAddress, GetModuleHandle(_T("comctl32.dll")));
152    }
153
154    bool hook(HWND hEdit) {
155        if (!dll.BeginBufferedPaint) {
156            return false;
157        }
158        self.DefaultWindowProceduer = (WNDPROC)GetWindowLongPtr(hEdit, GWLP_WNDPROC);
159        SetWindowLongPtr(hEdit, GWLP_WNDPROC, (LONG_PTR)BlurEditController::WndProc);
160        return true;
161    }
162
163    /**
164     * �����ςȐݒ��`�悳�����܂����߁A������������
165     * �ŁA���ꂪ�������ꂽ�ꍇ�ɐ������ݒ��ĕ`�悷��     */
166    static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
167        (void)static_cast<WNDPROC>(WndProc);
168
169        bool redraw = false;
170
171        if (message == WM_PAINT) {
172            BYTE alpha = 0;
173            if (self.focus) {
174                alpha = 0xff;
175            } else if (self.capture) {
176                alpha = 0xbb;
177            } else {
178                alpha = 0x88;
179            }
180
181            PAINTSTRUCT ps = {};
182            HDC hdc = BeginPaint(hWnd, &ps);
183            HDC mem_dc1 = NULL;
184            HPAINTBUFFER paint_buffer1 = dll.BeginBufferedPaint(hdc, &ps.rcPaint, BPBF_TOPDOWNDIB, NULL, &mem_dc1);
185            if (paint_buffer1 == 0) {
186                // fatal error
187                EndPaint(hWnd, &ps);
188                return CallWindowProc(self.DefaultWindowProceduer, hWnd, message, wParam, lParam);
189            }
190
191            if (alpha == 255) {
192                // �s�����̏ꍇ
193                {
194                    PaintEnable paintEnable;
195                    CallWindowProc(self.DefaultWindowProceduer, hWnd, WM_PRINTCLIENT, (WPARAM)mem_dc1, PRF_CLIENT);
196                }
197                dll.BufferedPaintSetAlpha(paint_buffer1, 0, 255);
198            } else {
199                // �����̏ꍇ�A�������f�o�C�X�R���e�L�X�g��������ăA���t�@�u�����h����                self.blend_function.SourceConstantAlpha = alpha;
200
201                HDC mem_dc2 = 0;
202                HPAINTBUFFER paint_buffer2 = dll.BeginBufferedPaint(mem_dc1, &ps.rcPaint, BPBF_TOPDOWNDIB, &self.bp_paintparams, &mem_dc2);
203                if (paint_buffer2 == 0) {
204                    // fatal error
205                    dll.EndBufferedPaint(paint_buffer1, FALSE);
206                    EndPaint(hWnd, &ps);
207                    return CallWindowProc(self.DefaultWindowProceduer, hWnd, message, wParam, lParam);
208                }
209
210                {
211                    PaintEnable paintEnable;
212                    CallWindowProc(self.DefaultWindowProceduer, hWnd, WM_PRINTCLIENT, (WPARAM)mem_dc2, PRF_CLIENT);
213                }
214
215                dll.BufferedPaintSetAlpha(paint_buffer2, 0, 255);
216                FillRect(mem_dc1, &ps.rcPaint, self.black_brush);
217                dll.EndBufferedPaint(paint_buffer2, TRUE);
218            }
219
220            dll.EndBufferedPaint(paint_buffer1, TRUE);
221            EndPaint(hWnd, &ps);
222            return 0;
223        }
224
225        //if (message == WM_ERASEBKGND) {
226        //    return 0;
227        //}
228
229        if (message == WM_SETFOCUS) {
230            self.focus = true;
231            redraw = true;
232        }
233
234        if (message == WM_KILLFOCUS) {
235            self.focus = false;
236            redraw = true;
237        }
238
239        if (message == WM_CAPTURECHANGED) {
240            if ((HWND)lParam != hWnd && self.capture) {
241                ReleaseCapture();
242                self.capture = false;
243                redraw = true;
244            }
245        }
246
247        if (message == WM_MOUSEMOVE) {
248            // �}�E�X���E�B���h�E�����݂��邩�`�F�b�N
249            RECT rect = {};
250            POINT p = {};
251            p.x = GET_X_LPARAM(lParam);
252            p.y = GET_Y_LPARAM(lParam);
253            if (!(wParam & MK_LBUTTON) &&
254                (p.x < 0 ||
255                p.y < 0 ||
256                !GetWindowRect(hWnd, &rect) ||
257                p.x >= (rect.right - rect.left) ||
258                p.y >= (rect.bottom - rect.top)
259                )) {
260                    // �f�[�^�擾���s���A�J�[�\�����E�B���h�E�O�ɂ���                    if (self.capture) {
261                        ReleaseCapture();
262                        self.capture = false;
263                        redraw = true;
264                    }
265
266            } else {
267                // �J�[�\�����E�B���h�E������                if (!self.capture) {
268                    SetCapture(hWnd);
269                    self.capture = true;
270                    redraw = true;
271                }
272            }
273        }
274
275        {
276            LRESULT l = CallWindowProc(self.DefaultWindowProceduer, hWnd, message, wParam, lParam);
277
278            if (redraw || self.auto_paint_ignored) {
279                self.auto_paint_ignored = false;
280                InvalidateRect(hWnd, NULL, FALSE);
281                // WndProc(hWnd, WM_PAINT, 0, 0);
282            }
283
284            return l;
285        }
286    }
287} self;
288
289bool BlurEditControllerHook(HWND hEdit) {
290    return self.hook(hEdit);
291}
292
Note: See TracBrowser for help on using the browser.