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