ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

themehooks.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.