Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Window classes functions |
| 3 | * |
| 4 | * Copyright 1993 Alexandre Julliard |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 5 | */ |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 6 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 7 | #include <stdlib.h> |
| 8 | #include <stdio.h> |
| 9 | #include <string.h> |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 10 | #include "class.h" |
| 11 | #include "user.h" |
| 12 | #include "win.h" |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 13 | #include "dce.h" |
Alexandre Julliard | e2991ea | 1995-07-29 13:09:43 +0000 | [diff] [blame] | 14 | #include "atom.h" |
Alexandre Julliard | 808cb04 | 1995-08-17 17:11:36 +0000 | [diff] [blame] | 15 | #include "ldt.h" |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 16 | #include "toolhelp.h" |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 17 | #include "stddebug.h" |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 18 | #include "debug.h" |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 19 | |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 20 | |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 21 | static CLASS *firstClass = NULL; |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 22 | |
| 23 | |
| 24 | /*********************************************************************** |
Alexandre Julliard | b817f4f | 1996-03-14 18:08:34 +0000 | [diff] [blame] | 25 | * CLASS_DumpClass |
| 26 | * |
| 27 | * Dump the content of a class structure to stderr. |
| 28 | */ |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 29 | void CLASS_DumpClass( CLASS *ptr ) |
Alexandre Julliard | b817f4f | 1996-03-14 18:08:34 +0000 | [diff] [blame] | 30 | { |
Alexandre Julliard | b817f4f | 1996-03-14 18:08:34 +0000 | [diff] [blame] | 31 | char className[80]; |
| 32 | int i; |
| 33 | |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 34 | if (((CLASS *)USER_HEAP_LIN_ADDR(ptr->self) != ptr) || |
| 35 | (ptr->wMagic != CLASS_MAGIC)) |
Alexandre Julliard | b817f4f | 1996-03-14 18:08:34 +0000 | [diff] [blame] | 36 | { |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 37 | fprintf( stderr, "%p is not a class\n", ptr ); |
Alexandre Julliard | b817f4f | 1996-03-14 18:08:34 +0000 | [diff] [blame] | 38 | return; |
| 39 | } |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 40 | |
Alexandre Julliard | b817f4f | 1996-03-14 18:08:34 +0000 | [diff] [blame] | 41 | GlobalGetAtomName( ptr->atomName, className, sizeof(className) ); |
| 42 | |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 43 | fprintf( stderr, "Class %p:\n", ptr ); |
Alexandre Julliard | b817f4f | 1996-03-14 18:08:34 +0000 | [diff] [blame] | 44 | fprintf( stderr, |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 45 | "next=%p name=%04x '%s' style=%04x wndProc=%08lx\n" |
Alexandre Julliard | b817f4f | 1996-03-14 18:08:34 +0000 | [diff] [blame] | 46 | "inst=%04x hdce=%04x icon=%04x cursor=%04x bkgnd=%04x\n" |
| 47 | "clsExtra=%d winExtra=%d #windows=%d\n", |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 48 | ptr->next, ptr->atomName, className, ptr->wc.style, |
Alexandre Julliard | b817f4f | 1996-03-14 18:08:34 +0000 | [diff] [blame] | 49 | (DWORD)ptr->wc.lpfnWndProc, ptr->wc.hInstance, ptr->hdce, |
| 50 | ptr->wc.hIcon, ptr->wc.hCursor, ptr->wc.hbrBackground, |
| 51 | ptr->wc.cbClsExtra, ptr->wc.cbWndExtra, ptr->cWindows ); |
| 52 | if (ptr->wc.cbClsExtra) |
| 53 | { |
| 54 | fprintf( stderr, "extra bytes:" ); |
| 55 | for (i = 0; i < ptr->wc.cbClsExtra; i++) |
| 56 | fprintf( stderr, " %02x", *((BYTE *)ptr->wExtra+i) ); |
| 57 | fprintf( stderr, "\n" ); |
| 58 | } |
| 59 | fprintf( stderr, "\n" ); |
| 60 | } |
| 61 | |
| 62 | |
| 63 | /*********************************************************************** |
| 64 | * CLASS_WalkClasses |
| 65 | * |
| 66 | * Walk the class list and print each class on stderr. |
| 67 | */ |
| 68 | void CLASS_WalkClasses(void) |
| 69 | { |
Alexandre Julliard | b817f4f | 1996-03-14 18:08:34 +0000 | [diff] [blame] | 70 | CLASS *ptr; |
| 71 | char className[80]; |
| 72 | |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 73 | fprintf( stderr, " Class Name Style WndProc\n" ); |
| 74 | for (ptr = firstClass; ptr; ptr = ptr->next) |
Alexandre Julliard | b817f4f | 1996-03-14 18:08:34 +0000 | [diff] [blame] | 75 | { |
Alexandre Julliard | b817f4f | 1996-03-14 18:08:34 +0000 | [diff] [blame] | 76 | GlobalGetAtomName( ptr->atomName, className, sizeof(className) ); |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 77 | fprintf( stderr, "%08lx %-20.20s %04x %08lx\n", (DWORD)ptr, className, |
| 78 | ptr->wc.style, (DWORD)ptr->wc.lpfnWndProc ); |
Alexandre Julliard | b817f4f | 1996-03-14 18:08:34 +0000 | [diff] [blame] | 79 | } |
| 80 | fprintf( stderr, "\n" ); |
| 81 | } |
| 82 | |
| 83 | |
| 84 | /*********************************************************************** |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 85 | * CLASS_FreeClass |
| 86 | * |
| 87 | * Free a class structure. |
| 88 | */ |
| 89 | static void CLASS_FreeClass( CLASS *classPtr ) |
| 90 | { |
| 91 | CLASS **ppClass; |
| 92 | |
| 93 | /* Remove the class from the linked list */ |
| 94 | |
| 95 | for (ppClass = &firstClass; *ppClass; ppClass = &(*ppClass)->next) |
| 96 | if (*ppClass == classPtr) break; |
| 97 | if (!*ppClass) |
| 98 | { |
| 99 | fprintf(stderr, "ERROR: Class list corrupted\n" ); |
| 100 | return; |
| 101 | } |
| 102 | *ppClass = classPtr->next; |
| 103 | |
| 104 | /* Delete the class */ |
| 105 | |
| 106 | if (classPtr->hdce) DCE_FreeDCE( classPtr->hdce ); |
| 107 | if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground ); |
| 108 | GlobalDeleteAtom( classPtr->atomName ); |
| 109 | if (HIWORD(classPtr->wc.lpszMenuName)) |
| 110 | USER_HEAP_FREE( (HANDLE)classPtr->wc.lpszMenuName ); |
| 111 | USER_HEAP_FREE( classPtr->self ); |
| 112 | } |
| 113 | |
| 114 | |
| 115 | /*********************************************************************** |
| 116 | * CLASS_FreeModuleClasses |
| 117 | */ |
| 118 | void CLASS_FreeModuleClasses( HMODULE hModule ) |
| 119 | { |
| 120 | CLASS *ptr, *next; |
| 121 | |
| 122 | for (ptr = firstClass; ptr; ptr = next) |
| 123 | { |
| 124 | next = ptr->next; |
| 125 | if (ptr->wc.hInstance == hModule) CLASS_FreeClass( ptr ); |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | |
| 130 | /*********************************************************************** |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 131 | * CLASS_FindClassByName |
| 132 | * |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 133 | * Return a pointer to the class. |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 134 | */ |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 135 | CLASS *CLASS_FindClassByName( SEGPTR name, HINSTANCE hinstance ) |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 136 | { |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 137 | ATOM atom; |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 138 | CLASS * class; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 139 | |
Alexandre Julliard | b7258be | 1995-09-01 15:57:28 +0000 | [diff] [blame] | 140 | if (!(atom = GlobalFindAtom( name ))) return 0; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 141 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 142 | /* First search task-specific classes */ |
| 143 | |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 144 | for (class = firstClass; (class); class = class->next) |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 145 | { |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 146 | if (class->wc.style & CS_GLOBALCLASS) continue; |
| 147 | if ((class->atomName == atom) && |
| 148 | ((hinstance==(HINSTANCE)0xffff) || |
| 149 | (hinstance == class->wc.hInstance))) return class; |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 150 | } |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 151 | |
| 152 | /* Then search global classes */ |
| 153 | |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 154 | for (class = firstClass; (class); class = class->next) |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 155 | { |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 156 | if (!(class->wc.style & CS_GLOBALCLASS)) continue; |
| 157 | if (class->atomName == atom) return class; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 158 | } |
| 159 | |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 160 | return 0; |
| 161 | } |
| 162 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 163 | |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 164 | /*********************************************************************** |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 165 | * RegisterClass (USER.57) |
| 166 | */ |
| 167 | ATOM RegisterClass( LPWNDCLASS class ) |
| 168 | { |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 169 | CLASS * newClass, * prevClass; |
| 170 | HCLASS handle; |
Alexandre Julliard | 6b81b39 | 1994-07-07 16:23:58 +0000 | [diff] [blame] | 171 | int classExtra; |
| 172 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 173 | dprintf_class( stddeb, "RegisterClass: wndproc=%08lx hinst=%04x name='%s' background %04x\n", |
Alexandre Julliard | 808cb04 | 1995-08-17 17:11:36 +0000 | [diff] [blame] | 174 | (DWORD)class->lpfnWndProc, class->hInstance, |
| 175 | HIWORD(class->lpszClassName) ? |
| 176 | (char *)PTR_SEG_TO_LIN(class->lpszClassName) : "(int)", |
| 177 | class->hbrBackground ); |
| 178 | dprintf_class(stddeb," style=%04x clsExtra=%d winExtra=%d\n", |
| 179 | class->style, class->cbClsExtra, class->cbWndExtra ); |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 180 | |
| 181 | /* Window classes are owned by modules, not instances */ |
| 182 | class->hInstance = GetExePtr( class->hInstance ); |
| 183 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 184 | /* Check if a class with this name already exists */ |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 185 | prevClass = CLASS_FindClassByName( class->lpszClassName, class->hInstance); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 186 | if (prevClass) |
| 187 | { |
| 188 | /* Class can be created only if it is local and */ |
| 189 | /* if the class with the same name is global. */ |
| 190 | |
| 191 | if (class->style & CS_GLOBALCLASS) return 0; |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 192 | if (!(prevClass->wc.style & CS_GLOBALCLASS)) return 0; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 193 | } |
| 194 | |
| 195 | /* Create class */ |
| 196 | |
Alexandre Julliard | 6b81b39 | 1994-07-07 16:23:58 +0000 | [diff] [blame] | 197 | classExtra = (class->cbClsExtra < 0) ? 0 : class->cbClsExtra; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 198 | handle = USER_HEAP_ALLOC( sizeof(CLASS) + classExtra ); |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 199 | if (!handle) return 0; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 200 | newClass = (CLASS *) USER_HEAP_LIN_ADDR( handle ); |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 201 | newClass->self = handle; |
| 202 | newClass->next = firstClass; |
Alexandre Julliard | 6b81b39 | 1994-07-07 16:23:58 +0000 | [diff] [blame] | 203 | newClass->wMagic = CLASS_MAGIC; |
| 204 | newClass->cWindows = 0; |
| 205 | newClass->wc = *class; |
| 206 | newClass->wc.cbWndExtra = (class->cbWndExtra < 0) ? 0 : class->cbWndExtra; |
| 207 | newClass->wc.cbClsExtra = classExtra; |
Alexandre Julliard | f0b2354 | 1993-09-29 12:21:49 +0000 | [diff] [blame] | 208 | |
Alexandre Julliard | b7258be | 1995-09-01 15:57:28 +0000 | [diff] [blame] | 209 | newClass->atomName = GlobalAddAtom( class->lpszClassName ); |
Alexandre Julliard | 808cb04 | 1995-08-17 17:11:36 +0000 | [diff] [blame] | 210 | newClass->wc.lpszClassName = 0; |
Alexandre Julliard | f0b2354 | 1993-09-29 12:21:49 +0000 | [diff] [blame] | 211 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 212 | if (newClass->wc.style & CS_CLASSDC) |
| 213 | newClass->hdce = DCE_AllocDCE( DCE_CLASS_DC ); |
| 214 | else newClass->hdce = 0; |
| 215 | |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 216 | /* Make a copy of the menu name (only if it is a string) */ |
| 217 | |
Alexandre Julliard | 808cb04 | 1995-08-17 17:11:36 +0000 | [diff] [blame] | 218 | if (HIWORD(class->lpszMenuName)) |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 219 | { |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 220 | char *menuname = PTR_SEG_TO_LIN( class->lpszMenuName ); |
| 221 | HANDLE hname = USER_HEAP_ALLOC( strlen(menuname)+1 ); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 222 | if (hname) |
| 223 | { |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 224 | newClass->wc.lpszMenuName = (SEGPTR)USER_HEAP_SEG_ADDR( hname ); |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 225 | strcpy( USER_HEAP_LIN_ADDR( hname ), menuname ); |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 226 | } |
| 227 | } |
| 228 | |
Alexandre Julliard | 6b81b39 | 1994-07-07 16:23:58 +0000 | [diff] [blame] | 229 | if (classExtra) memset( newClass->wExtra, 0, classExtra ); |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 230 | firstClass = newClass; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 231 | return newClass->atomName; |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 232 | } |
| 233 | |
| 234 | |
| 235 | /*********************************************************************** |
| 236 | * UnregisterClass (USER.403) |
| 237 | */ |
Alexandre Julliard | 808cb04 | 1995-08-17 17:11:36 +0000 | [diff] [blame] | 238 | BOOL UnregisterClass( SEGPTR className, HANDLE hinstance ) |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 239 | { |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 240 | CLASS *classPtr; |
| 241 | |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 242 | hinstance = GetExePtr( hinstance ); |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 243 | |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 244 | /* Check if we can remove this class */ |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 245 | if (!(classPtr = CLASS_FindClassByName( className, hinstance ))) |
| 246 | return FALSE; |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 247 | if ((classPtr->wc.hInstance != hinstance) || (classPtr->cWindows > 0)) |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 248 | return FALSE; |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 249 | CLASS_FreeClass( classPtr ); |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 250 | return TRUE; |
| 251 | } |
| 252 | |
| 253 | |
| 254 | /*********************************************************************** |
| 255 | * GetClassWord (USER.129) |
| 256 | */ |
| 257 | WORD GetClassWord( HWND hwnd, short offset ) |
| 258 | { |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 259 | WND * wndPtr; |
| 260 | |
| 261 | if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; |
| 262 | if (offset >= 0) |
| 263 | return *(WORD *)(((char *)wndPtr->class->wExtra) + offset); |
| 264 | switch(offset) |
| 265 | { |
| 266 | case GCW_HBRBACKGROUND: return wndPtr->class->wc.hbrBackground; |
| 267 | case GCW_HCURSOR: return wndPtr->class->wc.hCursor; |
| 268 | case GCW_HICON: return wndPtr->class->wc.hIcon; |
| 269 | case GCW_HMODULE: return wndPtr->class->wc.hInstance; |
| 270 | case GCW_CBWNDEXTRA: return wndPtr->class->wc.cbWndExtra; |
| 271 | case GCW_CBCLSEXTRA: return wndPtr->class->wc.cbClsExtra; |
| 272 | case GCW_STYLE: return wndPtr->class->wc.style; |
| 273 | case GCW_ATOM: return wndPtr->class->atomName; |
| 274 | } |
| 275 | fprintf(stderr, "Warning: invalid offset %d for GetClassWord()\n", offset); |
| 276 | return 0; |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 277 | } |
| 278 | |
| 279 | |
| 280 | /*********************************************************************** |
| 281 | * SetClassWord (USER.130) |
| 282 | */ |
| 283 | WORD SetClassWord( HWND hwnd, short offset, WORD newval ) |
| 284 | { |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 285 | WND * wndPtr; |
Alexandre Julliard | f0b2354 | 1993-09-29 12:21:49 +0000 | [diff] [blame] | 286 | WORD *ptr, retval = 0; |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 287 | |
| 288 | if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 289 | if (offset >= 0) ptr = (WORD *)(((char *)wndPtr->class->wExtra) + offset); |
| 290 | else switch(offset) |
| 291 | { |
| 292 | case GCW_HBRBACKGROUND: ptr = &wndPtr->class->wc.hbrBackground; break; |
| 293 | case GCW_HCURSOR: ptr = &wndPtr->class->wc.hCursor; break; |
| 294 | case GCW_HICON: ptr = &wndPtr->class->wc.hIcon; break; |
| 295 | case GCW_HMODULE: ptr = &wndPtr->class->wc.hInstance; break; |
| 296 | case GCW_CBWNDEXTRA: ptr = &wndPtr->class->wc.cbWndExtra; break; |
| 297 | case GCW_CBCLSEXTRA: ptr = &wndPtr->class->wc.cbClsExtra; break; |
| 298 | case GCW_STYLE: ptr = &wndPtr->class->wc.style; break; |
| 299 | case GCW_ATOM: ptr = &wndPtr->class->atomName; break; |
| 300 | default: |
| 301 | fprintf( stderr, "Warning: invalid offset %d for SetClassWord()\n", |
| 302 | offset); |
| 303 | return 0; |
| 304 | } |
Alexandre Julliard | f0b2354 | 1993-09-29 12:21:49 +0000 | [diff] [blame] | 305 | retval = *ptr; |
| 306 | *ptr = newval; |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 307 | return retval; |
| 308 | } |
| 309 | |
| 310 | |
| 311 | /*********************************************************************** |
| 312 | * GetClassLong (USER.131) |
| 313 | */ |
| 314 | LONG GetClassLong( HWND hwnd, short offset ) |
| 315 | { |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 316 | WND * wndPtr; |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 317 | |
| 318 | if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 319 | if (offset >= 0) |
| 320 | return *(WORD *)(((char *)wndPtr->class->wExtra) + offset); |
| 321 | switch(offset) |
| 322 | { |
| 323 | case GCL_MENUNAME: return (LONG)wndPtr->class->wc.lpszMenuName; |
| 324 | case GCL_WNDPROC: return (LONG)wndPtr->class->wc.lpfnWndProc; |
| 325 | } |
| 326 | fprintf(stderr, "Warning: invalid offset %d for GetClassLong()\n", offset); |
| 327 | return 0; |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 328 | } |
| 329 | |
| 330 | |
| 331 | /*********************************************************************** |
| 332 | * SetClassLong (USER.132) |
| 333 | */ |
| 334 | LONG SetClassLong( HWND hwnd, short offset, LONG newval ) |
| 335 | { |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 336 | WND * wndPtr; |
Alexandre Julliard | f0b2354 | 1993-09-29 12:21:49 +0000 | [diff] [blame] | 337 | LONG *ptr, retval = 0; |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 338 | |
| 339 | if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 340 | if (offset >= 0) ptr = (LONG *)(((char *)wndPtr->class->wExtra) + offset); |
| 341 | else switch(offset) |
| 342 | { |
| 343 | case GCL_MENUNAME: ptr = (LONG*)&wndPtr->class->wc.lpszMenuName; break; |
| 344 | case GCL_WNDPROC: ptr = (LONG*)&wndPtr->class->wc.lpfnWndProc; break; |
| 345 | default: |
| 346 | fprintf( stderr, "Warning: invalid offset %d for SetClassLong()\n", |
| 347 | offset); |
| 348 | return 0; |
| 349 | } |
Alexandre Julliard | f0b2354 | 1993-09-29 12:21:49 +0000 | [diff] [blame] | 350 | retval = *ptr; |
| 351 | *ptr = newval; |
Alexandre Julliard | 401710d | 1993-09-04 10:09:32 +0000 | [diff] [blame] | 352 | return retval; |
| 353 | } |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 354 | |
| 355 | |
| 356 | /*********************************************************************** |
| 357 | * GetClassName (USER.58) |
| 358 | */ |
| 359 | int GetClassName(HWND hwnd, LPSTR lpClassName, short maxCount) |
| 360 | { |
| 361 | WND *wndPtr; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 362 | |
Alexandre Julliard | 3ed37e0 | 1994-11-07 18:20:42 +0000 | [diff] [blame] | 363 | /* FIXME: We have the find the correct hInstance */ |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 364 | dprintf_class(stddeb,"GetClassName(%04x,%p,%d)\n",hwnd,lpClassName,maxCount); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 365 | if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 366 | |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 367 | return GlobalGetAtomName( wndPtr->class->atomName, lpClassName, maxCount ); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 368 | } |
| 369 | |
| 370 | |
| 371 | /*********************************************************************** |
| 372 | * GetClassInfo (USER.404) |
| 373 | */ |
Alexandre Julliard | 808cb04 | 1995-08-17 17:11:36 +0000 | [diff] [blame] | 374 | BOOL GetClassInfo( HANDLE hInstance, SEGPTR name, LPWNDCLASS lpWndClass ) |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 375 | { |
| 376 | CLASS *classPtr; |
Alexandre Julliard | 3ed37e0 | 1994-11-07 18:20:42 +0000 | [diff] [blame] | 377 | |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 378 | dprintf_class( stddeb, "GetClassInfo: hInstance=%04x className=%s\n", |
Alexandre Julliard | 808cb04 | 1995-08-17 17:11:36 +0000 | [diff] [blame] | 379 | hInstance, |
| 380 | HIWORD(name) ? (char *)PTR_SEG_TO_LIN(name) : "(int)" ); |
| 381 | |
| 382 | hInstance = GetExePtr( hInstance ); |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 383 | |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 384 | if (!(classPtr = CLASS_FindClassByName( name, hInstance ))) return FALSE; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 385 | if (hInstance && (hInstance != classPtr->wc.hInstance)) return FALSE; |
| 386 | |
| 387 | memcpy(lpWndClass, &(classPtr->wc), sizeof(WNDCLASS)); |
| 388 | return TRUE; |
| 389 | } |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 390 | |
| 391 | |
| 392 | /*********************************************************************** |
| 393 | * ClassFirst (TOOLHELP.69) |
| 394 | */ |
| 395 | BOOL ClassFirst( CLASSENTRY *pClassEntry ) |
| 396 | { |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 397 | pClassEntry->wNext = 1; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 398 | return ClassNext( pClassEntry ); |
| 399 | } |
| 400 | |
| 401 | |
| 402 | /*********************************************************************** |
| 403 | * ClassNext (TOOLHELP.70) |
| 404 | */ |
| 405 | BOOL ClassNext( CLASSENTRY *pClassEntry ) |
| 406 | { |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 407 | int i; |
| 408 | CLASS *class = firstClass; |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 409 | |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame^] | 410 | if (!pClassEntry->wNext) return FALSE; |
| 411 | for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next; |
| 412 | if (!class) |
| 413 | { |
| 414 | pClassEntry->wNext = 0; |
| 415 | return FALSE; |
| 416 | } |
| 417 | pClassEntry->hInst = class->wc.hInstance; |
| 418 | pClassEntry->wNext++; |
| 419 | GlobalGetAtomName( class->atomName, pClassEntry->szClassName, |
Alexandre Julliard | e2abbb1 | 1995-03-19 17:39:39 +0000 | [diff] [blame] | 420 | sizeof(pClassEntry->szClassName) ); |
| 421 | return TRUE; |
| 422 | } |