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