Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentheming.c
Go to the documentation of this file.
00001 /* 00002 * Theming - Initialization 00003 * 00004 * Copyright (c) 2005 by Frank Richter 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 * 00020 */ 00021 00022 #include <stdarg.h> 00023 00024 #include "windef.h" 00025 #include "winbase.h" 00026 #include "wingdi.h" 00027 #include "winuser.h" 00028 #include "comctl32.h" 00029 #include "uxtheme.h" 00030 #include "wine/debug.h" 00031 00032 WINE_DEFAULT_DEBUG_CHANNEL(theming); 00033 00034 typedef LRESULT (CALLBACK* THEMING_SUBCLASSPROC)(HWND, UINT, WPARAM, LPARAM, 00035 ULONG_PTR); 00036 00037 extern LRESULT CALLBACK THEMING_ButtonSubclassProc (HWND, UINT, WPARAM, LPARAM, 00038 ULONG_PTR) DECLSPEC_HIDDEN; 00039 extern LRESULT CALLBACK THEMING_ComboSubclassProc (HWND, UINT, WPARAM, LPARAM, 00040 ULONG_PTR) DECLSPEC_HIDDEN; 00041 extern LRESULT CALLBACK THEMING_DialogSubclassProc (HWND, UINT, WPARAM, LPARAM, 00042 ULONG_PTR) DECLSPEC_HIDDEN; 00043 extern LRESULT CALLBACK THEMING_EditSubclassProc (HWND, UINT, WPARAM, LPARAM, 00044 ULONG_PTR) DECLSPEC_HIDDEN; 00045 extern LRESULT CALLBACK THEMING_ListBoxSubclassProc (HWND, UINT, WPARAM, LPARAM, 00046 ULONG_PTR) DECLSPEC_HIDDEN; 00047 00048 static const WCHAR dialogClass[] = {'#','3','2','7','7','0',0}; 00049 static const WCHAR comboLboxClass[] = {'C','o','m','b','o','L','b','o','x',0}; 00050 00051 static const struct ThemingSubclass 00052 { 00053 const WCHAR* className; 00054 THEMING_SUBCLASSPROC subclassProc; 00055 } subclasses[] = { 00056 /* Note: list must be sorted by class name */ 00057 {dialogClass, THEMING_DialogSubclassProc}, 00058 {WC_BUTTONW, THEMING_ButtonSubclassProc}, 00059 {WC_COMBOBOXW, THEMING_ComboSubclassProc}, 00060 {comboLboxClass, THEMING_ListBoxSubclassProc}, 00061 {WC_EDITW, THEMING_EditSubclassProc}, 00062 {WC_LISTBOXW, THEMING_ListBoxSubclassProc} 00063 }; 00064 00065 #define NUM_SUBCLASSES (sizeof(subclasses)/sizeof(subclasses[0])) 00066 00067 static WNDPROC originalProcs[NUM_SUBCLASSES]; 00068 static ATOM atRefDataProp; 00069 static ATOM atSubclassProp; 00070 00071 /* Generate a number of subclass window procs. 00072 * With a single proc alone, we can't really reliably find out the superclass, 00073 * so have one for each subclass. The subclass number is also stored in a prop 00074 * since it's needed by THEMING_CallOriginalClass(). Then, the subclass 00075 * proc and ref data are fetched and the proc called. 00076 */ 00077 #define MAKE_SUBCLASS_PROC(N) \ 00078 static LRESULT CALLBACK subclass_proc ## N (HWND wnd, UINT msg, \ 00079 WPARAM wParam, LPARAM lParam) \ 00080 { \ 00081 LRESULT result; \ 00082 ULONG_PTR refData; \ 00083 SetPropW (wnd, (LPCWSTR)MAKEINTATOM(atSubclassProp), (HANDLE)N); \ 00084 refData = (ULONG_PTR)GetPropW (wnd, (LPCWSTR)MAKEINTATOM(atRefDataProp)); \ 00085 TRACE ("%d; (%p, %x, %lx, %lx, %lx)\n", N, wnd, msg, wParam, lParam, \ 00086 refData); \ 00087 result = subclasses[N].subclassProc (wnd, msg, wParam, lParam, refData);\ 00088 TRACE ("result = %lx\n", result); \ 00089 return result; \ 00090 } 00091 00092 MAKE_SUBCLASS_PROC(0) 00093 MAKE_SUBCLASS_PROC(1) 00094 MAKE_SUBCLASS_PROC(2) 00095 MAKE_SUBCLASS_PROC(3) 00096 MAKE_SUBCLASS_PROC(4) 00097 MAKE_SUBCLASS_PROC(5) 00098 00099 static const WNDPROC subclassProcs[NUM_SUBCLASSES] = { 00100 subclass_proc0, 00101 subclass_proc1, 00102 subclass_proc2, 00103 subclass_proc3, 00104 subclass_proc4, 00105 subclass_proc5 00106 }; 00107 00108 /*********************************************************************** 00109 * THEMING_Initialize 00110 * 00111 * Register classes for standard controls that will shadow the system 00112 * classes. 00113 */ 00114 void THEMING_Initialize (void) 00115 { 00116 unsigned int i; 00117 static const WCHAR subclassPropName[] = 00118 { 'C','C','3','2','T','h','e','m','i','n','g','S','u','b','C','l',0 }; 00119 static const WCHAR refDataPropName[] = 00120 { 'C','C','3','2','T','h','e','m','i','n','g','D','a','t','a',0 }; 00121 00122 if (!IsThemeActive()) return; 00123 00124 atSubclassProp = GlobalAddAtomW (subclassPropName); 00125 atRefDataProp = GlobalAddAtomW (refDataPropName); 00126 00127 for (i = 0; i < NUM_SUBCLASSES; i++) 00128 { 00129 WNDCLASSEXW class; 00130 00131 class.cbSize = sizeof(class); 00132 if (!GetClassInfoExW (NULL, subclasses[i].className, &class)) 00133 { 00134 ERR("Could not retrieve information for class %s\n", 00135 debugstr_w (subclasses[i].className)); 00136 continue; 00137 } 00138 originalProcs[i] = class.lpfnWndProc; 00139 class.lpfnWndProc = subclassProcs[i]; 00140 00141 if (!class.lpfnWndProc) 00142 { 00143 ERR("Missing proc for class %s\n", 00144 debugstr_w (subclasses[i].className)); 00145 continue; 00146 } 00147 00148 if (!RegisterClassExW (&class)) 00149 { 00150 ERR("Could not re-register class %s: %x\n", 00151 debugstr_w (subclasses[i].className), GetLastError ()); 00152 } 00153 else 00154 { 00155 TRACE("Re-registered class %s\n", 00156 debugstr_w (subclasses[i].className)); 00157 } 00158 } 00159 } 00160 00161 /*********************************************************************** 00162 * THEMING_Uninitialize 00163 * 00164 * Unregister shadow classes for standard controls. 00165 */ 00166 void THEMING_Uninitialize (void) 00167 { 00168 unsigned int i; 00169 00170 if (!atSubclassProp) return; /* not initialized */ 00171 00172 for (i = 0; i < NUM_SUBCLASSES; i++) 00173 { 00174 UnregisterClassW (subclasses[i].className, NULL); 00175 } 00176 } 00177 00178 /*********************************************************************** 00179 * THEMING_CallOriginalClass 00180 * 00181 * Determines the original window proc and calls it. 00182 */ 00183 LRESULT THEMING_CallOriginalClass (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) 00184 { 00185 INT_PTR subclass = (INT_PTR)GetPropW (wnd, (LPCWSTR)MAKEINTATOM(atSubclassProp)); 00186 WNDPROC oldProc = originalProcs[subclass]; 00187 return CallWindowProcW (oldProc, wnd, msg, wParam, lParam); 00188 } 00189 00190 /*********************************************************************** 00191 * THEMING_SetSubclassData 00192 * 00193 * Update the "refData" value of the subclassed window. 00194 */ 00195 void THEMING_SetSubclassData (HWND wnd, ULONG_PTR refData) 00196 { 00197 SetPropW (wnd, (LPCWSTR)MAKEINTATOM(atRefDataProp), (HANDLE)refData); 00198 } Generated on Fri May 25 2012 04:21:01 for ReactOS by
1.7.6.1
|