Fixed a couple of bugs in _except_handler3.
[wine/multimedia.git] / windows / property.c
blob7157d401b9010d12a29afbe6424f57cc2992f7cb
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 * GetPropA (USER32.@)
73 HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
75 PROPERTY *prop = PROP_FindProp( hwnd, str );
77 if (HIWORD(str))
78 TRACE("(%08x,'%s'): returning %08x\n",
79 hwnd, str, prop ? prop->handle : 0 );
80 else
81 TRACE("(%08x,#%04x): returning %08x\n",
82 hwnd, LOWORD(str), prop ? prop->handle : 0 );
84 return prop ? prop->handle : 0;
88 /***********************************************************************
89 * GetPropW (USER32.@)
91 HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
93 LPSTR strA;
94 HANDLE ret;
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 );
100 return ret;
104 /***********************************************************************
105 * SetPropA (USER32.@)
107 BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
109 PROPERTY *prop;
111 if (HIWORD(str))
112 TRACE("%04x '%s' %08x\n", hwnd, str, handle );
113 else
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);
125 return FALSE;
127 if (!(prop->string = SEGPTR_STRDUP(str)))
129 HeapFree( GetProcessHeap(), 0, prop );
130 WIN_ReleaseWndPtr(pWnd);
131 return FALSE;
134 prop->next = pWnd->pProp;
135 pWnd->pProp = prop;
136 WIN_ReleaseWndPtr(pWnd);
138 prop->handle = handle;
139 return TRUE;
143 /***********************************************************************
144 * SetPropW (USER32.@)
146 BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
148 BOOL ret;
149 LPSTR strA;
151 if (!HIWORD(str))
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 );
156 return ret;
160 /***********************************************************************
161 * RemovePropA (USER32.@)
163 HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str )
165 ATOM atom;
166 HANDLE handle;
167 PROPERTY **pprop, *prop;
168 WND *pWnd = WIN_FindWndPtr( hwnd );
170 if (HIWORD(str))
171 TRACE("%04x '%s'\n", hwnd, str );
172 else
173 TRACE("%04x #%04x\n", hwnd, LOWORD(str));
176 if (!pWnd) return (HANDLE)0;
177 if (HIWORD(str))
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;
189 else /* atom */
191 atom = LOWORD(str);
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;
203 prop = *pprop;
204 handle = prop->handle;
205 *pprop = prop->next;
206 SEGPTR_FREE(prop->string);
207 HeapFree( GetProcessHeap(), 0, prop );
208 return handle;
212 /***********************************************************************
213 * RemovePropW (USER32.@)
215 HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
217 LPSTR strA;
218 HANDLE ret;
220 if (!HIWORD(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 );
225 return ret;
229 /***********************************************************************
230 * PROPERTY_RemoveWindowProps
232 * Remove all properties of a window.
234 void PROPERTY_RemoveWindowProps( WND *pWnd )
236 PROPERTY *prop, *next;
238 for (prop = pWnd->pProp; (prop); prop = next)
240 next = prop->next;
241 SEGPTR_FREE( prop->string );
242 HeapFree( GetProcessHeap(), 0, prop );
244 pWnd->pProp = NULL;
248 /***********************************************************************
249 * EnumProps (USER.27)
251 INT16 WINAPI EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
253 PROPERTY *prop, *next;
254 WND *pWnd;
255 INT16 ret = -1;
257 TRACE("%04x %08x\n", hwnd, (UINT)func );
258 if (!(pWnd = WIN_FindWndPtr16( hwnd ))) return -1;
259 for (prop = pWnd->pProp; (prop); prop = next)
261 /* Already get the next in case the callback */
262 /* function removes the current property. */
263 next = prop->next;
265 /* SDK docu seems to suggest that EnumProps16 does not retrieve
266 * the string in case of an atom handle, in contrast to Win32 */
268 TRACE(" Callback: handle=%08x str=%s\n",
269 prop->handle, debugstr_a(prop->string) );
270 ret = func( hwnd, SEGPTR_GET(prop->string), prop->handle );
271 if (!ret) break;
273 WIN_ReleaseWndPtr(pWnd);
274 return ret;
278 /* relay to call the EnumProps callback function from EnumPropsEx */
279 static BOOL CALLBACK EnumPropsA_relay( HWND hwnd, LPCSTR str, HANDLE handle, ULONG_PTR lparam )
281 PROPENUMPROCA func = (PROPENUMPROCA)lparam;
282 return func( hwnd, str, handle );
286 /***********************************************************************
287 * EnumPropsA (USER32.@)
289 INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func )
291 return EnumPropsExA( hwnd, EnumPropsA_relay, (LPARAM)func );
295 /***********************************************************************
296 * EnumPropsExA (USER32.@)
298 INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
300 PROPERTY *prop, *next;
301 WND *pWnd;
302 INT ret = -1;
303 char atomStr[MAX_ATOM_LEN+1];
304 char *pStr;
306 TRACE("%04x %p %08lx\n", hwnd, func, lParam);
307 if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
308 for (prop = pWnd->pProp; (prop); prop = next)
310 /* Already get the next in case the callback */
311 /* function removes the current property. */
312 next = prop->next;
314 if (!HIWORD(prop->string))
315 { /* get "real" string the atom points to.
316 * This seems to be done for Win32 only */
317 if (!(GlobalGetAtomNameA((ATOM)LOWORD(prop->string), atomStr, MAX_ATOM_LEN+1)))
319 ERR("huh ? Atom %04x not an atom ??\n", LOWORD(prop->string));
320 atomStr[0] = '\0';
322 pStr = atomStr;
324 else
325 pStr = prop->string;
327 TRACE(" Callback: handle=%08x str='%s'\n",
328 prop->handle, prop->string );
330 ret = func( hwnd, pStr, prop->handle, lParam );
331 if (!ret) break;
333 WIN_ReleaseWndPtr(pWnd);
334 return ret;
338 /* relay to call the EnumProps callback function from EnumPropsEx */
339 static BOOL CALLBACK EnumPropsW_relay( HWND hwnd, LPCWSTR str, HANDLE handle, ULONG_PTR lparam )
341 PROPENUMPROCW func = (PROPENUMPROCW)lparam;
342 return func( hwnd, str, handle );
345 /***********************************************************************
346 * EnumPropsW (USER32.@)
348 INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func )
350 return EnumPropsExW( hwnd, EnumPropsW_relay, (LPARAM)func );
353 /***********************************************************************
354 * EnumPropsExW (USER32.@)
356 INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
358 PROPERTY *prop, *next;
359 WND *pWnd;
360 INT ret = -1;
361 char atomStr[MAX_ATOM_LEN+1];
362 char *pStr;
363 LPWSTR strW;
365 TRACE("%04x %p %08lx\n", hwnd, func, lParam);
366 if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
367 for (prop = pWnd->pProp; (prop); prop = next)
369 /* Already get the next in case the callback */
370 /* function removes the current property. */
371 next = prop->next;
373 if (!HIWORD(prop->string))
374 { /* get "real" string the atom points to.
375 * This seems to be done for Win32 only */
376 if (!(GlobalGetAtomNameA((ATOM)LOWORD(prop->string), atomStr, MAX_ATOM_LEN+1)))
378 ERR("huh ? Atom %04x not an atom ??\n",
379 (ATOM)LOWORD(prop->string));
380 atomStr[0] = '\0';
382 pStr = atomStr;
384 else
385 pStr = prop->string;
387 TRACE(" Callback: handle=%08x str='%s'\n",
388 prop->handle, prop->string );
390 strW = HEAP_strdupAtoW( GetProcessHeap(), 0, pStr );
392 ret = func( hwnd, strW, prop->handle, lParam );
393 HeapFree( GetProcessHeap(), 0, strW );
394 if (!ret) break;
396 WIN_ReleaseWndPtr(pWnd);
397 return ret;