property.c 7.36 KB
Newer Older
1 2 3 4
/*
 * Window properties
 *
 * Copyright 1995, 1996, 2001 Alexandre Julliard
5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 20
 */

Steven Edwards's avatar
Steven Edwards committed
21 22 23
#include "config.h"
#include "wine/port.h"

24
#include <stdarg.h>
25 26 27
#include <string.h>

#include "windef.h"
28
#include "winbase.h"
29
#include "winuser.h"
30
#include "wine/unicode.h"
31 32 33 34 35 36 37 38 39 40 41 42 43 44
#include "wine/server.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 )
{
45 46
    property_data_t *data;
    int total = 32;
47

48
    while (total)
49
    {
50 51 52 53 54
        int res = 0;
        if (!(data = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*data) ))) break;
        *count = 0;
        SERVER_START_REQ( get_window_properties )
        {
55
            req->window = wine_server_user_handle( hwnd );
56
            wine_server_set_reply( req, data, total * sizeof(*data) );
57 58 59 60
            if (!wine_server_call( req )) res = reply->total;
        }
        SERVER_END_REQ;
        if (res && res <= total)
61
        {
62 63
            *count = res;
            return data;
64
        }
65 66
        HeapFree( GetProcessHeap(), 0, data );
        total = res;  /* restart with larger buffer */
67
    }
68
    return NULL;
69 70 71 72 73 74 75 76
}


/***********************************************************************
 *              EnumPropsA_relay
 *
 * relay to call the EnumProps callback function from EnumPropsEx
 */
77
static BOOL CALLBACK EnumPropsA_relay( HWND hwnd, LPSTR str, HANDLE handle, ULONG_PTR lparam )
78 79 80 81 82 83 84 85 86 87 88
{
    PROPENUMPROCA func = (PROPENUMPROCA)lparam;
    return func( hwnd, str, handle );
}


/***********************************************************************
 *              EnumPropsW_relay
 *
 * relay to call the EnumProps callback function from EnumPropsEx
 */
89
static BOOL CALLBACK EnumPropsW_relay( HWND hwnd, LPWSTR str, HANDLE handle, ULONG_PTR lparam )
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
{
    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 )
{
119
    WCHAR buffer[ATOM_BUFFER_SIZE];
120

121
    if (IS_INTRESOURCE(str)) return GetPropW( hwnd, (LPCWSTR)str );
122 123
    if (!MultiByteToWideChar( CP_ACP, 0, str, -1, buffer, ATOM_BUFFER_SIZE )) return 0;
    return GetPropW( hwnd, buffer );
124 125 126 127 128 129 130 131
}


/***********************************************************************
 *              GetPropW   (USER32.@)
 */
HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
{
132
    ULONG_PTR ret = 0;
133 134 135

    SERVER_START_REQ( get_window_property )
    {
136
        req->window = wine_server_user_handle( hwnd );
137
        if (IS_INTRESOURCE(str)) req->atom = LOWORD(str);
138
        else wine_server_add_data( req, str, strlenW(str) * sizeof(WCHAR) );
139
        if (!wine_server_call_err( req )) ret = reply->data;
140 141
    }
    SERVER_END_REQ;
142
    return (HANDLE)ret;
143 144 145 146 147 148 149 150
}


/***********************************************************************
 *              SetPropA   (USER32.@)
 */
BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
{
151
    WCHAR buffer[ATOM_BUFFER_SIZE];
152

153
    if (IS_INTRESOURCE(str)) return SetPropW( hwnd, (LPCWSTR)str, handle );
154 155
    if (!MultiByteToWideChar( CP_ACP, 0, str, -1, buffer, ATOM_BUFFER_SIZE )) return FALSE;
    return SetPropW( hwnd, buffer, handle );
156 157 158 159 160 161 162 163 164 165 166 167
}


/***********************************************************************
 *              SetPropW   (USER32.@)
 */
BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
{
    BOOL ret;

    SERVER_START_REQ( set_window_property )
    {
168
        req->window = wine_server_user_handle( hwnd );
169
        req->data   = (ULONG_PTR)handle;
170
        if (IS_INTRESOURCE(str)) req->atom = LOWORD(str);
171
        else wine_server_add_data( req, str, strlenW(str) * sizeof(WCHAR) );
172
        ret = !wine_server_call_err( req );
173 174 175 176 177 178 179 180 181 182 183
    }
    SERVER_END_REQ;
    return ret;
}


/***********************************************************************
 *              RemovePropA   (USER32.@)
 */
HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str )
{
184
    WCHAR buffer[ATOM_BUFFER_SIZE];
185

186
    if (IS_INTRESOURCE(str)) return RemovePropW( hwnd, (LPCWSTR)str );
187 188
    if (!MultiByteToWideChar( CP_ACP, 0, str, -1, buffer, ATOM_BUFFER_SIZE )) return 0;
    return RemovePropW( hwnd, buffer );
189 190 191 192 193 194 195 196
}


/***********************************************************************
 *              RemovePropW   (USER32.@)
 */
HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
{
197
    ULONG_PTR ret = 0;
198 199 200

    SERVER_START_REQ( remove_window_property )
    {
201
        req->window = wine_server_user_handle( hwnd );
202
        if (IS_INTRESOURCE(str)) req->atom = LOWORD(str);
203
        else wine_server_add_data( req, str, strlenW(str) * sizeof(WCHAR) );
204
        if (!wine_server_call_err( req )) ret = reply->data;
205 206 207
    }
    SERVER_END_REQ;

208
    return (HANDLE)ret;
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
}


/***********************************************************************
 *              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;
226
            if (!(ret = func( hwnd, string, (HANDLE)(ULONG_PTR)list[i].data, lParam ))) break;
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
        }
        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;
248
            if (!(ret = func( hwnd, string, (HANDLE)(ULONG_PTR)list[i].data, lParam ))) break;
249 250 251 252 253
        }
        HeapFree( GetProcessHeap(), 0, list );
    }
    return ret;
}