user32: Reimplement accelerator functions to use 32-bit user handles instead of 16-bit functions.
This commit is contained in:
parent
a187b43ddd
commit
a7adbf7849
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;i<nrofaccells;i++) {
|
||||
accel16[i].fVirt = accel_table[i].fVirt & 0x7f;
|
||||
accel16[i].key = accel_table[i].key;
|
||||
if( !(accel16[i].fVirt & FVIRTKEY) )
|
||||
accel16[i].key &= 0x00ff;
|
||||
accel16[i].cmd = accel_table[i].cmd;
|
||||
}
|
||||
accel16[i-1].fVirt |= 0x80;
|
||||
}
|
||||
}
|
||||
TRACE_(accel)("returning HACCEL %p\n", hRsrc);
|
||||
return HACCEL_32(hRetval);
|
||||
if (!(rsrc = FindResourceW( instance, name, (LPWSTR)RT_ACCELERATOR ))) return 0;
|
||||
table = LoadResource( instance, rsrc );
|
||||
count = SizeofResource( instance, rsrc ) / sizeof(*table);
|
||||
if (!count) return 0;
|
||||
accel = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( struct accelerator, table[count] ));
|
||||
if (!accel) return 0;
|
||||
accel->count = 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<entries) entries=xsize;
|
||||
|
||||
i=0;
|
||||
while(!done) {
|
||||
/* Spit out some debugging information. */
|
||||
TRACE_(accel)("accel %d: type 0x%02x, event '%c', IDval 0x%04x.\n",
|
||||
i, accel[i].fVirt, accel[i].key, accel[i].cmd);
|
||||
|
||||
/* Copy data to the destination structure array (if dst == NULL,
|
||||
we're just supposed to count the number of entries). */
|
||||
if(dst) {
|
||||
dst[i].fVirt = accel[i].fVirt&0x7f;
|
||||
dst[i].key = accel[i].key;
|
||||
dst[i].cmd = accel[i].cmd;
|
||||
|
||||
/* Check if we've reached the end of the application supplied
|
||||
accelerator table. */
|
||||
if(i+1 == entries)
|
||||
done = TRUE;
|
||||
if (!(accel = get_user_handle_ptr( src, USER_ACCEL ))) return 0;
|
||||
if (accel == OBJ_OTHER_PROCESS)
|
||||
{
|
||||
FIXME( "other process handle %p?\n", src );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The highest order bit seems to mark the end of the accelerator
|
||||
resource table, but not always. Use GlobalSize() check too. */
|
||||
if((accel[i].fVirt & 0x80) != 0) done = TRUE;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
if (dst)
|
||||
{
|
||||
if (count > 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;i<cEntries;i++) {
|
||||
accel[i].fVirt = lpaccel[i].fVirt&0x7f;
|
||||
accel[i].key = lpaccel[i].key;
|
||||
if( !(accel[i].fVirt & FVIRTKEY) )
|
||||
accel[i].key &= 0x00ff;
|
||||
accel[i].cmd = lpaccel[i].cmd;
|
||||
}
|
||||
/* Set the end-of-table terminator. */
|
||||
accel[cEntries-1].fVirt |= 0x80;
|
||||
|
||||
TRACE_(accel)("Allocated accelerator handle %p with %d entries\n", hAccel,cEntries);
|
||||
return hAccel;
|
||||
if (count < 1)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
accel = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( struct accelerator, table[count] ));
|
||||
if (!accel) return 0;
|
||||
accel->count = 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;i<cEntries;i++) {
|
||||
accel[i].fVirt = lpaccel[i].fVirt&0x7f;
|
||||
if( !(accel[i].fVirt & FVIRTKEY) ) {
|
||||
ckey = (char) lpaccel[i].key;
|
||||
if(!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, &ckey, 1, &accel[i].key, 1))
|
||||
WARN_(accel)("Error converting ASCII accelerator table to Unicode\n");
|
||||
}
|
||||
else
|
||||
accel[i].key = lpaccel[i].key;
|
||||
accel[i].cmd = lpaccel[i].cmd;
|
||||
}
|
||||
|
||||
/* Set the end-of-table terminator. */
|
||||
accel[cEntries-1].fVirt |= 0x80;
|
||||
|
||||
TRACE_(accel)("Allocated accelerator handle %p\n", hAccel);
|
||||
return hAccel;
|
||||
if (count < 1)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
accel = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( struct accelerator, table[count] ));
|
||||
if (!accel) return 0;
|
||||
accel->count = 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 );
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
|
|
@ -128,6 +128,7 @@ enum user_obj_type
|
|||
{
|
||||
USER_WINDOW = 1, /* window */
|
||||
USER_MENU, /* menu */
|
||||
USER_ACCEL, /* accelerator */
|
||||
USER_DWP /* DeferWindowPos structure */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue