diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 59600316fdf..eb96ab4765b 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -5344,52 +5344,26 @@ static BOOL translate_accelerator( HWND hWnd, UINT message, WPARAM wParam, LPARA */ INT WINAPI TranslateAcceleratorA( HWND hWnd, HACCEL hAccel, LPMSG msg ) { - /* YES, Accel16! */ - LPACCEL16 lpAccelTbl; - int i; - WPARAM wParam; - - if (!hWnd || !msg) return 0; - - if (!hAccel || !(lpAccelTbl = (LPACCEL16) LockResource16(HACCEL_16(hAccel)))) - { - WARN_(accel)("invalid accel handle=%p\n", hAccel); - return 0; - } - - wParam = msg->wParam; - switch (msg->message) { case WM_KEYDOWN: case WM_SYSKEYDOWN: - break; + return TranslateAcceleratorW( hWnd, hAccel, msg ); case WM_CHAR: case WM_SYSCHAR: { - char ch = LOWORD(wParam); + MSG msgW = *msg; + char ch = LOWORD(msg->wParam); WCHAR wch; MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wch, 1); - wParam = MAKEWPARAM(wch, HIWORD(wParam)); + msgW.wParam = MAKEWPARAM(wch, HIWORD(msg->wParam)); + return TranslateAcceleratorW( hWnd, hAccel, &msgW ); } - break; default: return 0; } - - TRACE_(accel)("hAccel %p, hWnd %p, msg->hwnd %p, msg->message %04x, wParam %08lx, lParam %08lx\n", - hAccel,hWnd,msg->hwnd,msg->message,msg->wParam,msg->lParam); - i = 0; - do - { - if (translate_accelerator( hWnd, msg->message, wParam, msg->lParam, - lpAccelTbl[i].fVirt, lpAccelTbl[i].key, lpAccelTbl[i].cmd)) - return 1; - } while ((lpAccelTbl[i++].fVirt & 0x80) == 0); - - return 0; } /********************************************************************** @@ -5397,39 +5371,32 @@ INT WINAPI TranslateAcceleratorA( HWND hWnd, HACCEL hAccel, LPMSG msg ) */ INT WINAPI TranslateAcceleratorW( HWND hWnd, HACCEL hAccel, LPMSG msg ) { - /* YES, Accel16! */ - LPACCEL16 lpAccelTbl; - int i; + ACCEL data[32], *ptr = data; + int i, count; - if (!hWnd || !msg) return 0; + if (!hWnd) return 0; - if (!hAccel || !(lpAccelTbl = (LPACCEL16) LockResource16(HACCEL_16(hAccel)))) - { - WARN_(accel)("invalid accel handle=%p\n", hAccel); + if (msg->message != WM_KEYDOWN && + msg->message != WM_SYSKEYDOWN && + msg->message != WM_CHAR && + msg->message != WM_SYSCHAR) return 0; - } - - switch (msg->message) - { - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - case WM_CHAR: - case WM_SYSCHAR: - break; - - default: - return 0; - } TRACE_(accel)("hAccel %p, hWnd %p, msg->hwnd %p, msg->message %04x, wParam %08lx, lParam %08lx\n", hAccel,hWnd,msg->hwnd,msg->message,msg->wParam,msg->lParam); - i = 0; - do + + if (!(count = CopyAcceleratorTableW( hAccel, NULL, 0 ))) return 0; + if (count > sizeof(data)/sizeof(data[0])) + { + if (!(ptr = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*ptr) ))) return 0; + } + count = CopyAcceleratorTableW( hAccel, ptr, count ); + for (i = 0; i < count; i++) { if (translate_accelerator( hWnd, msg->message, msg->wParam, msg->lParam, - lpAccelTbl[i].fVirt, lpAccelTbl[i].key, lpAccelTbl[i].cmd)) - return 1; - } while ((lpAccelTbl[i++].fVirt & 0x80) == 0); - - return 0; + ptr[i].fVirt, ptr[i].key, ptr[i].cmd)) + break; + } + if (ptr != data) HeapFree( GetProcessHeap(), 0, ptr ); + return (i < count); } diff --git a/dlls/user32/resource.c b/dlls/user32/resource.c index 57fa7b80b05..1085dfa25e3 100644 --- a/dlls/user32/resource.c +++ b/dlls/user32/resource.c @@ -2,7 +2,7 @@ * USER resource functions * * Copyright 1993 Robert J. Amstadt - * Copyright 1995 Alexandre Julliard + * Copyright 1995, 2009 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,6 +30,7 @@ #include "wine/winuser16.h" #include "wownt32.h" #include "wine/debug.h" +#include "user_private.h" WINE_DEFAULT_DEBUG_CHANNEL(resource); WINE_DECLARE_DEBUG_CHANNEL(accel); @@ -41,7 +42,15 @@ typedef struct WORD key; WORD cmd; WORD pad; -} PE_ACCEL, *LPPE_ACCEL; +} PE_ACCEL; + +/* the accelerator user object */ +struct accelerator +{ + struct user_object obj; + unsigned int count; + PE_ACCEL table[1]; +}; /********************************************************************** * LoadAccelerators [USER.177] @@ -63,50 +72,28 @@ HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, LPCSTR lpTableName) /********************************************************************** * LoadAcceleratorsW (USER32.@) - * The image layout seems to look like this (not 100% sure): - * 00: WORD type type of accelerator - * 02: WORD event - * 04: WORD IDval - * 06: WORD pad (to DWORD boundary) */ -HACCEL WINAPI LoadAcceleratorsW(HINSTANCE instance,LPCWSTR lpTableName) +HACCEL WINAPI LoadAcceleratorsW(HINSTANCE instance, LPCWSTR name) { - HRSRC hRsrc; - HACCEL hMem; - HACCEL16 hRetval=0; - DWORD size; + struct accelerator *accel; + const PE_ACCEL *table; + HRSRC rsrc; + HACCEL handle; + DWORD count; - if (HIWORD(lpTableName)) - TRACE_(accel)("%p '%s'\n", instance, (const char *)( lpTableName ) ); - else - TRACE_(accel)("%p 0x%04x\n", instance, LOWORD(lpTableName) ); - - if (!(hRsrc = FindResourceW( instance, lpTableName, (LPWSTR)RT_ACCELERATOR ))) - { - WARN_(accel)("couldn't find accelerator table resource\n"); - } else { - hMem = LoadResource( instance, hRsrc ); - size = SizeofResource( instance, hRsrc ); - if(size>=sizeof(PE_ACCEL)) - { - LPPE_ACCEL accel_table = (LPPE_ACCEL) hMem; - LPACCEL16 accel16; - int i,nrofaccells = size/sizeof(PE_ACCEL); - - hRetval = GlobalAlloc16(0,sizeof(ACCEL16)*nrofaccells); - accel16 = (LPACCEL16)GlobalLock16(hRetval); - for (i=0;icount = count; + memcpy( accel->table, table, count * sizeof(*table) ); + if (!(handle = alloc_user_handle( &accel->obj, USER_ACCEL ))) + HeapFree( GetProcessHeap(), 0, accel ); + return handle; + TRACE_(accel)("%p %s returning %p\n", instance, debugstr_w(name), handle ); + return handle; } /*********************************************************************** @@ -133,165 +120,119 @@ HACCEL WINAPI LoadAcceleratorsA(HINSTANCE instance,LPCSTR lpTableName) /********************************************************************** * CopyAcceleratorTableA (USER32.@) */ -INT WINAPI CopyAcceleratorTableA(HACCEL src, LPACCEL dst, INT entries) +INT WINAPI CopyAcceleratorTableA(HACCEL src, LPACCEL dst, INT count) { - return CopyAcceleratorTableW(src, dst, entries); + char ch; + int i, ret = CopyAcceleratorTableW( src, dst, count ); + + if (ret && dst) + { + for (i = 0; i < ret; i++) + { + if (dst[i].fVirt & FVIRTKEY) continue; + WideCharToMultiByte( CP_ACP, 0, &dst[i].key, 1, &ch, 1, NULL, NULL ); + dst[i].key = ch; + } + } + return ret; } /********************************************************************** * CopyAcceleratorTableW (USER32.@) - * - * By mortene@pvv.org 980321 */ -INT WINAPI CopyAcceleratorTableW(HACCEL src, LPACCEL dst, - INT entries) +INT WINAPI CopyAcceleratorTableW(HACCEL src, LPACCEL dst, INT count) { - int i,xsize; - LPACCEL16 accel = (LPACCEL16)GlobalLock16(HACCEL_16(src)); - BOOL done = FALSE; + struct accelerator *accel; + int i; - /* Do parameter checking to avoid the explosions and the screaming - as far as possible. */ - if((dst && (entries < 1)) || (src == NULL) || !accel) { - WARN_(accel)("Application sent invalid parameters (%p %p %d).\n", - src, dst, entries); - return 0; - } - xsize = GlobalSize16(HACCEL_16(src))/sizeof(ACCEL16); - if (xsize accel->count) count = accel->count; + for (i = 0; i < count; i++) + { + dst[i].fVirt = accel->table[i].fVirt & 0x7f; + dst[i].key = accel->table[i].key; + dst[i].cmd = accel->table[i].cmd; + } + } + else count = accel->count; + release_user_handle_ptr( accel ); + return count; } /********************************************************************* * CreateAcceleratorTableA (USER32.@) - * - * By mortene@pvv.org 980321 */ -HACCEL WINAPI CreateAcceleratorTableA(LPACCEL lpaccel, INT cEntries) +HACCEL WINAPI CreateAcceleratorTableA(LPACCEL lpaccel, INT count) { - HACCEL hAccel; - LPACCEL16 accel; - int i; + struct accelerator *accel; + HACCEL handle; + int i; - /* Do parameter checking just in case someone's trying to be - funny. */ - if(cEntries < 1) { - WARN_(accel)("Application sent invalid parameters (%p %d).\n", - lpaccel, cEntries); - SetLastError(ERROR_INVALID_PARAMETER); - return NULL; - } - - /* Allocate memory and copy the table. */ - hAccel = HACCEL_32(GlobalAlloc16(0,cEntries*sizeof(ACCEL16))); - - TRACE_(accel)("handle %p\n", hAccel); - if(!hAccel) { - ERR_(accel)("Out of memory.\n"); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } - accel = GlobalLock16(HACCEL_16(hAccel)); - for (i=0;icount = count; + for (i = 0; i < count; i++) + { + accel->table[i].fVirt = lpaccel[i].fVirt; + accel->table[i].cmd = lpaccel[i].cmd; + if (!(lpaccel[i].fVirt & FVIRTKEY)) + { + char ch = lpaccel[i].key; + MultiByteToWideChar( CP_ACP, 0, &ch, 1, &accel->table[i].key, 1 ); + } + else accel->table[i].key = lpaccel[i].key; + } + if (!(handle = alloc_user_handle( &accel->obj, USER_ACCEL ))) + HeapFree( GetProcessHeap(), 0, accel ); + TRACE_(accel)("returning %p\n", handle ); + return handle; } /********************************************************************* * CreateAcceleratorTableW (USER32.@) - * - * */ -HACCEL WINAPI CreateAcceleratorTableW(LPACCEL lpaccel, INT cEntries) +HACCEL WINAPI CreateAcceleratorTableW(LPACCEL lpaccel, INT count) { - HACCEL hAccel; - LPACCEL16 accel; - int i; - char ckey; + struct accelerator *accel; + HACCEL handle; + int i; - /* Do parameter checking just in case someone's trying to be - funny. */ - if(cEntries < 1) { - WARN_(accel)("Application sent invalid parameters (%p %d).\n", - lpaccel, cEntries); - SetLastError(ERROR_INVALID_PARAMETER); - return NULL; - } - - /* Allocate memory and copy the table. */ - hAccel = HACCEL_32(GlobalAlloc16(0,cEntries*sizeof(ACCEL16))); - - TRACE_(accel)("handle %p\n", hAccel); - if(!hAccel) { - ERR_(accel)("Out of memory.\n"); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } - accel = GlobalLock16(HACCEL_16(hAccel)); - - - for (i=0;icount = count; + for (i = 0; i < count; i++) + { + accel->table[i].fVirt = lpaccel[i].fVirt; + accel->table[i].key = lpaccel[i].key; + accel->table[i].cmd = lpaccel[i].cmd; + } + if (!(handle = alloc_user_handle( &accel->obj, USER_ACCEL ))) + HeapFree( GetProcessHeap(), 0, accel ); + TRACE_(accel)("returning %p\n", handle ); + return handle; } /****************************************************************************** * DestroyAcceleratorTable [USER32.@] * Destroys an accelerator table * - * NOTES - * By mortene@pvv.org 980321 - * * PARAMS * handle [I] Handle to accelerator table * @@ -301,9 +242,15 @@ HACCEL WINAPI CreateAcceleratorTableW(LPACCEL lpaccel, INT cEntries) */ BOOL WINAPI DestroyAcceleratorTable( HACCEL handle ) { - if( !handle ) + struct accelerator *accel; + + if (!(accel = free_user_handle( handle, USER_ACCEL ))) return FALSE; + if (accel == OBJ_OTHER_PROCESS) + { + FIXME( "other process handle %p?\n", accel ); return FALSE; - return !GlobalFree16(HACCEL_16(handle)); + } + return HeapFree( GetProcessHeap(), 0, accel ); } /********************************************************************** diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 3dc1d83dc04..8c49ad39431 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -128,6 +128,7 @@ enum user_obj_type { USER_WINDOW = 1, /* window */ USER_MENU, /* menu */ + USER_ACCEL, /* accelerator */ USER_DWP /* DeferWindowPos structure */ };