Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenthemehooks.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS uxtheme.dll 00004 * FILE: dll/win32/uxtheme/themehooks.c 00005 * PURPOSE: uxtheme user api hook functions 00006 * PROGRAMMER: Giannis Adamopoulos 00007 */ 00008 00009 #include "uxthemep.h" 00010 #include "wine/debug.h" 00011 00012 WINE_DEFAULT_DEBUG_CHANNEL(uxtheme); 00013 00014 00015 00016 extern HINSTANCE hDllInst; 00017 00018 LRESULT CALLBACK ThemeWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, WNDPROC DefWndProc); 00019 00020 USERAPIHOOK user32ApiHook; 00021 BYTE gabDWPmessages[UAHOWP_MAX_SIZE]; 00022 BYTE gabMSGPmessages[UAHOWP_MAX_SIZE]; 00023 00024 00025 PWND_CONTEXT ThemeGetWndContext(HWND hWnd) 00026 { 00027 PWND_CONTEXT pcontext; 00028 00029 pcontext = (PWND_CONTEXT)GetPropW(hWnd, (LPCWSTR)MAKEINTATOM(atWndContrext)); 00030 if(pcontext == NULL) 00031 { 00032 pcontext = HeapAlloc(GetProcessHeap(), 00033 HEAP_ZERO_MEMORY, 00034 sizeof(WND_CONTEXT)); 00035 if(pcontext == NULL) 00036 { 00037 return NULL; 00038 } 00039 00040 SetPropW( hWnd, (LPCWSTR)MAKEINTATOM(atWndContrext), pcontext); 00041 } 00042 00043 return pcontext; 00044 } 00045 00046 void ThemeDetroyWndContext(HWND hWnd) 00047 { 00048 PWND_CONTEXT pContext; 00049 DWORD ProcessId; 00050 00051 /*Do not destroy WND_CONTEXT of a window that belong to another process */ 00052 GetWindowThreadProcessId(hWnd, &ProcessId); 00053 if(ProcessId != GetCurrentProcessId()) 00054 { 00055 return; 00056 } 00057 00058 pContext = (PWND_CONTEXT)GetPropW(hWnd, (LPCWSTR)MAKEINTATOM(atWndContrext)); 00059 if(pContext == NULL) 00060 { 00061 return; 00062 } 00063 00064 if(pContext->HasThemeRgn) 00065 { 00066 user32ApiHook.SetWindowRgn(hWnd, 0, TRUE); 00067 } 00068 00069 HeapFree(GetProcessHeap(), 0, pContext); 00070 00071 SetPropW( hWnd, (LPCWSTR)MAKEINTATOM(atWndContrext), NULL); 00072 } 00073 00074 static BOOL CALLBACK ThemeCleanupChildWndContext (HWND hWnd, LPARAM msg) 00075 { 00076 ThemeDetroyWndContext(hWnd); 00077 return TRUE; 00078 } 00079 00080 static BOOL CALLBACK ThemeCleanupWndContext(HWND hWnd, LPARAM msg) 00081 { 00082 if (hWnd == NULL) 00083 { 00084 EnumWindows (ThemeCleanupWndContext, 0); 00085 } 00086 else 00087 { 00088 ThemeDetroyWndContext(hWnd); 00089 EnumChildWindows (hWnd, ThemeCleanupChildWndContext, 0); 00090 } 00091 00092 return TRUE; 00093 } 00094 00095 void SetThemeRegion(HWND hWnd, PWND_CONTEXT pcontext) 00096 { 00097 HTHEME hTheme; 00098 RECT rcWindow; 00099 HRGN hrgn, hrgn1; 00100 int CaptionHeight, iPart; 00101 WINDOWINFO wi; 00102 00103 if(!IsAppThemed()) 00104 { 00105 if(pcontext->HasThemeRgn) 00106 { 00107 pcontext->HasThemeRgn = FALSE; 00108 user32ApiHook.SetWindowRgn(hWnd, 0, TRUE); 00109 } 00110 return; 00111 } 00112 00113 wi.cbSize = sizeof(wi); 00114 00115 GetWindowInfo(hWnd, &wi); 00116 00117 if((wi.dwStyle & WS_CAPTION)!=WS_CAPTION) 00118 { 00119 return; 00120 } 00121 00122 /* Get the caption part id */ 00123 if (wi.dwExStyle & WS_EX_TOOLWINDOW) 00124 iPart = WP_SMALLCAPTION; 00125 else if (wi.dwStyle & WS_MAXIMIZE) 00126 iPart = WP_MAXCAPTION; 00127 else 00128 iPart = WP_CAPTION; 00129 00130 pcontext->HasThemeRgn = TRUE; 00131 00132 CaptionHeight = wi.cyWindowBorders; 00133 CaptionHeight += GetSystemMetrics(wi.dwExStyle & WS_EX_TOOLWINDOW ? SM_CYSMCAPTION : SM_CYCAPTION ); 00134 00135 GetWindowRect(hWnd, &rcWindow); 00136 rcWindow.right -= rcWindow.left; 00137 rcWindow.bottom = CaptionHeight; 00138 rcWindow.top = 0; 00139 rcWindow.left = 0; 00140 00141 hTheme = OpenThemeData (hWnd, L"WINDOW"); 00142 00143 GetThemeBackgroundRegion(hTheme, 0, iPart, FS_ACTIVE, &rcWindow, &hrgn); 00144 00145 CloseThemeData(hTheme); 00146 00147 GetWindowRect(hWnd, &rcWindow); 00148 rcWindow.right -= rcWindow.left; 00149 rcWindow.bottom -= rcWindow.top; 00150 rcWindow.top = CaptionHeight; 00151 rcWindow.left = 0; 00152 hrgn1 = CreateRectRgnIndirect(&rcWindow); 00153 00154 CombineRgn(hrgn, hrgn, hrgn1, RGN_OR ); 00155 00156 DeleteObject(hrgn1); 00157 00158 user32ApiHook.SetWindowRgn(hWnd, hrgn, TRUE); 00159 } 00160 00161 int OnPostWinPosChanged(HWND hWnd) 00162 { 00163 PWND_CONTEXT pcontext = ThemeGetWndContext(hWnd); 00164 00165 if(pcontext && 00166 pcontext->HasAppDefinedRgn == FALSE && 00167 pcontext->UpdatingRgn == FALSE) 00168 { 00169 pcontext->UpdatingRgn = TRUE; 00170 SetThemeRegion(hWnd, pcontext); 00171 pcontext = ThemeGetWndContext(hWnd); 00172 pcontext->UpdatingRgn = FALSE; 00173 } 00174 return 0; 00175 } 00176 00177 /********************************************************************** 00178 * Hook Functions 00179 */ 00180 00181 static LRESULT CALLBACK 00182 ThemeDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) 00183 { 00184 if(!IsThemeActive()) 00185 { 00186 return user32ApiHook.DefWindowProcW(hWnd, 00187 Msg, 00188 wParam, 00189 lParam); 00190 } 00191 00192 return ThemeWndProc(hWnd, 00193 Msg, 00194 wParam, 00195 lParam, 00196 user32ApiHook.DefWindowProcW); 00197 } 00198 00199 static LRESULT CALLBACK 00200 ThemeDefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) 00201 { 00202 if(!IsThemeActive()) 00203 { 00204 return user32ApiHook.DefWindowProcA(hWnd, 00205 Msg, 00206 wParam, 00207 lParam); 00208 } 00209 00210 return ThemeWndProc(hWnd, 00211 Msg, 00212 wParam, 00213 lParam, 00214 user32ApiHook.DefWindowProcA); 00215 } 00216 00217 static LRESULT CALLBACK 00218 ThemePreWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ret,PDWORD unknown) 00219 { 00220 switch(Msg) 00221 { 00222 case WM_THEMECHANGED: 00223 UXTHEME_LoadTheme(TRUE); 00224 return 0; 00225 } 00226 00227 return 0; 00228 } 00229 00230 00231 static LRESULT CALLBACK 00232 ThemePostWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ret,PDWORD unknown) 00233 { 00234 switch(Msg) 00235 { 00236 case WM_WINDOWPOSCHANGED: 00237 { 00238 return OnPostWinPosChanged(hWnd); 00239 } 00240 case WM_DESTROY: 00241 { 00242 ThemeDetroyWndContext(hWnd); 00243 return 0; 00244 } 00245 } 00246 00247 return 0; 00248 } 00249 00250 int WINAPI ThemeSetWindowRgn(HWND hWnd, HRGN hRgn, BOOL bRedraw) 00251 { 00252 PWND_CONTEXT pcontext = ThemeGetWndContext(hWnd); 00253 if(pcontext) 00254 { 00255 pcontext->HasAppDefinedRgn = TRUE; 00256 pcontext->HasThemeRgn = FALSE; 00257 } 00258 00259 return user32ApiHook.SetWindowRgn(hWnd, hRgn, bRedraw); 00260 } 00261 00262 /********************************************************************** 00263 * Exports 00264 */ 00265 00266 BOOL CALLBACK 00267 ThemeInitApiHook(UAPIHK State, PUSERAPIHOOK puah) 00268 { 00269 /* Sanity checks for the caller */ 00270 if (!puah || State != uahLoadInit) 00271 { 00272 UXTHEME_LoadTheme(FALSE); 00273 ThemeCleanupWndContext(NULL, 0); 00274 return TRUE; 00275 } 00276 00277 /* Store the original functions from user32 */ 00278 user32ApiHook = *puah; 00279 00280 puah->DefWindowProcA = ThemeDefWindowProcA; 00281 puah->DefWindowProcW = ThemeDefWindowProcW; 00282 puah->PreWndProc = ThemePreWindowProc; 00283 puah->PostWndProc = ThemePostWindowProc; 00284 puah->PreDefDlgProc = ThemePreWindowProc; 00285 puah->PostDefDlgProc = ThemePostWindowProc; 00286 puah->DefWndProcArray.MsgBitArray = gabDWPmessages; 00287 puah->DefWndProcArray.Size = UAHOWP_MAX_SIZE; 00288 puah->WndProcArray.MsgBitArray = gabMSGPmessages; 00289 puah->WndProcArray.Size = UAHOWP_MAX_SIZE; 00290 puah->DlgProcArray.MsgBitArray = gabMSGPmessages; 00291 puah->DlgProcArray.Size = UAHOWP_MAX_SIZE; 00292 00293 puah->SetWindowRgn = ThemeSetWindowRgn; 00294 00295 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCPAINT); 00296 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCACTIVATE); 00297 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCMOUSEMOVE); 00298 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCMOUSELEAVE); 00299 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCHITTEST); 00300 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCLBUTTONDOWN); 00301 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCUAHDRAWCAPTION); 00302 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCUAHDRAWFRAME); 00303 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_SETTEXT); 00304 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_WINDOWPOSCHANGED); 00305 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_CONTEXTMENU); 00306 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_STYLECHANGED); 00307 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_SETICON); 00308 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_NCDESTROY); 00309 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_SYSCOMMAND); 00310 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_CTLCOLORMSGBOX); 00311 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_CTLCOLORBTN); 00312 UAH_HOOK_MESSAGE(puah->DefWndProcArray, WM_CTLCOLORSTATIC); 00313 00314 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_CREATE); 00315 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_SETTINGCHANGE); 00316 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_DRAWITEM); 00317 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_MEASUREITEM); 00318 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_WINDOWPOSCHANGING); 00319 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_WINDOWPOSCHANGED); 00320 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_STYLECHANGING); 00321 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_STYLECHANGED); 00322 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_NCCREATE); 00323 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_NCDESTROY); 00324 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_NCPAINT); 00325 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_MENUCHAR); 00326 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_MDISETMENU); 00327 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_THEMECHANGED); 00328 UAH_HOOK_MESSAGE(puah->WndProcArray, WM_UAHINIT); 00329 00330 UXTHEME_LoadTheme(TRUE); 00331 00332 return TRUE; 00333 } 00334 00335 typedef BOOL (WINAPI * PREGISTER_UAH_WINXP)(HINSTANCE hInstance, USERAPIHOOKPROC CallbackFunc); 00336 typedef BOOL (WINAPI * PREGISTER_UUAH_WIN2003)(PUSERAPIHOOKINFO puah); 00337 00338 BOOL WINAPI 00339 ThemeHooksInstall() 00340 { 00341 PVOID lpFunc; 00342 OSVERSIONINFO osvi; 00343 BOOL ret; 00344 00345 lpFunc = GetProcAddress(GetModuleHandle("user32.dll"), "RegisterUserApiHook"); 00346 00347 ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); 00348 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 00349 GetVersionEx(&osvi); 00350 00351 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) 00352 { 00353 PREGISTER_UAH_WINXP lpfuncxp = (PREGISTER_UAH_WINXP)lpFunc; 00354 ret = lpfuncxp(hDllInst, ThemeInitApiHook); 00355 } 00356 else if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) 00357 { 00358 PREGISTER_UUAH_WIN2003 lpfunc2003 = (PREGISTER_UUAH_WIN2003)lpFunc; 00359 USERAPIHOOKINFO uah; 00360 00361 uah.m_size = sizeof(uah); 00362 uah.m_dllname1 = L"uxtheme.dll"; 00363 uah.m_funname1 = L"ThemeInitApiHook"; 00364 uah.m_dllname2 = NULL; 00365 uah.m_funname2 = NULL; 00366 00367 ret = lpfunc2003(&uah); 00368 } 00369 else 00370 { 00371 UNIMPLEMENTED; 00372 ret = FALSE; 00373 } 00374 00375 UXTHEME_broadcast_msg (NULL, WM_THEMECHANGED); 00376 00377 return ret; 00378 } 00379 00380 BOOL WINAPI 00381 ThemeHooksRemove() 00382 { 00383 BOOL ret; 00384 00385 ret = UnregisterUserApiHook(); 00386 00387 UXTHEME_broadcast_msg (NULL, WM_THEMECHANGED); 00388 00389 return ret; 00390 } Generated on Sun May 27 2012 04:26:47 for ReactOS by
1.7.6.1
|