aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/General/gen_ml/flickerfix.cpp
blob: 0bed2bbaf25968c8261464b8d92da34e8198a9b5 (plain) (blame)
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);
}