PageRenderTime 66ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/Miranda IM - CK Release/Miranda/Plugins/Modernb/src/modern_xptheme.cpp

http://miranda-dev.googlecode.com/
C++ | 269 lines | 241 code | 22 blank | 6 comment | 27 complexity | 64344470b4ab5fce25788570ae696ed4 MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception, LGPL-3.0, AGPL-1.0, BSD-3-Clause, LGPL-2.1
  1. #include "../hdr/modern_commonheaders.h"
  2. #include "../hdr/modern_commonprototypes.h"
  3. #include "../m_api/m_xpTheme.h"
  4. //statical
  5. typedef struct _tagXPTObject
  6. {
  7. HANDLE hThemeHandle;
  8. HWND hOwnerWindow;
  9. LPCWSTR lpcwClassObject;
  10. } XPTObject;
  11. static SortedList * xptObjectList=NULL;
  12. static CRITICAL_SECTION xptCS;
  13. static BOOL xptModuleLoaded=FALSE;
  14. static HMODULE _xpt_ThemeAPIHandle = NULL; // handle to uxtheme.dll
  15. static HANDLE (WINAPI *_xpt_OpenThemeData)(HWND, LPCWSTR) = NULL;
  16. static HRESULT (WINAPI *_xpt_CloseThemeData)(HANDLE)= NULL;
  17. static BOOL (WINAPI *_xpt_IsThemeBackgroundPartiallyTransparent)(HANDLE, int,int)= NULL;
  18. static BOOL (WINAPI *_xpt_EnableThemeDialogTexture)(HANDLE, DWORD)=NULL;
  19. static HRESULT (WINAPI *_xpt_GetThemePartSize)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, RECT *prc, int eSize, SIZE *psz )= NULL;
  20. static HRESULT (WINAPI *_xpt_DrawThemeParentBackground)(HWND, HDC, const RECT *)= NULL;
  21. static HRESULT (WINAPI *_xpt_DrawThemeBackground)(HANDLE, HDC, int, int,const RECT *, const RECT *)= NULL;
  22. static HRESULT (WINAPI *_xpt_DrawThemeText)(HANDLE, HDC, int, int, LPCWSTR, int,DWORD, DWORD, const RECT *)= NULL;
  23. #undef MGPROC
  24. #define MGPROC(x) GetProcAddress(_xpt_ThemeAPIHandle,x)
  25. #define xptcheck if (!xptModuleLoaded) return
  26. #define xptlock() EnterCriticalSection(&xptCS)
  27. #define xptunlock() LeaveCriticalSection(&xptCS)
  28. static void _sttXptObjectDestructor (void * pt)
  29. {
  30. mir_free(pt);
  31. }
  32. static int _xpt_ThemeSupport()
  33. {
  34. if (IsWinVerXPPlus()) {
  35. if (!_xpt_ThemeAPIHandle) {
  36. _xpt_ThemeAPIHandle = GetModuleHandleA("uxtheme");
  37. if (_xpt_ThemeAPIHandle) {
  38. _xpt_OpenThemeData = (HANDLE(WINAPI *)(HWND, LPCWSTR))MGPROC("OpenThemeData");
  39. _xpt_CloseThemeData = (HRESULT(WINAPI *)(HANDLE))MGPROC("CloseThemeData");
  40. _xpt_IsThemeBackgroundPartiallyTransparent = (BOOL(WINAPI *)(HANDLE, int, int))MGPROC("IsThemeBackgroundPartiallyTransparent");
  41. _xpt_DrawThemeParentBackground = (HRESULT(WINAPI *)(HWND, HDC, const RECT *))MGPROC("DrawThemeParentBackground");
  42. _xpt_DrawThemeBackground = (HRESULT(WINAPI *)(HANDLE, HDC, int, int, const RECT *, const RECT *))MGPROC("DrawThemeBackground");
  43. _xpt_DrawThemeText = (HRESULT(WINAPI *)(HANDLE, HDC, int, int, LPCWSTR, int, DWORD, DWORD, const RECT *))MGPROC("DrawThemeText");
  44. _xpt_GetThemePartSize = (HRESULT(WINAPI *)(HTHEME , HDC , int , int , RECT *, int , SIZE * ))MGPROC("GetThemePartSize");
  45. _xpt_EnableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD)) MGPROC("EnableThemeDialogTexture");
  46. }
  47. }
  48. // Make sure all of these methods are valid (i would hope either all or none work)
  49. if (_xpt_OpenThemeData &&
  50. _xpt_CloseThemeData &&
  51. _xpt_IsThemeBackgroundPartiallyTransparent &&
  52. _xpt_DrawThemeParentBackground &&
  53. _xpt_DrawThemeBackground &&
  54. _xpt_DrawThemeText &&
  55. _xpt_GetThemePartSize)
  56. {
  57. return 1;
  58. }
  59. }
  60. return 0;
  61. }
  62. static void _sttXptCloseThemeData(XPTObject * xptObject)
  63. {
  64. _xpt_CloseThemeData(xptObject->hThemeHandle);
  65. xptObject->hThemeHandle=NULL;
  66. }
  67. static void _sttXptReloadThemeData(XPTObject * xptObject)
  68. {
  69. _xpt_CloseThemeData(xptObject->hThemeHandle);
  70. xptObject->hThemeHandle=_xpt_OpenThemeData(xptObject->hOwnerWindow, xptObject->lpcwClassObject);
  71. }
  72. HRESULT XPThemesLoadModule()
  73. {
  74. if (_xpt_ThemeSupport())
  75. {
  76. InitializeCriticalSection(&xptCS);
  77. xptObjectList=li.List_Create(0,1);
  78. xptModuleLoaded=TRUE;
  79. }
  80. return S_OK;
  81. }
  82. void XPThemesUnloadModule()
  83. {
  84. xptcheck;
  85. xptlock();
  86. xptModuleLoaded=FALSE;
  87. xptunlock();
  88. li_ListDestruct(xptObjectList,_sttXptObjectDestructor);
  89. DeleteCriticalSection(&xptCS);
  90. FreeLibrary(_xpt_ThemeAPIHandle);
  91. }
  92. BOOL xpt_IsThemed(XPTHANDLE xptHandle)
  93. {
  94. BOOL res=FALSE;
  95. xptcheck FALSE;
  96. if (!xptHandle) return FALSE;
  97. xptlock();
  98. {
  99. if (xpt_IsValidHandle(xptHandle) && ((XPTObject*) xptHandle)->hThemeHandle)
  100. res=TRUE;
  101. }
  102. xptunlock();
  103. return res;
  104. }
  105. BOOL xpt_IsValidHandle(XPTHANDLE xptHandle)
  106. {
  107. BOOL res=FALSE;
  108. xptcheck FALSE;
  109. if (!xptHandle) return FALSE;
  110. xptlock();
  111. {
  112. if (li.List_IndexOf(xptObjectList, (void*)xptHandle)!=-1)
  113. res=TRUE;
  114. }
  115. xptunlock();
  116. return res;
  117. }
  118. XPTHANDLE xpt_AddThemeHandle(HWND hwnd, LPCWSTR className)
  119. {
  120. XPTHANDLE res = NULL;
  121. xptcheck NULL;
  122. xptlock();
  123. {
  124. XPTObject* xptObject=(XPTObject*)mir_calloc(sizeof(XPTObject));
  125. xptObject->lpcwClassObject=className;
  126. xptObject->hOwnerWindow=hwnd;
  127. _sttXptReloadThemeData(xptObject);
  128. li.List_InsertPtr(xptObjectList, (void*)xptObject);
  129. res=(XPTHANDLE)xptObject;
  130. }
  131. xptunlock();
  132. return res;
  133. }
  134. void xpt_FreeThemeHandle(XPTHANDLE xptHandle)
  135. {
  136. xptcheck;
  137. xptlock();
  138. if (xpt_IsValidHandle(xptHandle))
  139. {
  140. XPTObject* xptObject=(XPTObject*)xptHandle;
  141. _sttXptCloseThemeData(xptObject);
  142. _sttXptObjectDestructor((void *) xptHandle);
  143. li.List_Remove(xptObjectList, li.List_IndexOf(xptObjectList,(void *) xptHandle));
  144. }
  145. xptunlock();
  146. }
  147. void xpt_FreeThemeForWindow(HWND hwnd)
  148. {
  149. xptcheck;
  150. xptlock();
  151. {
  152. int i=0;
  153. while (i<xptObjectList->realCount)
  154. {
  155. XPTObject* xptObject=(XPTObject*)xptObjectList->items[i];
  156. if (xptObject->hOwnerWindow==hwnd)
  157. {
  158. _sttXptCloseThemeData(xptObject);
  159. _sttXptObjectDestructor((void *) xptObject);
  160. li.List_Remove(xptObjectList, i);
  161. }
  162. else
  163. i++;
  164. }
  165. }
  166. xptunlock();
  167. }
  168. void xpt_OnWM_THEMECHANGED()
  169. {
  170. xptcheck;
  171. xptlock();
  172. {
  173. int i;
  174. for (i=0; i<xptObjectList->realCount; i++)
  175. _sttXptReloadThemeData((XPTObject*)xptObjectList->items[i]);
  176. }
  177. xptunlock();
  178. }
  179. HRESULT xpt_DrawThemeBackground(XPTHANDLE xptHandle, HDC hdc, int type, int state, const RECT * sizeRect, const RECT * clipRect)
  180. {
  181. HRESULT res=S_FALSE;
  182. xptcheck S_FALSE;
  183. xptlock();
  184. if (xpt_IsThemed(xptHandle))
  185. res=_xpt_DrawThemeBackground(((XPTObject*)xptHandle)->hThemeHandle, hdc, type, state, sizeRect, clipRect);
  186. xptunlock();
  187. return res;
  188. }
  189. HRESULT xpt_DrawThemeParentBackground(HWND hWnd, HDC hdc, const RECT * sizeRect)
  190. {
  191. xptcheck S_FALSE;
  192. return xpt_DrawThemeParentBackground(hWnd, hdc, sizeRect);
  193. }
  194. BOOL xpt_IsThemeBackgroundPartiallyTransparent(XPTHANDLE xptHandle, int type, int state)
  195. {
  196. BOOL res=FALSE;
  197. xptcheck FALSE;
  198. xptlock();
  199. if (xpt_IsThemed(xptHandle))
  200. res=_xpt_IsThemeBackgroundPartiallyTransparent(((XPTObject*)xptHandle)->hThemeHandle, type, state);
  201. xptunlock();
  202. return res;
  203. }
  204. HRESULT xpt_DrawTheme(XPTHANDLE xptHandle, HWND hwnd, HDC hdc, int type, int state, const RECT *sizeRect, const RECT * clipRect)
  205. {
  206. HRESULT res=S_FALSE;
  207. xptcheck S_FALSE;
  208. xptlock();
  209. if (xpt_IsThemed(xptHandle))
  210. {
  211. if (_xpt_IsThemeBackgroundPartiallyTransparent(((XPTObject*)xptHandle)->hThemeHandle, type, state))
  212. res=_xpt_DrawThemeParentBackground(hwnd,hdc,sizeRect);
  213. res=_xpt_DrawThemeBackground(((XPTObject*)xptHandle)->hThemeHandle, hdc, type, state, sizeRect, clipRect);
  214. }
  215. xptunlock();
  216. return res;
  217. }
  218. HRESULT xpt_DrawThemeText(XPTHANDLE xptHandle, HDC hdc, int type, int state, LPCTSTR lpStr, int len, DWORD flag1, DWORD flag2, const RECT * textRect)
  219. {
  220. #ifndef _UNICODE
  221. ske_DrawText(hdc,lpStr,len, (RECT*)textRect, flag1);
  222. return S_OK;
  223. #else
  224. HRESULT res=S_FALSE;
  225. xptcheck S_FALSE;
  226. xptlock();
  227. if (xpt_IsThemed(xptHandle))
  228. _xpt_DrawThemeText(((XPTObject*)xptHandle)->hThemeHandle, hdc, type, state, (LPCWSTR)lpStr, len, flag1, flag2, textRect);
  229. else
  230. ske_DrawText(hdc,lpStr,len, (RECT*)textRect, flag1);
  231. xptunlock();
  232. return S_OK;
  233. #endif
  234. }
  235. BOOL xpt_EnableThemeDialogTexture(HWND hwnd, DWORD flags)
  236. {
  237. BOOL res=FALSE;
  238. xptcheck res;
  239. xptlock();
  240. res=_xpt_EnableThemeDialogTexture(hwnd, flags);
  241. xptunlock();
  242. return res;
  243. }
  244. //usage outside
  245. // add theme data
  246. // in WM_DESTROY - release theme data
  247. // in paint xpt_DrawTheme