Release 0.4.0
[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->hDCE       = 0;  /* Should allocate a DCE if needed */
70     newClass->cWindows   = 0;  
71     newClass->wc         = *class;
72         
73       /* Class name should also be set to zero. For now we need the
74        * name because we don't have atoms.
75        */
76     newClass->wc.lpszClassName = (char *)malloc(strlen(class->lpszClassName)+1);
77     strcpy( newClass->wc.lpszClassName, class->lpszClassName );
78     
79     if (class->cbClsExtra) memset( newClass->wExtra, 0, class->cbClsExtra );
80     
81     firstClass = handle;
82     return handle;  /* Should be an atom */
83 }
84
85
86 /***********************************************************************
87  *           UnregisterClass    (USER.403)
88  */
89 BOOL UnregisterClass( LPSTR className, HANDLE instance )
90 {
91     HANDLE class, next, prevClass;
92     CLASS * classPtr, * prevClassPtr;
93     
94       /* Check if we can remove this class */
95     class = CLASS_FindClassByName( className, &classPtr );
96     if (!class) return FALSE;
97     if ((classPtr->wc.hInstance != instance) || (classPtr->cWindows > 0))
98         return FALSE;
99     
100       /* Remove the class from the linked list */
101     if (firstClass == class) firstClass = classPtr->hNext;
102     else
103     {
104         for (prevClass = firstClass; prevClass; prevClass=prevClassPtr->hNext)
105         {
106             prevClassPtr = (CLASS *) USER_HEAP_ADDR(prevClass);
107             if (prevClassPtr->hNext == class) break;
108         }
109         if (!prevClass)
110         {
111             printf( "ERROR: Class list corrupted\n" );
112             return FALSE;
113         }
114         prevClassPtr->hNext = classPtr->hNext;
115     }
116     
117     USER_HEAP_FREE( class );
118     return TRUE;
119 }
120
121
122 /***********************************************************************
123  *           GetClassWord    (USER.129)
124  */
125 WORD GetClassWord( HWND hwnd, short offset )
126 {
127     return (WORD)GetClassLong( hwnd, offset );
128 }
129
130
131 /***********************************************************************
132  *           SetClassWord    (USER.130)
133  */
134 WORD SetClassWord( HWND hwnd, short offset, WORD newval )
135 {
136     CLASS * classPtr;
137     WND * wndPtr;
138     WORD retval = 0;
139     
140     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
141     if ((classPtr = CLASS_FindClassPtr( wndPtr->hClass )))
142     {
143         WORD * ptr = (WORD *)(((char *)classPtr->wExtra) + offset);
144         retval = *ptr;
145         *ptr = newval;
146     }
147     GlobalUnlock( hwnd );
148     return retval;
149 }
150
151
152 /***********************************************************************
153  *           GetClassLong    (USER.131)
154  */
155 LONG GetClassLong( HWND hwnd, short offset )
156 {
157     CLASS * classPtr;
158     WND * wndPtr;
159     LONG retval = 0;
160     
161     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
162     if ((classPtr = CLASS_FindClassPtr( wndPtr->hClass )))
163         retval = *(LONG *)(((char *)classPtr->wExtra) + offset);
164     GlobalUnlock( hwnd );
165     return retval;
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 retval = 0;
177     
178     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
179     if ((classPtr = CLASS_FindClassPtr( wndPtr->hClass )))
180     {
181         LONG * ptr = (LONG *)(((char *)classPtr->wExtra) + offset);
182         retval = *ptr;
183         *ptr = newval;
184     }
185     GlobalUnlock( hwnd );
186     return retval;
187 }