Added/fixed some documentation reported by winapi_check.
[wine] / windows / property.c
1 /*
2  * Window properties
3  *
4  * Copyright 1995, 1996 Alexandre Julliard
5  */
6
7 #include <string.h>
8
9 #include "windef.h"
10 #include "wingdi.h"
11 #include "wine/winuser16.h"
12 #include "win.h"
13 #include "heap.h"
14 #include "debugtools.h"
15
16 DEFAULT_DEBUG_CHANNEL(prop)
17
18
19 typedef struct tagPROPERTY
20 {
21     struct tagPROPERTY *next;     /* Next property in window list */
22     HANDLE            handle;   /* User's data */
23     LPSTR               string;   /* Property string (or atom) */
24 } PROPERTY;
25
26
27 /***********************************************************************
28  *           PROP_FindProp
29  */
30 static PROPERTY *PROP_FindProp( HWND hwnd, LPCSTR str )
31 {
32     ATOM atom;
33     PROPERTY *prop;
34     WND *pWnd = WIN_FindWndPtr( hwnd );
35
36     if (!pWnd) return NULL;
37     if (HIWORD(str))
38     {
39         atom = GlobalFindAtomA( str );
40         for (prop = pWnd->pProp; prop; prop = prop->next)
41         {
42             if (HIWORD(prop->string))
43             {
44                 if (!lstrcmpiA( prop->string, str )) goto END;
45             }
46             else if (LOWORD(prop->string) == atom) goto END;
47         }
48     }
49     else  /* atom */
50     {
51         atom = LOWORD(str);
52         for (prop = pWnd->pProp; (prop); prop = prop->next)
53         {
54             if (HIWORD(prop->string))
55             {
56                 if (GlobalFindAtomA( prop->string ) == atom) goto END;
57             }
58             else if (LOWORD(prop->string) == atom) goto END;
59         }
60     }
61     prop = NULL;
62 END:
63     WIN_ReleaseWndPtr(pWnd);
64     return prop;
65 }
66
67
68 /***********************************************************************
69  *           GetProp16   (USER.25)
70  */
71 HANDLE16 WINAPI GetProp16( HWND16 hwnd, LPCSTR str )
72 {
73     return (HANDLE16)GetPropA( hwnd, str );
74 }
75
76
77 /***********************************************************************
78  *           GetPropA   (USER32.281)
79  */
80 HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
81 {
82     PROPERTY *prop = PROP_FindProp( hwnd, str );
83
84     if (HIWORD(str))
85         TRACE("(%08x,'%s'): returning %08x\n",
86                       hwnd, str, prop ? prop->handle : 0 );
87     else
88         TRACE("(%08x,#%04x): returning %08x\n",
89                       hwnd, LOWORD(str), prop ? prop->handle : 0 );
90
91     return prop ? prop->handle : 0;
92 }
93
94
95 /***********************************************************************
96  *           GetPropW   (USER32.282)
97  */
98 HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
99 {
100     LPSTR strA;
101     HANDLE ret;
102
103     if (!HIWORD(str)) return GetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str) );
104     strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
105     ret = GetPropA( hwnd, strA );
106     HeapFree( GetProcessHeap(), 0, strA );
107     return ret;
108 }
109
110
111 /***********************************************************************
112  *           SetProp16   (USER.26)
113  */
114 BOOL16 WINAPI SetProp16( HWND16 hwnd, LPCSTR str, HANDLE16 handle )
115 {
116     return (BOOL16)SetPropA( hwnd, str, handle );
117 }
118
119
120 /***********************************************************************
121  *           SetPropA   (USER32.497)
122  */
123 BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
124 {
125     PROPERTY *prop;
126
127     if (HIWORD(str))
128         TRACE("%04x '%s' %08x\n", hwnd, str, handle );
129     else
130         TRACE("%04x #%04x %08x\n",
131                       hwnd, LOWORD(str), handle );
132
133     if (!(prop = PROP_FindProp( hwnd, str )))
134     {
135         /* We need to create it */
136         WND *pWnd = WIN_FindWndPtr( hwnd );
137         if (!pWnd) return FALSE;
138         if (!(prop = HeapAlloc( SystemHeap, 0, sizeof(*prop) )))
139         {
140             WIN_ReleaseWndPtr(pWnd);
141             return FALSE;
142         }
143         if (!(prop->string = SEGPTR_STRDUP(str)))
144         {
145             HeapFree( SystemHeap, 0, prop );
146             WIN_ReleaseWndPtr(pWnd);
147             return FALSE;
148
149         }
150         prop->next  = pWnd->pProp;
151         pWnd->pProp = prop;
152         WIN_ReleaseWndPtr(pWnd);
153     }
154     prop->handle = handle;
155     return TRUE;
156 }
157
158
159 /***********************************************************************
160  *           SetPropW   (USER32.498)
161  */
162 BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
163 {
164     BOOL ret;
165     LPSTR strA;
166
167     if (!HIWORD(str))
168         return SetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str), handle );
169     strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
170     ret = SetPropA( hwnd, strA, handle );
171     HeapFree( GetProcessHeap(), 0, strA );
172     return ret;
173 }
174
175
176 /***********************************************************************
177  *           RemoveProp16   (USER.24)
178  */
179 HANDLE16 WINAPI RemoveProp16( HWND16 hwnd, LPCSTR str )
180 {
181     return (HANDLE16)RemovePropA( hwnd, str );
182 }
183
184
185 /***********************************************************************
186  *           RemovePropA   (USER32.442)
187  */
188 HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str )
189 {
190     ATOM atom;
191     HANDLE handle;
192     PROPERTY **pprop, *prop;
193     WND *pWnd = WIN_FindWndPtr( hwnd );
194
195     if (HIWORD(str))
196       TRACE("%04x '%s'\n", hwnd, str );
197     else
198       TRACE("%04x #%04x\n", hwnd, LOWORD(str));
199
200
201     if (!pWnd) return (HANDLE)0;
202     if (HIWORD(str))
203     {
204         atom = GlobalFindAtomA( str );
205         for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
206         {
207             if (HIWORD((*pprop)->string))
208             {
209                 if (!lstrcmpiA( (*pprop)->string, str )) break;
210             }
211             else if (LOWORD((*pprop)->string) == atom) break;
212         }
213     }
214     else  /* atom */
215     {
216         atom = LOWORD(str);
217         for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
218         {
219             if (HIWORD((*pprop)->string))
220             {
221                 if (GlobalFindAtomA( (*pprop)->string ) == atom) break;
222             }
223             else if (LOWORD((*pprop)->string) == atom) break;
224         }
225     }
226     WIN_ReleaseWndPtr(pWnd);
227     if (!*pprop) return 0;
228     prop   = *pprop;
229     handle = prop->handle;
230     *pprop = prop->next;
231     SEGPTR_FREE(prop->string);
232     HeapFree( SystemHeap, 0, prop );
233     return handle;
234 }
235
236
237 /***********************************************************************
238  *           RemovePropW   (USER32.443)
239  */
240 HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
241 {
242     LPSTR strA;
243     HANDLE ret;
244
245     if (!HIWORD(str))
246         return RemovePropA( hwnd, (LPCSTR)(UINT)LOWORD(str) );
247     strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
248     ret = RemovePropA( hwnd, strA );
249     HeapFree( GetProcessHeap(), 0, strA );
250     return ret;
251 }
252
253
254 /***********************************************************************
255  *           PROPERTY_RemoveWindowProps
256  *
257  * Remove all properties of a window.
258  */
259 void PROPERTY_RemoveWindowProps( WND *pWnd )
260 {
261     PROPERTY *prop, *next;
262
263     for (prop = pWnd->pProp; (prop); prop = next)
264     {
265         next = prop->next;
266         SEGPTR_FREE( prop->string );
267         HeapFree( SystemHeap, 0, prop );
268     }
269     pWnd->pProp = NULL;
270 }
271
272
273 /***********************************************************************
274  *           EnumProps16   (USER.27)
275  */
276 INT16 WINAPI EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
277 {
278     PROPERTY *prop, *next;
279     WND *pWnd;
280     INT16 ret = -1;
281
282     TRACE("%04x %08x\n", hwnd, (UINT)func );
283     if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
284     for (prop = pWnd->pProp; (prop); prop = next)
285     {
286         /* Already get the next in case the callback */
287         /* function removes the current property.    */
288         next = prop->next;
289
290         TRACE("  Callback: handle=%08x str='%s'\n",
291                       prop->handle, prop->string );
292         ret = func( hwnd, SEGPTR_GET(prop->string), prop->handle );
293         if (!ret) break;
294     }
295     WIN_ReleaseWndPtr(pWnd);
296     return ret;
297 }
298
299
300 /***********************************************************************
301  *           EnumPropsA   (USER32.186)
302  */
303 INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func )
304 {
305     return EnumPropsExA( hwnd, (PROPENUMPROCEXA)func, 0 );
306 }
307
308
309 /***********************************************************************
310  *           EnumPropsW   (USER32.189)
311  */
312 INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func )
313 {
314     return EnumPropsExW( hwnd, (PROPENUMPROCEXW)func, 0 );
315 }
316
317
318 /***********************************************************************
319  *           EnumPropsExA   (USER32.187)
320  */
321 INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
322 {
323     PROPERTY *prop, *next;
324     WND *pWnd;
325     INT ret = -1;
326
327     TRACE("%04x %08x %08lx\n",
328                   hwnd, (UINT)func, lParam );
329     if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
330     for (prop = pWnd->pProp; (prop); prop = next)
331     {
332         /* Already get the next in case the callback */
333         /* function removes the current property.    */
334         next = prop->next;
335
336         TRACE("  Callback: handle=%08x str='%s'\n",
337                       prop->handle, prop->string );
338         ret = func( hwnd, prop->string, prop->handle, lParam );
339         if (!ret) break;
340     }
341     WIN_ReleaseWndPtr(pWnd);
342     return ret;
343 }
344
345
346 /***********************************************************************
347  *           EnumPropsExW   (USER32.188)
348  */
349 INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
350 {
351     PROPERTY *prop, *next;
352     WND *pWnd;
353     INT ret = -1;
354
355     TRACE("%04x %08x %08lx\n",
356                   hwnd, (UINT)func, lParam );
357     if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
358     for (prop = pWnd->pProp; (prop); prop = next)
359     {
360         /* Already get the next in case the callback */
361         /* function removes the current property.    */
362         next = prop->next;
363
364         TRACE("  Callback: handle=%08x str='%s'\n",
365                       prop->handle, prop->string );
366         if (HIWORD(prop->string))
367         {
368             LPWSTR str = HEAP_strdupAtoW( GetProcessHeap(), 0, prop->string );
369             ret = func( hwnd, str, prop->handle, lParam );
370             HeapFree( GetProcessHeap(), 0, str );
371         }
372         else
373             ret = func( hwnd, (LPCWSTR)(UINT)LOWORD( prop->string ),
374                         prop->handle, lParam );
375         if (!ret) break;
376     }
377     WIN_ReleaseWndPtr(pWnd);
378     return ret;
379 }