Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

classc.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: classc.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * This module contains 00007 * 00008 * History: 00009 * 15-Dec-1993 JohnC Pulled functions from user\server. 00010 \***************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 /* 00016 * These arrays are used by GetClassWord/Long. 00017 */ 00018 00019 // !!! can't we get rid of this and just special case GCW_ATOM 00020 00021 CONST BYTE afClassDWord[] = { 00022 FIELD_SIZE(CLS, spicnSm), // GCL_HICONSM (-34) 00023 0, 00024 FIELD_SIZE(CLS, atomClassName), // GCW_ATOM (-32) 00025 0, 00026 0, 00027 0, 00028 0, 00029 0, 00030 FIELD_SIZE(CLS, style), // GCL_STYLE (-26) 00031 0, 00032 FIELD_SIZE(CLS, lpfnWndProc), // GCL_WNDPROC (-24) 00033 0, 00034 0, 00035 0, 00036 FIELD_SIZE(CLS, cbclsExtra), // GCL_CBCLSEXTRA (-20) 00037 0, 00038 FIELD_SIZE(CLS, cbwndExtra), // GCL_CBWNDEXTRA (-18) 00039 0, 00040 FIELD_SIZE(CLS, hModule), // GCL_HMODULE (-16) 00041 0, 00042 FIELD_SIZE(CLS, spicn), // GCL_HICON (-14) 00043 0, 00044 FIELD_SIZE(CLS, spcur), // GCL_HCURSOR (-12) 00045 0, 00046 FIELD_SIZE(CLS, hbrBackground), // GCL_HBRBACKGROUND (-10) 00047 0, 00048 FIELD_SIZE(CLS, lpszMenuName) // GCL_HMENUNAME (-8) 00049 }; 00050 00051 CONST BYTE aiClassOffset[] = { 00052 FIELD_OFFSET(CLS, spicnSm), // GCL_HICONSM 00053 0, 00054 FIELD_OFFSET(CLS, atomClassName), // GCW_ATOM 00055 0, 00056 0, 00057 0, 00058 0, 00059 0, 00060 FIELD_OFFSET(CLS, style), // GCL_STYLE 00061 0, 00062 FIELD_OFFSET(CLS, lpfnWndProc), // GCL_WNDPROC 00063 0, 00064 0, 00065 0, 00066 FIELD_OFFSET(CLS, cbclsExtra), // GCL_CBCLSEXTRA 00067 0, 00068 FIELD_OFFSET(CLS, cbwndExtra), // GCL_CBWNDEXTRA 00069 0, 00070 FIELD_OFFSET(CLS, hModule), // GCL_HMODULE 00071 0, 00072 FIELD_OFFSET(CLS, spicn), // GCL_HICON 00073 0, 00074 FIELD_OFFSET(CLS, spcur), // GCL_HCURSOR 00075 0, 00076 FIELD_OFFSET(CLS, hbrBackground), // GCL_HBRBACKGROUND 00077 0, 00078 FIELD_OFFSET(CLS, lpszMenuName) // GCL_MENUNAME 00079 }; 00080 00081 /* 00082 * INDEX_OFFSET must refer to the first entry of afClassDWord[] 00083 */ 00084 #define INDEX_OFFSET GCLP_HICONSM 00085 00086 00087 /***************************************************************************\ 00088 * GetClassData 00089 * 00090 * GetClassWord and GetClassLong are now identical routines because they both 00091 * can return DWORDs. This single routine performs the work for them both 00092 * by using two arrays; afClassDWord to determine whether the result should be 00093 * a UINT or a DWORD, and aiClassOffset to find the correct offset into the 00094 * CLS structure for a given GCL_ or GCL_ index. 00095 * 00096 * History: 00097 * 11-19-90 darrinm Wrote. 00098 \***************************************************************************/ 00099 00100 ULONG_PTR _GetClassData( 00101 PCLS pcls, 00102 PWND pwnd, // used for transition to kernel-mode for GCL_WNDPROC 00103 int index, 00104 BOOL bAnsi) 00105 { 00106 KERNEL_ULONG_PTR dwData; 00107 DWORD dwCPDType = 0; 00108 00109 index -= INDEX_OFFSET; 00110 00111 if (index < 0) { 00112 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); 00113 return 0; 00114 } 00115 00116 UserAssert(index >= 0); 00117 UserAssert(index < sizeof(afClassDWord)); 00118 UserAssert(sizeof(afClassDWord) == sizeof(aiClassOffset)); 00119 if (afClassDWord[index] == sizeof(DWORD)) { 00120 dwData = *(DWORD *)(((BYTE *)pcls) + aiClassOffset[index]); 00121 } else if (afClassDWord[index] == sizeof(KERNEL_ULONG_PTR)) { 00122 dwData = *(KERNEL_ULONG_PTR *)(((BYTE *)pcls) + aiClassOffset[index]); 00123 } else { 00124 dwData = (DWORD)*(WORD *)(((BYTE *)pcls) + aiClassOffset[index]); 00125 } 00126 00127 index += INDEX_OFFSET; 00128 00129 /* 00130 * If we're returning an icon or cursor handle, do the reverse 00131 * mapping here. 00132 */ 00133 switch(index) { 00134 case GCLP_MENUNAME: 00135 if (IS_PTR(pcls->lpszMenuName)) { 00136 /* 00137 * The Menu Name is a real string: return the client-side address. 00138 * (If the class was registered by another app this returns an 00139 * address in that app's addr. space, but it's the best we can do) 00140 */ 00141 dwData = bAnsi ? 00142 (ULONG_PTR)pcls->lpszClientAnsiMenuName : 00143 (ULONG_PTR)pcls->lpszClientUnicodeMenuName; 00144 } 00145 break; 00146 00147 case GCLP_HICON: 00148 case GCLP_HCURSOR: 00149 case GCLP_HICONSM: 00150 /* 00151 * We have to go to the kernel to convert the pcursor to a handle because 00152 * cursors are allocated out of POOL, which is not accessable from the client. 00153 */ 00154 if (dwData) { 00155 dwData = NtUserCallHwndParam(PtoH(pwnd), index, SFI_GETCLASSICOCUR); 00156 } 00157 break; 00158 00159 case GCLP_WNDPROC: 00160 { 00161 00162 /* 00163 * Always return the client wndproc in case this is a server 00164 * window class. 00165 */ 00166 00167 if (pcls->CSF_flags & CSF_SERVERSIDEPROC) { 00168 dwData = MapServerToClientPfn(dwData, bAnsi); 00169 } else { 00170 KERNEL_ULONG_PTR dwT = dwData; 00171 00172 dwData = MapClientNeuterToClientPfn(pcls, dwT, bAnsi); 00173 00174 /* 00175 * If the client mapping didn't change the window proc then see if 00176 * we need a callproc handle. 00177 */ 00178 if (dwData == dwT) { 00179 /* 00180 * Need to return a CallProc handle if there is an Ansi/Unicode mismatch 00181 */ 00182 if (bAnsi != !!(pcls->CSF_flags & CSF_ANSIPROC)) { 00183 dwCPDType |= bAnsi ? CPD_ANSI_TO_UNICODE : CPD_UNICODE_TO_ANSI; 00184 } 00185 } 00186 } 00187 00188 if (dwCPDType) { 00189 ULONG_PTR dwCPD; 00190 00191 dwCPD = GetCPD(pwnd, dwCPDType | CPD_WNDTOCLS, KERNEL_ULONG_PTR_TO_ULONG_PTR(dwData)); 00192 00193 if (dwCPD) { 00194 dwData = dwCPD; 00195 } else { 00196 RIPMSG0(RIP_WARNING, "GetClassLong unable to alloc CPD returning handle\n"); 00197 } 00198 } 00199 } 00200 break; 00201 00202 case GCL_CBCLSEXTRA: 00203 if ((pcls->CSF_flags & CSF_WOWCLASS) && (pcls->CSF_flags & CSF_WOWEXTRA)) { 00204 /* 00205 * The 16-bit app changed its Extra bytes value. Return the changed 00206 * value. FritzS 00207 */ 00208 00209 return PWCFromPCLS(pcls)->iClsExtra; 00210 } 00211 else 00212 return pcls->cbclsExtra; 00213 00214 break; 00215 00216 /* 00217 * WOW uses a pointer straight into the class structure. 00218 */ 00219 case GCLP_WOWWORDS: 00220 if (pcls->CSF_flags & CSF_WOWCLASS) { 00221 return ((ULONG_PTR)PWCFromPCLS(pcls)); 00222 } else 00223 return 0; 00224 00225 case GCL_STYLE: 00226 dwData &= CS_VALID; 00227 break; 00228 } 00229 00230 return KERNEL_ULONG_PTR_TO_ULONG_PTR(dwData); 00231 } 00232 00233 00234 00235 /***************************************************************************\ 00236 * _GetClassLong (API) 00237 * 00238 * Return a class long. Positive index values return application class longs 00239 * while negative index values return system class longs. The negative 00240 * indices are published in WINDOWS.H. 00241 * 00242 * History: 00243 * 10-16-90 darrinm Wrote. 00244 \***************************************************************************/ 00245 00246 ULONG_PTR _GetClassLongPtr( 00247 PWND pwnd, 00248 int index, 00249 BOOL bAnsi) 00250 { 00251 PCLS pcls = REBASEALWAYS(pwnd, pcls); 00252 00253 if (index < 0) { 00254 return _GetClassData(pcls, pwnd, index, bAnsi); 00255 } else { 00256 if (index + (int)sizeof(ULONG_PTR) > pcls->cbclsExtra) { 00257 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); 00258 return 0; 00259 } else { 00260 ULONG_PTR UNALIGNED *pudw; 00261 pudw = (ULONG_PTR UNALIGNED *)((BYTE *)(pcls + 1) + index); 00262 return *pudw; 00263 } 00264 } 00265 } 00266 00267 #ifdef _WIN64 00268 DWORD _GetClassLong( 00269 PWND pwnd, 00270 int index, 00271 BOOL bAnsi) 00272 { 00273 PCLS pcls = REBASEALWAYS(pwnd, pcls); 00274 00275 if (index < 0) { 00276 if (index < INDEX_OFFSET || afClassDWord[index - INDEX_OFFSET] > sizeof(DWORD)) { 00277 RIPERR1(ERROR_INVALID_INDEX, RIP_WARNING, "GetClassLong: invalid index %d", index); 00278 return 0; 00279 } 00280 return (DWORD)_GetClassData(pcls, pwnd, index, bAnsi); 00281 } else { 00282 if (index + (int)sizeof(DWORD) > pcls->cbclsExtra) { 00283 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); 00284 return 0; 00285 } else { 00286 DWORD UNALIGNED *pudw; 00287 pudw = (DWORD UNALIGNED *)((BYTE *)(pcls + 1) + index); 00288 return *pudw; 00289 } 00290 } 00291 } 00292 #endif 00293 00294 /***************************************************************************\ 00295 * GetClassWord (API) 00296 * 00297 * Return a class word. Positive index values return application class words 00298 * while negative index values return system class words. The negative 00299 * indices are published in WINDOWS.H. 00300 * 00301 * History: 00302 * 10-16-90 darrinm Wrote. 00303 \***************************************************************************/ 00304 00305 WORD GetClassWord( 00306 HWND hwnd, 00307 int index) 00308 { 00309 PWND pwnd; 00310 PCLS pclsClient; 00311 00312 pwnd = ValidateHwnd(hwnd); 00313 00314 if (pwnd == NULL) 00315 return 0; 00316 00317 pclsClient = (PCLS)REBASEALWAYS(pwnd, pcls); 00318 00319 if (index == GCW_ATOM) { 00320 return (WORD)_GetClassData(pclsClient, pwnd, index, FALSE); 00321 } else { 00322 if ((index < 0) || (index + (int)sizeof(WORD) > pclsClient->cbclsExtra)) { 00323 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); 00324 return 0; 00325 } else { 00326 WORD UNALIGNED *puw; 00327 puw = (WORD UNALIGNED *)((BYTE *)(pclsClient + 1) + index); 00328 return *puw; 00329 } 00330 } 00331 }

Generated on Sat May 15 19:39:24 2004 for test by doxygen 1.3.7