/* * Window properties * * Copyright 1995, 1996 Alexandre Julliard */ #include #include "win.h" #include "heap.h" #include "debug.h" typedef struct tagPROPERTY { struct tagPROPERTY *next; /* Next property in window list */ HANDLE handle; /* User's data */ LPSTR string; /* Property string (or atom) */ } PROPERTY; /*********************************************************************** * PROP_FindProp */ static PROPERTY *PROP_FindProp( HWND hwnd, LPCSTR str ) { ATOM atom; PROPERTY *prop; WND *pWnd = WIN_FindWndPtr( hwnd ); if (!pWnd) return NULL; if (HIWORD(str)) { atom = GlobalFindAtomA( str ); for (prop = pWnd->pProp; prop; prop = prop->next) { if (HIWORD(prop->string)) { if (!lstrcmpiA( prop->string, str )) goto END; } else if (LOWORD(prop->string) == atom) goto END; } } else /* atom */ { atom = LOWORD(str); for (prop = pWnd->pProp; (prop); prop = prop->next) { if (HIWORD(prop->string)) { if (GlobalFindAtomA( prop->string ) == atom) goto END; } else if (LOWORD(prop->string) == atom) goto END; } } prop = NULL; END: WIN_ReleaseWndPtr(pWnd); return prop; } /*********************************************************************** * GetProp16 (USER.25) */ HANDLE16 WINAPI GetProp16( HWND16 hwnd, LPCSTR str ) { return (HANDLE16)GetPropA( hwnd, str ); } /*********************************************************************** * GetProp32A (USER32.281) */ HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str ) { PROPERTY *prop = PROP_FindProp( hwnd, str ); if (HIWORD(str)) TRACE(prop, "(%08x,'%s'): returning %08x\n", hwnd, str, prop ? prop->handle : 0 ); else TRACE(prop, "(%08x,#%04x): returning %08x\n", hwnd, LOWORD(str), prop ? prop->handle : 0 ); return prop ? prop->handle : 0; } /*********************************************************************** * GetProp32W (USER32.282) */ HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str ) { LPSTR strA; HANDLE ret; if (!HIWORD(str)) return GetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str) ); strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str ); ret = GetPropA( hwnd, strA ); HeapFree( GetProcessHeap(), 0, strA ); return ret; } /*********************************************************************** * SetProp16 (USER.26) */ BOOL16 WINAPI SetProp16( HWND16 hwnd, LPCSTR str, HANDLE16 handle ) { return (BOOL16)SetPropA( hwnd, str, handle ); } /*********************************************************************** * SetProp32A (USER32.497) */ BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle ) { PROPERTY *prop; if (HIWORD(str)) TRACE(prop, "%04x '%s' %08x\n", hwnd, str, handle ); else TRACE(prop, "%04x #%04x %08x\n", hwnd, LOWORD(str), handle ); if (!(prop = PROP_FindProp( hwnd, str ))) { /* We need to create it */ WND *pWnd = WIN_FindWndPtr( hwnd ); if (!pWnd) return FALSE; if (!(prop = HeapAlloc( SystemHeap, 0, sizeof(*prop) ))) { WIN_ReleaseWndPtr(pWnd); return FALSE; } if (!(prop->string = SEGPTR_STRDUP(str))) { HeapFree( SystemHeap, 0, prop ); WIN_ReleaseWndPtr(pWnd); return FALSE; } prop->next = pWnd->pProp; pWnd->pProp = prop; WIN_ReleaseWndPtr(pWnd); } prop->handle = handle; return TRUE; } /*********************************************************************** * SetProp32W (USER32.498) */ BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle ) { BOOL ret; LPSTR strA; if (!HIWORD(str)) return SetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str), handle ); strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str ); ret = SetPropA( hwnd, strA, handle ); HeapFree( GetProcessHeap(), 0, strA ); return ret; } /*********************************************************************** * RemoveProp16 (USER.24) */ HANDLE16 WINAPI RemoveProp16( HWND16 hwnd, LPCSTR str ) { return (HANDLE16)RemovePropA( hwnd, str ); } /*********************************************************************** * RemoveProp32A (USER32.442) */ HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str ) { ATOM atom; HANDLE handle; PROPERTY **pprop, *prop; WND *pWnd = WIN_FindWndPtr( hwnd ); if (HIWORD(str)) TRACE(prop, "%04x '%s'\n", hwnd, str ); else TRACE(prop, "%04x #%04x\n", hwnd, LOWORD(str)); if (!pWnd) return (HANDLE)0; if (HIWORD(str)) { atom = GlobalFindAtomA( str ); for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next) { if (HIWORD((*pprop)->string)) { if (!lstrcmpiA( (*pprop)->string, str )) break; } else if (LOWORD((*pprop)->string) == atom) break; } } else /* atom */ { atom = LOWORD(str); for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next) { if (HIWORD((*pprop)->string)) { if (GlobalFindAtomA( (*pprop)->string ) == atom) break; } else if (LOWORD((*pprop)->string) == atom) break; } } WIN_ReleaseWndPtr(pWnd); if (!*pprop) return 0; prop = *pprop; handle = prop->handle; *pprop = prop->next; SEGPTR_FREE(prop->string); HeapFree( SystemHeap, 0, prop ); return handle; } /*********************************************************************** * RemoveProp32W (USER32.443) */ HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str ) { LPSTR strA; HANDLE ret; if (!HIWORD(str)) return RemovePropA( hwnd, (LPCSTR)(UINT)LOWORD(str) ); strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str ); ret = RemovePropA( hwnd, strA ); HeapFree( GetProcessHeap(), 0, strA ); return ret; } /*********************************************************************** * PROPERTY_RemoveWindowProps * * Remove all properties of a window. */ void PROPERTY_RemoveWindowProps( WND *pWnd ) { PROPERTY *prop, *next; for (prop = pWnd->pProp; (prop); prop = next) { next = prop->next; SEGPTR_FREE( prop->string ); HeapFree( SystemHeap, 0, prop ); } pWnd->pProp = NULL; } /*********************************************************************** * EnumProps16 (USER.27) */ INT16 WINAPI EnumProps16( HWND16 hwnd, PROPENUMPROC16 func ) { PROPERTY *prop, *next; WND *pWnd; INT16 ret = -1; TRACE(prop, "%04x %08x\n", hwnd, (UINT)func ); if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1; for (prop = pWnd->pProp; (prop); prop = next) { /* Already get the next in case the callback */ /* function removes the current property. */ next = prop->next; TRACE(prop, " Callback: handle=%08x str='%s'\n", prop->handle, prop->string ); ret = func( hwnd, SEGPTR_GET(prop->string), prop->handle ); if (!ret) break; } WIN_ReleaseWndPtr(pWnd); return ret; } /*********************************************************************** * EnumProps32A (USER32.186) */ INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func ) { return EnumPropsExA( hwnd, (PROPENUMPROCEXA)func, 0 ); } /*********************************************************************** * EnumProps32W (USER32.189) */ INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func ) { return EnumPropsExW( hwnd, (PROPENUMPROCEXW)func, 0 ); } /*********************************************************************** * EnumPropsEx32A (USER32.187) */ INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam) { PROPERTY *prop, *next; WND *pWnd; INT ret = -1; TRACE(prop, "%04x %08x %08lx\n", hwnd, (UINT)func, lParam ); if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1; for (prop = pWnd->pProp; (prop); prop = next) { /* Already get the next in case the callback */ /* function removes the current property. */ next = prop->next; TRACE(prop, " Callback: handle=%08x str='%s'\n", prop->handle, prop->string ); ret = func( hwnd, prop->string, prop->handle, lParam ); if (!ret) break; } WIN_ReleaseWndPtr(pWnd); return ret; } /*********************************************************************** * EnumPropsEx32W (USER32.188) */ INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam) { PROPERTY *prop, *next; WND *pWnd; INT ret = -1; TRACE(prop, "%04x %08x %08lx\n", hwnd, (UINT)func, lParam ); if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1; for (prop = pWnd->pProp; (prop); prop = next) { /* Already get the next in case the callback */ /* function removes the current property. */ next = prop->next; TRACE(prop, " Callback: handle=%08x str='%s'\n", prop->handle, prop->string ); if (HIWORD(prop->string)) { LPWSTR str = HEAP_strdupAtoW( GetProcessHeap(), 0, prop->string ); ret = func( hwnd, str, prop->handle, lParam ); HeapFree( GetProcessHeap(), 0, str ); } else ret = func( hwnd, (LPCWSTR)(UINT)LOWORD( prop->string ), prop->handle, lParam ); if (!ret) break; } WIN_ReleaseWndPtr(pWnd); return ret; }