Add SHGetSpecialFolderPathW to spec file.
[wine.git] / windows / property.c
blob4515ca9f71743c3fcc341daaf48221e3e782193f
1 /*
2 * Window properties
4 * Copyright 1995, 1996 Alexandre Julliard
5 */
7 #include <string.h>
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"
16 DEFAULT_DEBUG_CHANNEL(prop);
19 typedef struct tagPROPERTY
21 struct tagPROPERTY *next; /* Next property in window list */
22 HANDLE handle; /* User's data */
23 LPSTR string; /* Property string (or atom) */
24 } PROPERTY;
27 #define MAX_ATOM_LEN 255
29 /***********************************************************************
30 * PROP_FindProp
32 static PROPERTY *PROP_FindProp( HWND hwnd, LPCSTR str )
34 ATOM atom;
35 PROPERTY *prop;
36 WND *pWnd = WIN_FindWndPtr( hwnd );
38 if (!pWnd) return NULL;
39 if (HIWORD(str))
41 atom = GlobalFindAtomA( str );
42 for (prop = pWnd->pProp; prop; prop = prop->next)
44 if (HIWORD(prop->string))
46 if (!lstrcmpiA( prop->string, str )) goto END;
48 else if (LOWORD(prop->string) == atom) goto END;
51 else /* atom */
53 atom = LOWORD(str);
54 for (prop = pWnd->pProp; (prop); prop = prop->next)
56 if (HIWORD(prop->string))
58 if (GlobalFindAtomA( prop->string ) == atom) goto END;
60 else if (LOWORD(prop->string) == atom) goto END;
63 prop = NULL;
64 END:
65 WIN_ReleaseWndPtr(pWnd);
66 return prop;
70 /***********************************************************************
71 * GetProp (USER.25)
73 HANDLE16 WINAPI GetProp16( HWND16 hwnd, LPCSTR str )
75 return (HANDLE16)GetPropA( hwnd, str );
79 /***********************************************************************
80 * GetPropA (USER32.@)
82 HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
84 PROPERTY *prop = PROP_FindProp( hwnd, str );
86 if (HIWORD(str))
87 TRACE("(%08x,'%s'): returning %08x\n",
88 hwnd, str, prop ? prop->handle : 0 );
89 else
90 TRACE("(%08x,#%04x): returning %08x\n",
91 hwnd, LOWORD(str), prop ? prop->handle : 0 );
93 return prop ? prop->handle : 0;
97 /***********************************************************************
98 * GetPropW (USER32.@)
100 HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
102 LPSTR strA;
103 HANDLE ret;
105 if (!HIWORD(str)) return GetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str) );
106 strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
107 ret = GetPropA( hwnd, strA );
108 HeapFree( GetProcessHeap(), 0, strA );
109 return ret;
113 /***********************************************************************
114 * SetProp (USER.26)
116 BOOL16 WINAPI SetProp16( HWND16 hwnd, LPCSTR str, HANDLE16 handle )
118 return (BOOL16)SetPropA( hwnd, str, handle );
122 /***********************************************************************
123 * SetPropA (USER32.@)
125 BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
127 PROPERTY *prop;
129 if (HIWORD(str))
130 TRACE("%04x '%s' %08x\n", hwnd, str, handle );
131 else
132 TRACE("%04x #%04x %08x\n",
133 hwnd, LOWORD(str), handle );
135 if (!(prop = PROP_FindProp( hwnd, str )))
137 /* We need to create it */
138 WND *pWnd = WIN_FindWndPtr( hwnd );
139 if (!pWnd) return FALSE;
140 if (!(prop = HeapAlloc( GetProcessHeap(), 0, sizeof(*prop) )))
142 WIN_ReleaseWndPtr(pWnd);
143 return FALSE;
145 if (!(prop->string = SEGPTR_STRDUP(str)))
147 HeapFree( GetProcessHeap(), 0, prop );
148 WIN_ReleaseWndPtr(pWnd);
149 return FALSE;
152 prop->next = pWnd->pProp;
153 pWnd->pProp = prop;
154 WIN_ReleaseWndPtr(pWnd);
156 prop->handle = handle;
157 return TRUE;
161 /***********************************************************************
162 * SetPropW (USER32.@)
164 BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
166 BOOL ret;
167 LPSTR strA;
169 if (!HIWORD(str))
170 return SetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str), handle );
171 strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
172 ret = SetPropA( hwnd, strA, handle );
173 HeapFree( GetProcessHeap(), 0, strA );
174 return ret;
178 /***********************************************************************
179 * RemoveProp (USER.24)
181 HANDLE16 WINAPI RemoveProp16( HWND16 hwnd, LPCSTR str )
183 return (HANDLE16)RemovePropA( hwnd, str );
187 /***********************************************************************
188 * RemovePropA (USER32.@)
190 HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str )
192 ATOM atom;
193 HANDLE handle;
194 PROPERTY **pprop, *prop;
195 WND *pWnd = WIN_FindWndPtr( hwnd );
197 if (HIWORD(str))
198 TRACE("%04x '%s'\n", hwnd, str );
199 else
200 TRACE("%04x #%04x\n", hwnd, LOWORD(str));
203 if (!pWnd) return (HANDLE)0;
204 if (HIWORD(str))
206 atom = GlobalFindAtomA( str );
207 for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
209 if (HIWORD((*pprop)->string))
211 if (!lstrcmpiA( (*pprop)->string, str )) break;
213 else if (LOWORD((*pprop)->string) == atom) break;
216 else /* atom */
218 atom = LOWORD(str);
219 for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
221 if (HIWORD((*pprop)->string))
223 if (GlobalFindAtomA( (*pprop)->string ) == atom) break;
225 else if (LOWORD((*pprop)->string) == atom) break;
228 WIN_ReleaseWndPtr(pWnd);
229 if (!*pprop) return 0;
230 prop = *pprop;
231 handle = prop->handle;
232 *pprop = prop->next;
233 SEGPTR_FREE(prop->string);
234 HeapFree( GetProcessHeap(), 0, prop );
235 return handle;
239 /***********************************************************************
240 * RemovePropW (USER32.@)
242 HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
244 LPSTR strA;
245 HANDLE ret;
247 if (!HIWORD(str))
248 return RemovePropA( hwnd, (LPCSTR)(UINT)LOWORD(str) );
249 strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
250 ret = RemovePropA( hwnd, strA );
251 HeapFree( GetProcessHeap(), 0, strA );
252 return ret;
256 /***********************************************************************
257 * PROPERTY_RemoveWindowProps
259 * Remove all properties of a window.
261 void PROPERTY_RemoveWindowProps( WND *pWnd )
263 PROPERTY *prop, *next;
265 for (prop = pWnd->pProp; (prop); prop = next)
267 next = prop->next;
268 SEGPTR_FREE( prop->string );
269 HeapFree( GetProcessHeap(), 0, prop );
271 pWnd->pProp = NULL;
275 /***********************************************************************
276 * EnumProps (USER.27)
278 INT16 WINAPI EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
280 PROPERTY *prop, *next;
281 WND *pWnd;
282 INT16 ret = -1;
284 TRACE("%04x %08x\n", hwnd, (UINT)func );
285 if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
286 for (prop = pWnd->pProp; (prop); prop = next)
288 /* Already get the next in case the callback */
289 /* function removes the current property. */
290 next = prop->next;
292 /* SDK docu seems to suggest that EnumProps16 does not retrieve
293 * the string in case of an atom handle, in contrast to Win32 */
295 TRACE(" Callback: handle=%08x str=%s\n",
296 prop->handle, debugstr_a(prop->string) );
297 ret = func( hwnd, SEGPTR_GET(prop->string), prop->handle );
298 if (!ret) break;
300 WIN_ReleaseWndPtr(pWnd);
301 return ret;
305 /* relay to call the EnumProps callback function from EnumPropsEx */
306 static BOOL CALLBACK EnumPropsA_relay( HWND hwnd, LPCSTR str, HANDLE handle, ULONG_PTR lparam )
308 PROPENUMPROCA func = (PROPENUMPROCA)lparam;
309 return func( hwnd, str, handle );
313 /***********************************************************************
314 * EnumPropsA (USER32.@)
316 INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func )
318 return EnumPropsExA( hwnd, EnumPropsA_relay, (LPARAM)func );
322 /***********************************************************************
323 * EnumPropsExA (USER32.@)
325 INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
327 PROPERTY *prop, *next;
328 WND *pWnd;
329 INT ret = -1;
330 char atomStr[MAX_ATOM_LEN+1];
331 char *pStr;
333 TRACE("%04x %p %08lx\n", hwnd, func, lParam);
334 if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
335 for (prop = pWnd->pProp; (prop); prop = next)
337 /* Already get the next in case the callback */
338 /* function removes the current property. */
339 next = prop->next;
341 if (!HIWORD(prop->string))
342 { /* get "real" string the atom points to.
343 * This seems to be done for Win32 only */
344 if (!(GlobalGetAtomNameA((ATOM)LOWORD(prop->string), atomStr, MAX_ATOM_LEN+1)))
346 ERR("huh ? Atom %04x not an atom ??\n", LOWORD(prop->string));
347 atomStr[0] = '\0';
349 pStr = atomStr;
351 else
352 pStr = prop->string;
354 TRACE(" Callback: handle=%08x str='%s'\n",
355 prop->handle, prop->string );
357 ret = func( hwnd, pStr, prop->handle, lParam );
358 if (!ret) break;
360 WIN_ReleaseWndPtr(pWnd);
361 return ret;
365 /* relay to call the EnumProps callback function from EnumPropsEx */
366 static BOOL CALLBACK EnumPropsW_relay( HWND hwnd, LPCWSTR str, HANDLE handle, ULONG_PTR lparam )
368 PROPENUMPROCW func = (PROPENUMPROCW)lparam;
369 return func( hwnd, str, handle );
372 /***********************************************************************
373 * EnumPropsW (USER32.@)
375 INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func )
377 return EnumPropsExW( hwnd, EnumPropsW_relay, (LPARAM)func );
380 /***********************************************************************
381 * EnumPropsExW (USER32.@)
383 INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
385 PROPERTY *prop, *next;
386 WND *pWnd;
387 INT ret = -1;
388 char atomStr[MAX_ATOM_LEN+1];
389 char *pStr;
390 LPWSTR strW;
392 TRACE("%04x %p %08lx\n", hwnd, func, lParam);
393 if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
394 for (prop = pWnd->pProp; (prop); prop = next)
396 /* Already get the next in case the callback */
397 /* function removes the current property. */
398 next = prop->next;
400 if (!HIWORD(prop->string))
401 { /* get "real" string the atom points to.
402 * This seems to be done for Win32 only */
403 if (!(GlobalGetAtomNameA((ATOM)LOWORD(prop->string), atomStr, MAX_ATOM_LEN+1)))
405 ERR("huh ? Atom %04x not an atom ??\n",
406 (ATOM)LOWORD(prop->string));
407 atomStr[0] = '\0';
409 pStr = atomStr;
411 else
412 pStr = prop->string;
414 TRACE(" Callback: handle=%08x str='%s'\n",
415 prop->handle, prop->string );
417 strW = HEAP_strdupAtoW( GetProcessHeap(), 0, pStr );
419 ret = func( hwnd, strW, prop->handle, lParam );
420 HeapFree( GetProcessHeap(), 0, strW );
421 if (!ret) break;
423 WIN_ReleaseWndPtr(pWnd);
424 return ret;