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
|
#include <windows.h>
#include "ml.h"
#include "../nu/CGlobalAtom.h"
#ifndef LONGX86
#ifdef _WIN64
#define LONGX86 LONG_PTR
#else /*_WIN64*/
#define LONGX86 LONG
#endif /*_WIN64*/
#endif // LONGX86
static CGlobalAtom PROP_FLIKERFIX(L"WAFFIX");
typedef struct _FFDATA
{
WNDPROC oldProc;
DWORD mode;
BOOL unicode;
BOOL forward;
}FFDATA, *PFFDATA;
static LRESULT WINAPI FlickerFixWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PFFDATA pfd;
pfd = (PFFDATA)GetPropW(hwnd, PROP_FLIKERFIX);
if (!pfd) return (IsWindowUnicode(hwnd)) ? DefWindowProcW(hwnd, uMsg, wParam, lParam) : DefWindowProcA(hwnd, uMsg, wParam, lParam);
switch(uMsg)
{
case WM_ERASEBKGND:
if (pfd->forward) break;
if (FFM_NOERASE & pfd->mode) return 1;
if (FFM_ERASEINPAINT & pfd->mode) return 0;
if (FFM_FORCEERASE & pfd->mode)
{
HBRUSH hb;
RECT rc;
hb = CreateSolidBrush(pfd->mode & 0x00FFFFFF);
GetClientRect(hwnd, &rc);
FillRect((HDC)wParam, &rc, hb);
DeleteObject(hb);
return 1;
}
// otherwise unsubclass....
case WM_NCDESTROY:
if (FlickerFixWndProc == (WNDPROC)(LONG_PTR)GetWindowLongPtrW(hwnd, GWLP_WNDPROC))
{
RemovePropW(hwnd, PROP_FLIKERFIX);
SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)pfd->oldProc);
(pfd->unicode) ? CallWindowProcW(pfd->oldProc, hwnd, uMsg, wParam, lParam) :
CallWindowProcA(pfd->oldProc, hwnd, uMsg, wParam, lParam);
free(pfd);
return 0;
}
else pfd->forward = TRUE;
break;
}
return (pfd->unicode) ? CallWindowProcW(pfd->oldProc, hwnd, uMsg, wParam, lParam) :
CallWindowProcA(pfd->oldProc, hwnd, uMsg, wParam, lParam);
}
BOOL FlickerFixWindow(HWND hwnd, INT mode)
{
PFFDATA pfd;
if (!hwnd || !IsWindow(hwnd)) return FALSE;
pfd = (PFFDATA)GetPropW(hwnd, PROP_FLIKERFIX);
if (pfd) pfd->mode = mode;
else
{
pfd = (PFFDATA)calloc(1, sizeof(FFDATA));
if (pfd)
{
pfd->forward = FALSE;
pfd->mode = mode;
pfd->unicode = IsWindowUnicode(hwnd);
pfd->oldProc = (WNDPROC)(LONG_PTR) ((pfd->unicode) ? SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)FlickerFixWndProc) :
SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)FlickerFixWndProc));
if (!pfd->oldProc || !SetPropW(hwnd, PROP_FLIKERFIX, pfd))
{
if (pfd->oldProc)
{
((pfd->unicode) ? SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)pfd->oldProc) :
SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)pfd->oldProc));
}
free(pfd);
pfd = NULL;
}
}
}
return (NULL != pfd);
}
|