4 * Copyright 1995, 1996 Alexandre Julliard
11 #include "wine/winuser16.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) */
27 #define MAX_ATOM_LEN 255
29 /***********************************************************************
32 static PROPERTY *PROP_FindProp( HWND hwnd, LPCSTR str )
36 WND *pWnd = WIN_FindWndPtr( hwnd );
38 if (!pWnd) return NULL;
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;
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;
65 WIN_ReleaseWndPtr(pWnd);
70 /***********************************************************************
73 HANDLE16 WINAPI GetProp16( HWND16 hwnd, LPCSTR str )
75 return (HANDLE16)GetPropA( hwnd, str );
79 /***********************************************************************
82 HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
84 PROPERTY *prop = PROP_FindProp( hwnd, str );
87 TRACE("(%08x,'%s'): returning %08x\n",
88 hwnd, str, prop ? prop->handle : 0 );
90 TRACE("(%08x,#%04x): returning %08x\n",
91 hwnd, LOWORD(str), prop ? prop->handle : 0 );
93 return prop ? prop->handle : 0;
97 /***********************************************************************
100 HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
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 );
113 /***********************************************************************
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 )
130 TRACE("%04x '%s' %08x\n", hwnd, str, handle );
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);
145 if (!(prop->string = SEGPTR_STRDUP(str)))
147 HeapFree( GetProcessHeap(), 0, prop );
148 WIN_ReleaseWndPtr(pWnd);
152 prop->next = pWnd->pProp;
154 WIN_ReleaseWndPtr(pWnd);
156 prop->handle = handle;
161 /***********************************************************************
162 * SetPropW (USER32.@)
164 BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
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 );
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 )
194 PROPERTY **pprop, *prop;
195 WND *pWnd = WIN_FindWndPtr( hwnd );
198 TRACE("%04x '%s'\n", hwnd, str );
200 TRACE("%04x #%04x\n", hwnd, LOWORD(str));
203 if (!pWnd) return (HANDLE)0;
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;
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;
231 handle = prop->handle;
233 SEGPTR_FREE(prop->string);
234 HeapFree( GetProcessHeap(), 0, prop );
239 /***********************************************************************
240 * RemovePropW (USER32.@)
242 HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR 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 );
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)
268 SEGPTR_FREE( prop->string );
269 HeapFree( GetProcessHeap(), 0, prop );
275 /***********************************************************************
276 * EnumProps (USER.27)
278 INT16 WINAPI EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
280 PROPERTY *prop, *next;
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. */
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 );
300 WIN_ReleaseWndPtr(pWnd);
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;
330 char atomStr[MAX_ATOM_LEN+1];
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. */
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));
354 TRACE(" Callback: handle=%08x str='%s'\n",
355 prop->handle, prop->string );
357 ret = func( hwnd, pStr, prop->handle, lParam );
360 WIN_ReleaseWndPtr(pWnd);
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;
388 char atomStr[MAX_ATOM_LEN+1];
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. */
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));
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 );
423 WIN_ReleaseWndPtr(pWnd);