/* * Window properties * * Copyright 1995, 1996, 2001 Alexandre Julliard */ #include #include "windef.h" #include "wingdi.h" #include "wine/winuser16.h" #include "wine/server.h" #include "heap.h" /* size of buffer needed to store an atom string */ #define ATOM_BUFFER_SIZE 256 /*********************************************************************** * get_properties * * Retrieve the list of properties of a given window. * Returned buffer must be freed by caller. */ static property_data_t *get_properties( HWND hwnd, int *count ) { property_data_t *ret = NULL; SERVER_START_VAR_REQ( get_window_properties, REQUEST_MAX_VAR_SIZE ) { req->window = hwnd; if (!SERVER_CALL()) { size_t size = server_data_size(req); if (size) { property_data_t *data = server_data_ptr(req); if ((ret = HeapAlloc( GetProcessHeap(), 0, size ))) memcpy( ret, data, size ); *count = size / sizeof(*data); } } } SERVER_END_VAR_REQ; return ret; } /*********************************************************************** * EnumPropsA_relay * * relay to call the EnumProps callback function from EnumPropsEx */ static BOOL CALLBACK EnumPropsA_relay( HWND hwnd, LPCSTR str, HANDLE handle, ULONG_PTR lparam ) { PROPENUMPROCA func = (PROPENUMPROCA)lparam; return func( hwnd, str, handle ); } /*********************************************************************** * EnumPropsW_relay * * relay to call the EnumProps callback function from EnumPropsEx */ static BOOL CALLBACK EnumPropsW_relay( HWND hwnd, LPCWSTR str, HANDLE handle, ULONG_PTR lparam ) { PROPENUMPROCW func = (PROPENUMPROCW)lparam; return func( hwnd, str, handle ); } /*********************************************************************** * EnumPropsA (USER32.@) */ INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func ) { return EnumPropsExA( hwnd, EnumPropsA_relay, (LPARAM)func ); } /*********************************************************************** * EnumPropsW (USER32.@) */ INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func ) { return EnumPropsExW( hwnd, EnumPropsW_relay, (LPARAM)func ); } /*********************************************************************** * GetPropA (USER32.@) */ HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str ) { ATOM atom; HANDLE ret = 0; if (!HIWORD(str)) atom = LOWORD(str); else if (!(atom = GlobalFindAtomA( str ))) return 0; SERVER_START_REQ( get_window_property ) { req->window = hwnd; req->atom = atom; if (!SERVER_CALL_ERR()) ret = req->handle; } SERVER_END_REQ; return ret; } /*********************************************************************** * GetPropW (USER32.@) */ HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str ) { ATOM atom; HANDLE ret = 0; if (!HIWORD(str)) atom = LOWORD(str); else if (!(atom = GlobalFindAtomW( str ))) return 0; SERVER_START_REQ( get_window_property ) { req->window = hwnd; req->atom = atom; if (!SERVER_CALL_ERR()) ret = req->handle; } SERVER_END_REQ; return ret; } /*********************************************************************** * SetPropA (USER32.@) */ BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle ) { ATOM atom; BOOL ret; if (!HIWORD(str)) atom = LOWORD(str); else if (!(atom = GlobalAddAtomA( str ))) return FALSE; SERVER_START_REQ( set_window_property ) { req->window = hwnd; req->atom = atom; req->string = (HIWORD(str) != 0); req->handle = handle; ret = !SERVER_CALL_ERR(); } SERVER_END_REQ; if (HIWORD(str)) GlobalDeleteAtom( atom ); return ret; } /*********************************************************************** * SetPropW (USER32.@) */ BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle ) { ATOM atom; BOOL ret; if (!HIWORD(str)) atom = LOWORD(str); else if (!(atom = GlobalAddAtomW( str ))) return FALSE; SERVER_START_REQ( set_window_property ) { req->window = hwnd; req->atom = atom; req->string = (HIWORD(str) != 0); req->handle = handle; ret = !SERVER_CALL_ERR(); } SERVER_END_REQ; if (HIWORD(str)) GlobalDeleteAtom( atom ); return ret; } /*********************************************************************** * RemovePropA (USER32.@) */ HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str ) { ATOM atom; HANDLE ret = 0; if (!HIWORD(str)) return RemovePropW( hwnd, MAKEINTATOMW(LOWORD(str)) ); if ((atom = GlobalAddAtomA( str ))) { ret = RemovePropW( hwnd, MAKEINTATOMW(atom) ); GlobalDeleteAtom( atom ); } return ret; } /*********************************************************************** * RemovePropW (USER32.@) */ HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str ) { ATOM atom; HANDLE ret = 0; if (!HIWORD(str)) atom = LOWORD(str); else if (!(atom = GlobalAddAtomW( str ))) return 0; SERVER_START_REQ( remove_window_property ) { req->window = hwnd; req->atom = atom; if (!SERVER_CALL_ERR()) ret = req->handle; } SERVER_END_REQ; if (HIWORD(str)) GlobalDeleteAtom( atom ); return ret; } /*********************************************************************** * EnumPropsExA (USER32.@) */ INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam) { int ret = -1, i, count; property_data_t *list = get_properties( hwnd, &count ); if (list) { for (i = 0; i < count; i++) { char string[ATOM_BUFFER_SIZE]; if (!GlobalGetAtomNameA( list[i].atom, string, ATOM_BUFFER_SIZE )) continue; if (!(ret = func( hwnd, string, list[i].handle, lParam ))) break; } HeapFree( GetProcessHeap(), 0, list ); } return ret; } /*********************************************************************** * EnumPropsExW (USER32.@) */ INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam) { int ret = -1, i, count; property_data_t *list = get_properties( hwnd, &count ); if (list) { for (i = 0; i < count; i++) { WCHAR string[ATOM_BUFFER_SIZE]; if (!GlobalGetAtomNameW( list[i].atom, string, ATOM_BUFFER_SIZE )) continue; if (!(ret = func( hwnd, string, list[i].handle, lParam ))) break; } HeapFree( GetProcessHeap(), 0, list ); } return ret; } /*********************************************************************** * EnumProps (USER.27) */ INT16 WINAPI EnumProps16( HWND16 hwnd, PROPENUMPROC16 func ) { int ret = -1, i, count; property_data_t *list = get_properties( hwnd, &count ); if (list) { char *string = SEGPTR_ALLOC( ATOM_BUFFER_SIZE ); for (i = 0; i < count; i++) { if (list[i].string) /* it was a string originally */ { if (!GlobalGetAtomNameA( list[i].atom, string, ATOM_BUFFER_SIZE )) continue; ret = func( hwnd, SEGPTR_GET(string), list[i].handle ); } else ret = func( hwnd, list[i].atom, list[i].handle ); if (!ret) break; } SEGPTR_FREE( string ); HeapFree( GetProcessHeap(), 0, list ); } return ret; }