Release 960824
[wine] / windows / property.c
1 /*
2  * Window properties
3  *
4  * Copyright 1995, 1996 Alexandre Julliard
5  */
6
7 #define NO_TRANSITION_TYPES  /* This file is Win32-clean */
8 #include <stdlib.h>
9 #include <string.h>
10 #include "win.h"
11 #include "heap.h"
12 #include "string32.h"
13 #include "stddebug.h"
14 #include "debug.h"
15
16
17 typedef struct tagPROPERTY
18 {
19     struct tagPROPERTY *next;     /* Next property in window list */
20     HANDLE32            handle;   /* User's data */
21     LPSTR               string;   /* Property string (or atom) */
22 } PROPERTY;
23
24
25 /***********************************************************************
26  *           PROP_FindProp
27  */
28 static PROPERTY *PROP_FindProp( HWND32 hwnd, LPCSTR str )
29 {
30     PROPERTY *prop;
31     WND *pWnd = WIN_FindWndPtr( hwnd );
32
33     if (!pWnd) return NULL;
34     if (HIWORD(str))
35     {
36         for (prop = pWnd->pProp; prop; prop = prop->next)
37             if (HIWORD(prop->string) && !lstrcmpi32A( prop->string, str ))
38                 return prop;
39     }
40     else  /* atom */
41     {
42         for (prop = pWnd->pProp; (prop); prop = prop->next)
43             if (!HIWORD(prop->string) && (LOWORD(prop->string) == LOWORD(str)))
44                 return prop;
45     }
46     return NULL;
47 }
48
49
50 /***********************************************************************
51  *           GetProp16   (USER.25)
52  */
53 HANDLE16 GetProp16( HWND16 hwnd, LPCSTR str )
54 {
55     return (HANDLE16)GetProp32A( hwnd, str );
56 }
57
58
59 /***********************************************************************
60  *           GetProp32A   (USER32.280)
61  */
62 HANDLE32 GetProp32A( HWND32 hwnd, LPCSTR str )
63 {
64     PROPERTY *prop = PROP_FindProp( hwnd, str );
65
66     if (HIWORD(str))
67         dprintf_prop( stddeb, "GetProp(%08x,'%s'): returning %08x\n",
68                       hwnd, str, prop ? prop->handle : 0 );
69     else
70         dprintf_prop( stddeb, "GetProp(%08x,#%04x): returning %08x\n",
71                       hwnd, LOWORD(str), prop ? prop->handle : 0 );
72
73     return prop ? prop->handle : 0;
74 }
75
76
77 /***********************************************************************
78  *           GetProp32W   (USER32.281)
79  */
80 HANDLE32 GetProp32W( HWND32 hwnd, LPCWSTR str )
81 {
82     LPSTR strA;
83     HANDLE32 ret;
84
85     if (!HIWORD(str)) return GetProp32A( hwnd, (LPCSTR)(UINT32)LOWORD(str) );
86     strA = STRING32_DupUniToAnsi( str );
87     ret = GetProp32A( hwnd, strA );
88     free( strA );
89     return ret;
90 }
91
92
93 /***********************************************************************
94  *           SetProp16   (USER.26)
95  */
96 BOOL16 SetProp16( HWND16 hwnd, LPCSTR str, HANDLE16 handle )
97 {
98     return (BOOL16)SetProp32A( hwnd, str, handle );
99 }
100
101
102 /***********************************************************************
103  *           SetProp32A   (USER32.496)
104  */
105 BOOL32 SetProp32A( HWND32 hwnd, LPCSTR str, HANDLE32 handle )
106 {
107     PROPERTY *prop;
108
109     if (HIWORD(str))
110         dprintf_prop( stddeb, "SetProp: %04x '%s' %08x\n", hwnd, str, handle );
111     else
112         dprintf_prop( stddeb, "SetProp: %04x #%04x %08x\n",
113                       hwnd, LOWORD(str), handle );
114
115     if (!(prop = PROP_FindProp( hwnd, str )))
116     {
117         /* We need to create it */
118         WND *pWnd = WIN_FindWndPtr( hwnd );
119         if (!pWnd) return FALSE;
120         if (!(prop = HeapAlloc( SystemHeap, 0, sizeof(*prop) ))) return FALSE;
121         if (!(prop->string = SEGPTR_STRDUP(str)))
122         {
123             HeapFree( SystemHeap, 0, prop );
124             return FALSE;
125         }
126         prop->next  = pWnd->pProp;
127         pWnd->pProp = prop;
128     }
129     prop->handle = handle;
130     return TRUE;
131 }
132
133
134 /***********************************************************************
135  *           SetProp32W   (USER32.497)
136  */
137 BOOL32 SetProp32W( HWND32 hwnd, LPCWSTR str, HANDLE32 handle )
138 {
139     BOOL32 ret;
140     LPSTR strA;
141
142     if (!HIWORD(str))
143         return SetProp32A( hwnd, (LPCSTR)(UINT32)LOWORD(str), handle );
144     strA = STRING32_DupUniToAnsi( str );
145     ret = SetProp32A( hwnd, strA, handle );
146     free( strA );
147     return ret;
148 }
149
150
151 /***********************************************************************
152  *           RemoveProp16   (USER.24)
153  */
154 HANDLE16 RemoveProp16( HWND16 hwnd, LPCSTR str )
155 {
156     return (HANDLE16)RemoveProp32A( hwnd, str );
157 }
158
159
160 /***********************************************************************
161  *           RemoveProp32A   (USER32.441)
162  */
163 HANDLE32 RemoveProp32A( HWND32 hwnd, LPCSTR str )
164 {
165     HANDLE32 handle;
166     PROPERTY **pprop, *prop;
167     WND *pWnd = WIN_FindWndPtr( hwnd );
168
169     dprintf_prop( stddeb, "RemoveProp: %04x '%s'\n", hwnd, str );
170     if (!pWnd) return NULL;
171     if (HIWORD(str))
172     {
173         for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
174             if (HIWORD((*pprop)->string) &&
175                 !lstrcmpi32A( (*pprop)->string, str )) break;
176     }
177     else  /* atom */
178     {
179         for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
180             if (!HIWORD((*pprop)->string) &&
181                 (LOWORD((*pprop)->string) == LOWORD(str))) break;
182     }
183     if (!*pprop) return 0;
184     prop   = *pprop;
185     handle = prop->handle;
186     *pprop = prop->next;
187     SEGPTR_FREE(prop->string);
188     HeapFree( SystemHeap, 0, prop );
189     return handle;
190 }
191
192
193 /***********************************************************************
194  *           RemoveProp32W   (USER32.442)
195  */
196 HANDLE32 RemoveProp32W( HWND32 hwnd, LPCWSTR str )
197 {
198     LPSTR strA;
199     HANDLE32 ret;
200
201     if (!HIWORD(str))
202         return RemoveProp32A( hwnd, (LPCSTR)(UINT32)LOWORD(str) );
203     strA = STRING32_DupUniToAnsi( str );
204     ret = RemoveProp32A( hwnd, strA );
205     free( strA );
206     return ret;
207 }
208
209
210 /***********************************************************************
211  *           PROPERTY_RemoveWindowProps
212  *
213  * Remove all properties of a window.
214  */
215 void PROPERTY_RemoveWindowProps( WND *pWnd )
216 {
217     PROPERTY *prop, *next;
218
219     for (prop = pWnd->pProp; (prop); prop = next)
220     {
221         next = prop->next;
222         SEGPTR_FREE( prop->string );
223         HeapFree( SystemHeap, 0, prop );
224     }
225     pWnd->pProp = NULL;
226 }
227
228
229 /***********************************************************************
230  *           EnumProps16   (USER.27)
231  */
232 INT16 EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
233 {
234     PROPERTY *prop, *next;
235     WND *pWnd;
236     INT16 ret = -1;
237
238     dprintf_prop( stddeb, "EnumProps: %04x %08x\n", hwnd, (UINT32)func );
239     if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
240     for (prop = pWnd->pProp; (prop); prop = next)
241     {
242         /* Already get the next in case the callback */
243         /* function removes the current property.    */
244         next = prop->next;
245
246         dprintf_prop( stddeb, "  Callback: handle=%08x str='%s'\n",
247                       prop->handle, prop->string );
248         ret = func( hwnd, SEGPTR_GET(prop->string), prop->handle );
249         if (!ret) break;
250     }
251     return ret;
252 }
253
254
255 /***********************************************************************
256  *           EnumProps32A   (USER32.185)
257  */
258 INT32 EnumProps32A( HWND32 hwnd, PROPENUMPROC32A func )
259 {
260     return EnumPropsEx32A( hwnd, (PROPENUMPROCEX32A)func, 0 );
261 }
262
263
264 /***********************************************************************
265  *           EnumProps32W   (USER32.188)
266  */
267 INT32 EnumProps32W( HWND32 hwnd, PROPENUMPROC32W func )
268 {
269     return EnumPropsEx32W( hwnd, (PROPENUMPROCEX32W)func, 0 );
270 }
271
272
273 /***********************************************************************
274  *           EnumPropsEx32A   (USER32.186)
275  */
276 INT32 EnumPropsEx32A( HWND32 hwnd, PROPENUMPROCEX32A func, LPARAM lParam )
277 {
278     PROPERTY *prop, *next;
279     WND *pWnd;
280     INT32 ret = -1;
281
282     dprintf_prop( stddeb, "EnumPropsEx32A: %04x %08x %08lx\n",
283                   hwnd, (UINT32)func, lParam );
284     if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
285     for (prop = pWnd->pProp; (prop); prop = next)
286     {
287         /* Already get the next in case the callback */
288         /* function removes the current property.    */
289         next = prop->next;
290
291         dprintf_prop( stddeb, "  Callback: handle=%08x str='%s'\n",
292                       prop->handle, prop->string );
293         ret = func( hwnd, prop->string, prop->handle, lParam );
294         if (!ret) break;
295     }
296     return ret;
297 }
298
299
300 /***********************************************************************
301  *           EnumPropsEx32W   (USER32.187)
302  */
303 INT32 EnumPropsEx32W( HWND32 hwnd, PROPENUMPROCEX32W func, LPARAM lParam )
304 {
305     PROPERTY *prop, *next;
306     WND *pWnd;
307     INT32 ret = -1;
308
309     dprintf_prop( stddeb, "EnumPropsEx32W: %04x %08x %08lx\n",
310                   hwnd, (UINT32)func, lParam );
311     if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
312     for (prop = pWnd->pProp; (prop); prop = next)
313     {
314         /* Already get the next in case the callback */
315         /* function removes the current property.    */
316         next = prop->next;
317
318         dprintf_prop( stddeb, "  Callback: handle=%08x str='%s'\n",
319                       prop->handle, prop->string );
320         if (HIWORD(prop->string))
321         {
322             LPWSTR str = STRING32_DupAnsiToUni( prop->string );
323             ret = func( hwnd, str, prop->handle, lParam );
324             free( str );
325         }
326         else
327             ret = func( hwnd, (LPCWSTR)(UINT32)LOWORD( prop->string ),
328                         prop->handle, lParam );
329         if (!ret) break;
330     }
331     return ret;
332 }