summaryrefslogtreecommitdiff
path: root/plugins/Clist_modern/src/modern_xptheme.cpp
blob: bff9e8a7fb2893d7a9552418e72f6226247ff21e (plain)
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "stdafx.h"
#include "m_xpTheme.h"


//statical

typedef struct _tagXPTObject
{
	HANDLE  hThemeHandle;
	HWND    hOwnerWindow;
	LPCWSTR lpcwClassObject;
} XPTObject;

static OBJLIST<XPTObject> xptObjectList(1);
static mir_cs xptCS;

static void _sttXptCloseThemeData(XPTObject * xptObject)
{
	CloseThemeData(xptObject->hThemeHandle);
	xptObject->hThemeHandle = nullptr;
}

static void _sttXptReloadThemeData(XPTObject * xptObject)
{
	CloseThemeData(xptObject->hThemeHandle);
	xptObject->hThemeHandle = OpenThemeData(xptObject->hOwnerWindow, xptObject->lpcwClassObject);
}

void XPThemesUnloadModule()
{
	xptObjectList.destroy();
}

BOOL xpt_IsThemed(XPTHANDLE xptHandle)
{
	if (!xptHandle) return FALSE;

	mir_cslock lck(xptCS);
	return xpt_IsValidHandle(xptHandle) && ((XPTObject*)xptHandle)->hThemeHandle;
}

BOOL xpt_IsValidHandle(XPTHANDLE xptHandle)
{
	if (!xptHandle) return FALSE;

	mir_cslock lck(xptCS);
	return xptObjectList.indexOf((XPTObject*)xptHandle) != -1;
}

XPTHANDLE xpt_AddThemeHandle(HWND hwnd, LPCWSTR className)
{
	mir_cslock lck(xptCS);
	XPTObject* xptObject = new XPTObject;
	xptObject->lpcwClassObject = className;
	xptObject->hOwnerWindow = hwnd;
	_sttXptReloadThemeData(xptObject);
	xptObjectList.insert(xptObject);
	return (XPTHANDLE)xptObject;
}

void xpt_FreeThemeHandle(XPTHANDLE xptHandle)
{
	mir_cslock lck(xptCS);
	if (xpt_IsValidHandle(xptHandle)) {
		XPTObject* xptObject = (XPTObject*)xptHandle;
		_sttXptCloseThemeData(xptObject);
		mir_free(xptHandle);
		xptObjectList.remove(xptObjectList.indexOf(xptObject));
	}
}

void xpt_FreeThemeForWindow(HWND hwnd)
{
	mir_cslock lck(xptCS);
	auto T = xptObjectList.rev_iter();
	for (auto &xptObject : T)
		if (xptObject->hOwnerWindow == hwnd) {
			_sttXptCloseThemeData(xptObject);
			xptObjectList.remove(T.indexOf(&xptObject));
		}
}

void xpt_OnWM_THEMECHANGED()
{
	mir_cslock lck(xptCS);

	for (auto &it : xptObjectList)
		_sttXptReloadThemeData(it);
}

HRESULT	xpt_DrawThemeBackground(XPTHANDLE xptHandle, HDC hdc, int type, int state, const RECT *sizeRect, const RECT *clipRect)
{
	mir_cslock lck(xptCS);
	if (xpt_IsThemed(xptHandle))
		return DrawThemeBackground(((XPTObject*)xptHandle)->hThemeHandle, hdc, type, state, sizeRect, clipRect);

	return S_FALSE;
}

BOOL xpt_IsThemeBackgroundPartiallyTransparent(XPTHANDLE xptHandle, int type, int state)
{
	mir_cslock lck(xptCS);
	if (xpt_IsThemed(xptHandle))
		return IsThemeBackgroundPartiallyTransparent(((XPTObject*)xptHandle)->hThemeHandle, type, state);

	return FALSE;
}

HRESULT	xpt_DrawTheme(XPTHANDLE xptHandle, HWND hwnd, HDC hdc, int type, int state, const RECT *sizeRect, const RECT *clipRect)
{
	mir_cslock lck(xptCS);
	if (xpt_IsThemed(xptHandle)) {
		if (IsThemeBackgroundPartiallyTransparent(((XPTObject*)xptHandle)->hThemeHandle, type, state)) {
			DrawThemeParentBackground(hwnd, hdc, sizeRect);
			return DrawThemeBackground(((XPTObject*)xptHandle)->hThemeHandle, hdc, type, state, sizeRect, clipRect);
		}
	}

	return S_FALSE;
}

HRESULT xpt_DrawThemeText(XPTHANDLE xptHandle, HDC hdc, int type, int state, LPCTSTR lpStr, int len, DWORD flag1, DWORD flag2, const RECT *textRect)
{
	mir_cslock lck(xptCS);
	if (xpt_IsThemed(xptHandle))
		DrawThemeText(((XPTObject*)xptHandle)->hThemeHandle, hdc, type, state, (LPCWSTR)lpStr, len, flag1, flag2, textRect);
	else
		ske_DrawText(hdc, lpStr, len, (RECT*)textRect, flag1);

	return S_OK;
}

BOOL xpt_EnableThemeDialogTexture(HWND hwnd, DWORD flags)
{
	mir_cslock lck(xptCS);
	return SUCCEEDED(EnableThemeDialogTexture(hwnd, flags));
}