Release 0.4.3
[wine] / windows / class.c
1 /*
2  * Window classes functions
3  *
4  * Copyright 1993 Alexandre Julliard
5  */
6
7 static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
8
9 #include "class.h"
10 #include "user.h"
11 #include "win.h"
12
13
14 static HCLASS firstClass = 0;
15
16
17 /***********************************************************************
18  *           CLASS_FindClassByName
19  *
20  * Return a handle and a pointer to the class.
21  */
22 HCLASS CLASS_FindClassByName( char * name, CLASS **ptr )
23 {
24     HCLASS class = firstClass;
25     while(class)
26     {
27         *ptr = (CLASS *) USER_HEAP_ADDR(class);
28         if (!strcasecmp( (*ptr)->wc.lpszClassName, name )) return class;
29         class = (*ptr)->hNext;
30     }
31     return 0;
32 }
33
34 /***********************************************************************
35  *           CLASS_FindClassPtr
36  *
37  * Return a pointer to the CLASS structure corresponding to a HCLASS.
38  */
39 CLASS * CLASS_FindClassPtr( HCLASS hclass )
40 {
41     CLASS * ptr;
42     
43     if (!hclass) return NULL;
44     ptr = (CLASS *) USER_HEAP_ADDR( hclass );
45     if (ptr->wMagic != CLASS_MAGIC) return NULL;
46     return ptr;
47 }
48
49
50 /***********************************************************************
51  *           RegisterClass    (USER.57)
52  */
53 ATOM RegisterClass( LPWNDCLASS class )
54 {
55     CLASS * newClass;
56     HCLASS handle;
57     
58 #ifdef DEBUG_CLASS
59     printf( "RegisterClass: wndproc=%08x hinst=%d name='%s'\n", 
60             class->lpfnWndProc, class->hInstance, class->lpszClassName );
61 #endif
62
63     handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CLASS)+class->cbClsExtra );
64     if (!handle) return 0;
65     newClass = (CLASS *) USER_HEAP_ADDR( handle );
66     newClass->hNext      = firstClass;
67     newClass->wMagic     = CLASS_MAGIC;
68     newClass->atomName   = handle;  /* Should be an atom */
69     newClass->cWindows   = 0;  
70     newClass->wc         = *class;
71
72     if (newClass->wc.style & CS_CLASSDC)
73         newClass->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL );
74     else newClass->hdc = 0;
75
76       /* Class name should also be set to zero. For now we need the
77        * name because we don't have atoms.
78        */
79     newClass->wc.lpszClassName = (char *)malloc(strlen(class->lpszClassName)+1);
80     strcpy( newClass->wc.lpszClassName, class->lpszClassName );
81     
82     if (class->cbClsExtra) memset( newClass->wExtra, 0, class->cbClsExtra );
83     
84     firstClass = handle;
85     return handle;  /* Should be an atom */
86 }
87
88
89 /***********************************************************************
90  *           UnregisterClass    (USER.403)
91  */
92 BOOL UnregisterClass( LPSTR className, HANDLE instance )
93 {
94     HANDLE class, next, prevClass;
95     CLASS * classPtr, * prevClassPtr;
96     
97       /* Check if we can remove this class */
98     class = CLASS_FindClassByName( className, &classPtr );
99     if (!class) return FALSE;
100     if ((classPtr->wc.hInstance != instance) || (classPtr->cWindows > 0))
101         return FALSE;
102     
103       /* Remove the class from the linked list */
104     if (firstClass == class) firstClass = classPtr->hNext;
105     else
106     {
107         for (prevClass = firstClass; prevClass; prevClass=prevClassPtr->hNext)
108         {
109             prevClassPtr = (CLASS *) USER_HEAP_ADDR(prevClass);
110             if (prevClassPtr->hNext == class) break;
111         }
112         if (!prevClass)
113         {
114             printf( "ERROR: Class list corrupted\n" );
115             return FALSE;
116         }
117         prevClassPtr->hNext = classPtr->hNext;
118     }
119
120       /* Delete the class */
121     if (classPtr->hdc) DeleteDC( classPtr->hdc );
122     if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground );
123     USER_HEAP_FREE( class );
124     return TRUE;
125 }
126
127
128 /***********************************************************************
129  *           GetClassWord    (USER.129)
130  */
131 WORD GetClassWord( HWND hwnd, short offset )
132 {
133     return (WORD)GetClassLong( hwnd, offset );
134 }
135
136
137 /***********************************************************************
138  *           SetClassWord    (USER.130)
139  */
140 WORD SetClassWord( HWND hwnd, short offset, WORD newval )
141 {
142     CLASS * classPtr;
143     WND * wndPtr;
144     WORD *ptr, retval = 0;
145     
146     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
147     if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
148     ptr = (WORD *)(((char *)classPtr->wExtra) + offset);
149     retval = *ptr;
150     *ptr = newval;
151     return retval;
152 }
153
154
155 /***********************************************************************
156  *           GetClassLong    (USER.131)
157  */
158 LONG GetClassLong( HWND hwnd, short offset )
159 {
160     CLASS * classPtr;
161     WND * wndPtr;
162     
163     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
164     if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
165     return *(LONG *)(((char *)classPtr->wExtra) + offset);
166 }
167
168
169 /***********************************************************************
170  *           SetClassLong    (USER.132)
171  */
172 LONG SetClassLong( HWND hwnd, short offset, LONG newval )
173 {
174     CLASS * classPtr;
175     WND * wndPtr;
176     LONG *ptr, retval = 0;
177     
178     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
179     if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
180     ptr = (LONG *)(((char *)classPtr->wExtra) + offset);
181     retval = *ptr;
182     *ptr = newval;
183     return retval;
184 }