2 * USER resource functions
4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995, 2009 Alexandre Julliard
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/debug.h"
30 #include "user_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(resource
);
33 WINE_DECLARE_DEBUG_CHANNEL(accel
);
35 /* this is the 8 byte accel struct used in Win32 resources (internal only) */
44 /* the accelerator user object */
47 struct user_object obj
;
52 /**********************************************************************
53 * LoadAcceleratorsW (USER32.@)
55 HACCEL WINAPI
LoadAcceleratorsW(HINSTANCE instance
, LPCWSTR name
)
57 struct accelerator
*accel
;
58 const PE_ACCEL
*table
;
63 if (!(rsrc
= FindResourceW( instance
, name
, (LPWSTR
)RT_ACCELERATOR
))) return 0;
64 table
= LoadResource( instance
, rsrc
);
65 count
= SizeofResource( instance
, rsrc
) / sizeof(*table
);
67 accel
= HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( struct accelerator
, table
[count
] ));
70 memcpy( accel
->table
, table
, count
* sizeof(*table
) );
71 if (!(handle
= alloc_user_handle( &accel
->obj
, USER_ACCEL
)))
72 HeapFree( GetProcessHeap(), 0, accel
);
74 TRACE_(accel
)("%p %s returning %p\n", instance
, debugstr_w(name
), handle
);
78 /***********************************************************************
79 * LoadAcceleratorsA (USER32.@)
81 HACCEL WINAPI
LoadAcceleratorsA(HINSTANCE instance
,LPCSTR lpTableName
)
87 if (!HIWORD(lpTableName
)) return LoadAcceleratorsW( instance
, (LPCWSTR
)lpTableName
);
89 len
= MultiByteToWideChar( CP_ACP
, 0, lpTableName
, -1, NULL
, 0 );
90 if ((uni
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
92 MultiByteToWideChar( CP_ACP
, 0, lpTableName
, -1, uni
, len
);
93 result
= LoadAcceleratorsW(instance
,uni
);
94 HeapFree( GetProcessHeap(), 0, uni
);
99 /**********************************************************************
100 * CopyAcceleratorTableA (USER32.@)
102 INT WINAPI
CopyAcceleratorTableA(HACCEL src
, LPACCEL dst
, INT count
)
105 int i
, ret
= CopyAcceleratorTableW( src
, dst
, count
);
109 for (i
= 0; i
< ret
; i
++)
111 if (dst
[i
].fVirt
& FVIRTKEY
) continue;
112 WideCharToMultiByte( CP_ACP
, 0, &dst
[i
].key
, 1, &ch
, 1, NULL
, NULL
);
119 /**********************************************************************
120 * CopyAcceleratorTableW (USER32.@)
122 INT WINAPI
CopyAcceleratorTableW(HACCEL src
, LPACCEL dst
, INT count
)
124 struct accelerator
*accel
;
127 if (!(accel
= get_user_handle_ptr( src
, USER_ACCEL
))) return 0;
128 if (accel
== OBJ_OTHER_PROCESS
)
130 FIXME( "other process handle %p?\n", src
);
135 if (count
> accel
->count
) count
= accel
->count
;
136 for (i
= 0; i
< count
; i
++)
138 dst
[i
].fVirt
= accel
->table
[i
].fVirt
& 0x7f;
139 dst
[i
].key
= accel
->table
[i
].key
;
140 dst
[i
].cmd
= accel
->table
[i
].cmd
;
143 else count
= accel
->count
;
144 release_user_handle_ptr( accel
);
148 /*********************************************************************
149 * CreateAcceleratorTableA (USER32.@)
151 HACCEL WINAPI
CreateAcceleratorTableA(LPACCEL lpaccel
, INT count
)
153 struct accelerator
*accel
;
159 SetLastError( ERROR_INVALID_PARAMETER
);
162 accel
= HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( struct accelerator
, table
[count
] ));
163 if (!accel
) return 0;
164 accel
->count
= count
;
165 for (i
= 0; i
< count
; i
++)
167 accel
->table
[i
].fVirt
= lpaccel
[i
].fVirt
;
168 accel
->table
[i
].cmd
= lpaccel
[i
].cmd
;
169 if (!(lpaccel
[i
].fVirt
& FVIRTKEY
))
171 char ch
= lpaccel
[i
].key
;
172 MultiByteToWideChar( CP_ACP
, 0, &ch
, 1, &accel
->table
[i
].key
, 1 );
174 else accel
->table
[i
].key
= lpaccel
[i
].key
;
176 if (!(handle
= alloc_user_handle( &accel
->obj
, USER_ACCEL
)))
177 HeapFree( GetProcessHeap(), 0, accel
);
178 TRACE_(accel
)("returning %p\n", handle
);
182 /*********************************************************************
183 * CreateAcceleratorTableW (USER32.@)
185 HACCEL WINAPI
CreateAcceleratorTableW(LPACCEL lpaccel
, INT count
)
187 struct accelerator
*accel
;
193 SetLastError( ERROR_INVALID_PARAMETER
);
196 accel
= HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( struct accelerator
, table
[count
] ));
197 if (!accel
) return 0;
198 accel
->count
= count
;
199 for (i
= 0; i
< count
; i
++)
201 accel
->table
[i
].fVirt
= lpaccel
[i
].fVirt
;
202 accel
->table
[i
].key
= lpaccel
[i
].key
;
203 accel
->table
[i
].cmd
= lpaccel
[i
].cmd
;
205 if (!(handle
= alloc_user_handle( &accel
->obj
, USER_ACCEL
)))
206 HeapFree( GetProcessHeap(), 0, accel
);
207 TRACE_(accel
)("returning %p\n", handle
);
211 /******************************************************************************
212 * DestroyAcceleratorTable [USER32.@]
213 * Destroys an accelerator table
216 * handle [I] Handle to accelerator table
222 BOOL WINAPI
DestroyAcceleratorTable( HACCEL handle
)
224 struct accelerator
*accel
;
226 if (!(accel
= free_user_handle( handle
, USER_ACCEL
))) return FALSE
;
227 if (accel
== OBJ_OTHER_PROCESS
)
229 FIXME( "other process handle %p?\n", accel
);
232 return HeapFree( GetProcessHeap(), 0, accel
);
235 /**********************************************************************
236 * LoadStringW (USER32.@)
238 INT WINAPI
LoadStringW( HINSTANCE instance
, UINT resource_id
,
239 LPWSTR buffer
, INT buflen
)
247 TRACE("instance = %p, id = %04x, buffer = %p, length = %d\n",
248 instance
, resource_id
, buffer
, buflen
);
253 /* Use loword (incremented by 1) as resourceid */
254 hrsrc
= FindResourceW( instance
, MAKEINTRESOURCEW((LOWORD(resource_id
) >> 4) + 1),
256 if (!hrsrc
) return 0;
257 hmem
= LoadResource( instance
, hrsrc
);
260 p
= LockResource(hmem
);
261 string_num
= resource_id
& 0x000f;
262 for (i
= 0; i
< string_num
; i
++)
265 TRACE("strlen = %d\n", (int)*p
);
267 /*if buflen == 0, then return a read-only pointer to the resource itself in buffer
268 it is assumed that buffer is actually a (LPWSTR *) */
271 *((LPWSTR
*)buffer
) = p
+ 1;
275 i
= min(buflen
- 1, *p
);
277 memcpy(buffer
, p
+ 1, i
* sizeof (WCHAR
));
286 TRACE("%s loaded !\n", debugstr_w(buffer
));
290 /**********************************************************************
291 * LoadStringA (USER32.@)
293 INT WINAPI
LoadStringA( HINSTANCE instance
, UINT resource_id
, LPSTR buffer
, INT buflen
)
299 TRACE("instance = %p, id = %04x, buffer = %p, length = %d\n",
300 instance
, resource_id
, buffer
, buflen
);
302 if (!buflen
) return -1;
304 /* Use loword (incremented by 1) as resourceid */
305 if ((hrsrc
= FindResourceW( instance
, MAKEINTRESOURCEW((LOWORD(resource_id
) >> 4) + 1),
306 (LPWSTR
)RT_STRING
)) &&
307 (hmem
= LoadResource( instance
, hrsrc
)))
309 const WCHAR
*p
= LockResource(hmem
);
310 unsigned int id
= resource_id
& 0x000f;
312 while (id
--) p
+= *p
+ 1;
314 RtlUnicodeToMultiByteN( buffer
, buflen
- 1, &retval
, p
+ 1, *p
* sizeof(WCHAR
) );
317 TRACE("returning %s\n", debugstr_a(buffer
));
321 /**********************************************************************
322 * GetGuiResources (USER32.@)
324 DWORD WINAPI
GetGuiResources( HANDLE hProcess
, DWORD uiFlags
)
326 static BOOL warn
= TRUE
;
329 FIXME("(%p,%x): stub\n",hProcess
,uiFlags
);
333 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);