This fixes a problem with Mind Your Own Business Premier 7.
ChangeLog: * Fix a problem with menu accelerators and add a regression test for it
Index: dlls/user/resource.c =================================================================== RCS file: /home/wine/wine/dlls/user/resource.c,v retrieving revision 1.19 diff -u -r1.19 resource.c --- dlls/user/resource.c 26 Nov 2003 22:28:16 -0000 1.19 +++ dlls/user/resource.c 18 Dec 2003 08:48:45 -0000 @@ -171,17 +171,17 @@ /* 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; - dst[i].key = accel[i].key; + dst[i].fVirt = accel[i].fVirt & 0x7f; + if( accel[i].fVirt & FVIRTKEY ) + dst[i].key = accel[i].key; + else + dst[i].key = accel[i].key & 0x00ff; dst[i].cmd = accel[i].cmd; /* Check if we've reached the end of the application supplied accelerator table. */ - if(i+1 == entries) { - /* Turn off the high order bit, just in case. */ - dst[i].fVirt &= 0x7f; + if(i+1 == entries) done = TRUE; - } } /* The highest order bit seems to mark the end of the accelerator Index: dlls/user/tests/Makefile.in =================================================================== RCS file: /home/wine/wine/dlls/user/tests/Makefile.in,v retrieving revision 1.6 diff -u -r1.6 Makefile.in --- dlls/user/tests/Makefile.in 28 Oct 2003 00:18:40 -0000 1.6 +++ dlls/user/tests/Makefile.in 18 Dec 2003 08:48:45 -0000 @@ -6,6 +6,7 @@ IMPORTS = user32 gdi32 advapi32 CTESTS = \ + accel.c \ class.c \ generated.c \ input.c \ --- /dev/null 1994-07-18 08:46:18.000000000 +0900 +++ dlls/user/tests/accel.c 2003-12-18 18:05:28.000000000 +0900 @@ -0,0 +1,132 @@ +/* Unit test suite for Keyboard Accelerators + * + * Copyright 2003 Mike McCormack + * + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <assert.h> +#include <stdlib.h> +#include <stdarg.h> +#include <stdio.h> + +#include "wine/test.h" +#include "windef.h" +#include "winbase.h" +#include "winuser.h" + + +START_TEST(accel) +{ + UINT r, n; + HACCEL hAccel; + ACCEL ac[10]; + + /* now create our own valid accelerator table */ + n = 0; + ac[n].cmd = 1000; + ac[n].key = 'A'; + ac[n++].fVirt = FVIRTKEY | FNOINVERT; + + ac[n].cmd = 1001; + ac[n].key = 'B'; + ac[n++].fVirt = FNOINVERT; + + ac[n].cmd = 0; + ac[n].key = 0; + ac[n++].fVirt = 0; + + hAccel = CreateAcceleratorTable( &ac[0], n ); + ok( hAccel != NULL, "create accelerator table"); + + r = DestroyAcceleratorTable( hAccel ); + ok( r, "destroy accelerator table" ); + + /* now try create an invalid one */ + n = 0; + ac[n].cmd = 1000; + ac[n].key = 'A'; + ac[n++].fVirt = FVIRTKEY | FNOINVERT; + + ac[n].cmd = 0xffff; + ac[n].key = 0xffff; + ac[n++].fVirt = (SHORT) 0xffff; + + ac[n].cmd = 0xfff0; + ac[n].key = 0xffff; + ac[n++].fVirt = (SHORT) 0xfff0; + + ac[n].cmd = 0xfff0; + ac[n].key = 0xffff; + ac[n++].fVirt = (SHORT) 0x0000; + + ac[n].cmd = 0xfff0; + ac[n].key = 0xffff; + ac[n++].fVirt = (SHORT) 0x0001; + + hAccel = CreateAcceleratorTable( &ac[0], n ); + ok( hAccel != NULL, "create accelerator table"); + + r = CopyAcceleratorTable( hAccel, NULL, 0 ); + ok( r == n, "two entries in table\n"); + + r = CopyAcceleratorTable( hAccel, &ac[0], r ); + ok( r == n, "still should be two entries in table\n"); + + n=0; + ok( ac[n].cmd == 1000, "cmd 0 not preserved"); + ok( ac[n].key == 'A', "key 0 not preserved"); + ok( ac[n].fVirt == (FVIRTKEY | FNOINVERT), "fVirt 0 not preserved"); + + n++; + ok( ac[n].cmd == 0xffff, "cmd 1 not preserved"); + ok( ac[n].key == 0xffff, "key 1 not preserved"); + ok( ac[n].fVirt == 0x007f, "fVirt 1 not changed"); + + n++; + ok( ac[n].cmd == 0xfff0, "cmd 2 not preserved"); + ok( ac[n].key == 0x00ff, "key 2 not preserved"); + ok( ac[n].fVirt == 0x0070, "fVirt 2 not changed"); + + n++; + ok( ac[n].cmd == 0xfff0, "cmd 3 not preserved"); + ok( ac[n].key == 0x00ff, "key 3 not preserved"); + ok( ac[n].fVirt == 0x0000, "fVirt 3 not changed"); + + n++; + ok( ac[n].cmd == 0xfff0, "cmd 4 not preserved"); + ok( ac[n].key == 0xffff, "key 4 not preserved"); + ok( ac[n].fVirt == 0x0001, "fVirt 4 not changed"); + + /* + n = 0; + printf("%04x %04x %04x\n", ac[n].cmd, ac[n].fVirt, ac[n].key );n++; + printf("%04x %04x %04x\n", ac[n].cmd, ac[n].fVirt, ac[n].key );n++; + printf("%04x %04x %04x\n", ac[n].cmd, ac[n].fVirt, ac[n].key );n++; + printf("%04x %04x %04x\n", ac[n].cmd, ac[n].fVirt, ac[n].key );n++; + printf("%04x %04x %04x\n", ac[n].cmd, ac[n].fVirt, ac[n].key );n++; + */ + + r = DestroyAcceleratorTable( hAccel ); + ok( r, "destroy accelerator table" ); + + hAccel = CreateAcceleratorTable( &ac[0], 0 ); + ok( !hAccel, "zero elements should fail"); + + /* these will on crash win2k + hAccel = CreateAcceleratorTable( NULL, 1 ); + hAccel = CreateAcceleratorTable( &ac[0], -1 ); + */ +}