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 HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
75 PROPERTY *prop = PROP_FindProp( hwnd, str );
78 TRACE("(%08x,'%s'): returning %08x\n",
79 hwnd, str, prop ? prop->handle : 0 );
81 TRACE("(%08x,#%04x): returning %08x\n",
82 hwnd, LOWORD(str), prop ? prop->handle : 0 );
84 return prop ? prop->handle : 0;
88 /***********************************************************************
91 HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
96 if (!HIWORD(str)) return GetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str) );
97 strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
98 ret = GetPropA( hwnd, strA );
99 HeapFree( GetProcessHeap(), 0, strA );
104 /***********************************************************************
105 * SetPropA (USER32.@)
107 BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
112 TRACE("%04x '%s' %08x\n", hwnd, str, handle );
114 TRACE("%04x #%04x %08x\n",
115 hwnd, LOWORD(str), handle );
117 if (!(prop = PROP_FindProp( hwnd, str )))
119 /* We need to create it */
120 WND *pWnd = WIN_FindWndPtr( hwnd );
121 if (!pWnd) return FALSE;
122 if (!(prop = HeapAlloc( GetProcessHeap(), 0, sizeof(*prop) )))
124 WIN_ReleaseWndPtr(pWnd);
127 if (!(prop->string = SEGPTR_STRDUP(str)))
129 HeapFree( GetProcessHeap(), 0, prop );
130 WIN_ReleaseWndPtr(pWnd);
134 prop->next = pWnd->pProp;
136 WIN_ReleaseWndPtr(pWnd);
138 prop->handle = handle;
143 /***********************************************************************
144 * SetPropW (USER32.@)
146 BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
152 return SetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str), handle );
153 strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
154 ret = SetPropA( hwnd, strA, handle );
155 HeapFree( GetProcessHeap(), 0, strA );
160 /***********************************************************************
161 * RemovePropA (USER32.@)
163 HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str )
167 PROPERTY **pprop, *prop;
168 WND *pWnd = WIN_FindWndPtr( hwnd );
171 TRACE("%04x '%s'\n", hwnd, str );
173 TRACE("%04x #%04x\n", hwnd, LOWORD(str));
176 if (!pWnd) return (HANDLE)0;
179 atom = GlobalFindAtomA( str );
180 for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
182 if (HIWORD((*pprop)->string))
184 if (!lstrcmpiA( (*pprop)->string, str )) break;
186 else if (LOWORD((*pprop)->string) == atom) break;
192 for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
194 if (HIWORD((*pprop)->string))
196 if (GlobalFindAtomA( (*pprop)->string ) == atom) break;
198 else if (LOWORD((*pprop)->string) == atom) break;
201 WIN_ReleaseWndPtr(pWnd);
202 if (!*pprop) return 0;
204 handle = prop->handle;
206 SEGPTR_FREE(prop->string);
207 HeapFree( GetProcessHeap(), 0, prop );
212 /***********************************************************************
213 * RemovePropW (USER32.@)
215 HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
221 return RemovePropA( hwnd, (LPCSTR)(UINT)LOWORD(str) );
222 strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
223 ret = RemovePropA( hwnd, strA );
224 HeapFree( GetProcessHeap(), 0, strA );
229 /***********************************************************************
230 * PROPERTY_RemoveWindowProps
232 * Remove all properties of a window.
234 void PROPERTY_RemoveWindowProps( HWND hwnd )
236 PROPERTY *prop, *next;
237 WND *pWnd = WIN_FindWndPtr( hwnd );
240 for (prop = pWnd->pProp; (prop); prop = next)
243 SEGPTR_FREE( prop->string );
244 HeapFree( GetProcessHeap(), 0, prop );
247 WIN_ReleaseWndPtr( pWnd );
251 /***********************************************************************
252 * EnumProps (USER.27)
254 INT16 WINAPI EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
256 PROPERTY *prop, *next;
260 TRACE("%04x %08x\n", hwnd, (UINT)func );
261 if (!(pWnd = WIN_FindWndPtr16( hwnd ))) return -1;
262 for (prop = pWnd->pProp; (prop); prop = next)
264 /* Already get the next in case the callback */
265 /* function removes the current property. */
268 /* SDK docu seems to suggest that EnumProps16 does not retrieve
269 * the string in case of an atom handle, in contrast to Win32 */
271 TRACE(" Callback: handle=%08x str=%s\n",
272 prop->handle, debugstr_a(prop->string) );
273 ret = func( hwnd, SEGPTR_GET(prop->string), prop->handle );
276 WIN_ReleaseWndPtr(pWnd);
281 /* relay to call the EnumProps callback function from EnumPropsEx */
282 static BOOL CALLBACK EnumPropsA_relay( HWND hwnd, LPCSTR str, HANDLE handle, ULONG_PTR lparam )
284 PROPENUMPROCA func = (PROPENUMPROCA)lparam;
285 return func( hwnd, str, handle );
289 /***********************************************************************
290 * EnumPropsA (USER32.@)
292 INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func )
294 return EnumPropsExA( hwnd, EnumPropsA_relay, (LPARAM)func );
298 /***********************************************************************
299 * EnumPropsExA (USER32.@)
301 INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
303 PROPERTY *prop, *next;
306 char atomStr[MAX_ATOM_LEN+1];
309 TRACE("%04x %p %08lx\n", hwnd, func, lParam);
310 if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
311 for (prop = pWnd->pProp; (prop); prop = next)
313 /* Already get the next in case the callback */
314 /* function removes the current property. */
317 if (!HIWORD(prop->string))
318 { /* get "real" string the atom points to.
319 * This seems to be done for Win32 only */
320 if (!(GlobalGetAtomNameA((ATOM)LOWORD(prop->string), atomStr, MAX_ATOM_LEN+1)))
322 ERR("huh ? Atom %04x not an atom ??\n", LOWORD(prop->string));
330 TRACE(" Callback: handle=%08x str='%s'\n",
331 prop->handle, prop->string );
333 ret = func( hwnd, pStr, prop->handle, lParam );
336 WIN_ReleaseWndPtr(pWnd);
341 /* relay to call the EnumProps callback function from EnumPropsEx */
342 static BOOL CALLBACK EnumPropsW_relay( HWND hwnd, LPCWSTR str, HANDLE handle, ULONG_PTR lparam )
344 PROPENUMPROCW func = (PROPENUMPROCW)lparam;
345 return func( hwnd, str, handle );
348 /***********************************************************************
349 * EnumPropsW (USER32.@)
351 INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func )
353 return EnumPropsExW( hwnd, EnumPropsW_relay, (LPARAM)func );
356 /***********************************************************************
357 * EnumPropsExW (USER32.@)
359 INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
361 PROPERTY *prop, *next;
364 char atomStr[MAX_ATOM_LEN+1];
368 TRACE("%04x %p %08lx\n", hwnd, func, lParam);
369 if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
370 for (prop = pWnd->pProp; (prop); prop = next)
372 /* Already get the next in case the callback */
373 /* function removes the current property. */
376 if (!HIWORD(prop->string))
377 { /* get "real" string the atom points to.
378 * This seems to be done for Win32 only */
379 if (!(GlobalGetAtomNameA((ATOM)LOWORD(prop->string), atomStr, MAX_ATOM_LEN+1)))
381 ERR("huh ? Atom %04x not an atom ??\n",
382 (ATOM)LOWORD(prop->string));
390 TRACE(" Callback: handle=%08x str='%s'\n",
391 prop->handle, prop->string );
393 strW = HEAP_strdupAtoW( GetProcessHeap(), 0, pStr );
395 ret = func( hwnd, strW, prop->handle, lParam );
396 HeapFree( GetProcessHeap(), 0, strW );
399 WIN_ReleaseWndPtr(pWnd);