Yet another major reorganization and a few new features.
[wine/wine64.git] / windows / property.c
blobf75827cb74abddec636ae681f298fe8535bd1ac2
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 /***********************************************************************
28 * PROP_FindProp
30 static PROPERTY *PROP_FindProp( HWND hwnd, LPCSTR str )
32 ATOM atom;
33 PROPERTY *prop;
34 WND *pWnd = WIN_FindWndPtr( hwnd );
36 if (!pWnd) return NULL;
37 if (HIWORD(str))
39 atom = GlobalFindAtomA( str );
40 for (prop = pWnd->pProp; prop; prop = prop->next)
42 if (HIWORD(prop->string))
44 if (!lstrcmpiA( prop->string, str )) goto END;
46 else if (LOWORD(prop->string) == atom) goto END;
49 else /* atom */
51 atom = LOWORD(str);
52 for (prop = pWnd->pProp; (prop); prop = prop->next)
54 if (HIWORD(prop->string))
56 if (GlobalFindAtomA( prop->string ) == atom) goto END;
58 else if (LOWORD(prop->string) == atom) goto END;
61 prop = NULL;
62 END:
63 WIN_ReleaseWndPtr(pWnd);
64 return prop;
68 /***********************************************************************
69 * GetProp (USER.25)
71 HANDLE16 WINAPI GetProp16( HWND16 hwnd, LPCSTR str )
73 return (HANDLE16)GetPropA( hwnd, str );
77 /***********************************************************************
78 * GetPropA (USER32.@)
80 HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
82 PROPERTY *prop = PROP_FindProp( hwnd, str );
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 );
91 return prop ? prop->handle : 0;
95 /***********************************************************************
96 * GetPropW (USER32.@)
98 HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
100 LPSTR strA;
101 HANDLE ret;
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;
111 /***********************************************************************
112 * SetProp (USER.26)
114 BOOL16 WINAPI SetProp16( HWND16 hwnd, LPCSTR str, HANDLE16 handle )
116 return (BOOL16)SetPropA( hwnd, str, handle );
120 /***********************************************************************
121 * SetPropA (USER32.@)
123 BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
125 PROPERTY *prop;
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 );
133 if (!(prop = PROP_FindProp( hwnd, str )))
135 /* We need to create it */
136 WND *pWnd = WIN_FindWndPtr( hwnd );
137 if (!pWnd) return FALSE;
138 if (!(prop = HeapAlloc( GetProcessHeap(), 0, sizeof(*prop) )))
140 WIN_ReleaseWndPtr(pWnd);
141 return FALSE;
143 if (!(prop->string = SEGPTR_STRDUP(str)))
145 HeapFree( GetProcessHeap(), 0, prop );
146 WIN_ReleaseWndPtr(pWnd);
147 return FALSE;
150 prop->next = pWnd->pProp;
151 pWnd->pProp = prop;
152 WIN_ReleaseWndPtr(pWnd);
154 prop->handle = handle;
155 return TRUE;
159 /***********************************************************************
160 * SetPropW (USER32.@)
162 BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
164 BOOL ret;
165 LPSTR strA;
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;
176 /***********************************************************************
177 * RemoveProp (USER.24)
179 HANDLE16 WINAPI RemoveProp16( HWND16 hwnd, LPCSTR str )
181 return (HANDLE16)RemovePropA( hwnd, str );
185 /***********************************************************************
186 * RemovePropA (USER32.@)
188 HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str )
190 ATOM atom;
191 HANDLE handle;
192 PROPERTY **pprop, *prop;
193 WND *pWnd = WIN_FindWndPtr( hwnd );
195 if (HIWORD(str))
196 TRACE("%04x '%s'\n", hwnd, str );
197 else
198 TRACE("%04x #%04x\n", hwnd, LOWORD(str));
201 if (!pWnd) return (HANDLE)0;
202 if (HIWORD(str))
204 atom = GlobalFindAtomA( str );
205 for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
207 if (HIWORD((*pprop)->string))
209 if (!lstrcmpiA( (*pprop)->string, str )) break;
211 else if (LOWORD((*pprop)->string) == atom) break;
214 else /* atom */
216 atom = LOWORD(str);
217 for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
219 if (HIWORD((*pprop)->string))
221 if (GlobalFindAtomA( (*pprop)->string ) == atom) break;
223 else if (LOWORD((*pprop)->string) == atom) break;
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( GetProcessHeap(), 0, prop );
233 return handle;
237 /***********************************************************************
238 * RemovePropW (USER32.@)
240 HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
242 LPSTR strA;
243 HANDLE ret;
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;
254 /***********************************************************************
255 * PROPERTY_RemoveWindowProps
257 * Remove all properties of a window.
259 void PROPERTY_RemoveWindowProps( WND *pWnd )
261 PROPERTY *prop, *next;
263 for (prop = pWnd->pProp; (prop); prop = next)
265 next = prop->next;
266 SEGPTR_FREE( prop->string );
267 HeapFree( GetProcessHeap(), 0, prop );
269 pWnd->pProp = NULL;
273 /***********************************************************************
274 * EnumProps (USER.27)
276 INT16 WINAPI EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
278 PROPERTY *prop, *next;
279 WND *pWnd;
280 INT16 ret = -1;
282 TRACE("%04x %08x\n", hwnd, (UINT)func );
283 if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
284 for (prop = pWnd->pProp; (prop); prop = next)
286 /* Already get the next in case the callback */
287 /* function removes the current property. */
288 next = prop->next;
290 /* SDK docu seems to suggest that EnumProps16 does not retrieve
291 * the string in case of an atom handle, in contrast to Win32 */
293 TRACE(" Callback: handle=%08x str=%s\n",
294 prop->handle, debugstr_a(prop->string) );
295 ret = func( hwnd, SEGPTR_GET(prop->string), prop->handle );
296 if (!ret) break;
298 WIN_ReleaseWndPtr(pWnd);
299 return ret;
303 #define MAX_ATOM_LEN 255
304 static INT PROPS_EnumPropsA( HWND hwnd, PROPENUMPROCA func, LPARAM lParam, BOOL ex )
306 PROPERTY *prop, *next;
307 WND *pWnd;
308 INT ret = -1;
309 char atomStr[MAX_ATOM_LEN+1];
310 char *pStr;
312 TRACE("%04x %08x %08lx%s\n",
313 hwnd, (UINT)func, lParam, ex ? " [Ex]" : "" );
314 if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
315 for (prop = pWnd->pProp; (prop); prop = next)
317 /* Already get the next in case the callback */
318 /* function removes the current property. */
319 next = prop->next;
321 if (!HIWORD(prop->string))
322 { /* get "real" string the atom points to.
323 * This seems to be done for Win32 only */
324 if (!(GlobalGetAtomNameA((ATOM)LOWORD(prop->string), atomStr, MAX_ATOM_LEN+1)))
326 ERR("huh ? Atom %04x not an atom ??\n",
327 (ATOM)LOWORD(prop->string));
328 atomStr[0] = '\0';
330 pStr = atomStr;
332 else
333 pStr = prop->string;
335 TRACE(" Callback: handle=%08x str='%s'\n",
336 prop->handle, prop->string );
338 if (ex) /* EnumPropsEx has an additional lParam !! */
339 ret = func( hwnd, pStr, prop->handle, lParam );
340 else
341 ret = func( hwnd, pStr, prop->handle );
342 if (!ret) break;
344 WIN_ReleaseWndPtr(pWnd);
345 return ret;
349 /***********************************************************************
350 * EnumPropsA (USER32.@)
352 INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func )
354 return PROPS_EnumPropsA(hwnd, func, 0, FALSE);
358 /***********************************************************************
359 * EnumPropsExA (USER32.@)
361 INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
363 return PROPS_EnumPropsA(hwnd, (PROPENUMPROCA)func, lParam, TRUE);
367 static INT PROPS_EnumPropsW( HWND hwnd, PROPENUMPROCW func, LPARAM lParam, BOOL ex )
369 PROPERTY *prop, *next;
370 WND *pWnd;
371 INT ret = -1;
372 char atomStr[MAX_ATOM_LEN+1];
373 char *pStr;
374 LPWSTR strW;
376 TRACE("%04x %08x %08lx%s\n",
377 hwnd, (UINT)func, lParam, ex ? " [Ex]" : "" );
378 if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
379 for (prop = pWnd->pProp; (prop); prop = next)
381 /* Already get the next in case the callback */
382 /* function removes the current property. */
383 next = prop->next;
385 if (!HIWORD(prop->string))
386 { /* get "real" string the atom points to.
387 * This seems to be done for Win32 only */
388 if (!(GlobalGetAtomNameA((ATOM)LOWORD(prop->string), atomStr, MAX_ATOM_LEN+1)))
390 ERR("huh ? Atom %04x not an atom ??\n",
391 (ATOM)LOWORD(prop->string));
392 atomStr[0] = '\0';
394 pStr = atomStr;
396 else
397 pStr = prop->string;
399 TRACE(" Callback: handle=%08x str='%s'\n",
400 prop->handle, prop->string );
402 strW = HEAP_strdupAtoW( GetProcessHeap(), 0, pStr );
404 if (ex) /* EnumPropsEx has an additional lParam !! */
405 ret = func( hwnd, strW, prop->handle, lParam );
406 else
407 ret = func( hwnd, strW, prop->handle );
408 HeapFree( GetProcessHeap(), 0, strW );
409 if (!ret) break;
411 WIN_ReleaseWndPtr(pWnd);
412 return ret;
416 /***********************************************************************
417 * EnumPropsW (USER32.@)
419 INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func )
421 return PROPS_EnumPropsW(hwnd, func, 0, FALSE);
424 /***********************************************************************
425 * EnumPropsExW (USER32.@)
427 INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
429 return PROPS_EnumPropsW(hwnd, (PROPENUMPROCW)func, 0, TRUE);