From ef55932f4b1ba4c0f0539a061f48e12a733214d9 Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Thu, 26 Oct 2000 21:47:20 +0000 Subject: [PATCH] Ask application to reinitialize its menu before processing an accelerator key. --- controls/menu.c | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- windows/input.c | 207 ------------------------------------------------- 2 files changed, 231 insertions(+), 209 deletions(-) diff --git a/controls/menu.c b/controls/menu.c index 5a26a71d500..c6efef07c51 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -35,8 +35,8 @@ #include "debugtools.h" -DEFAULT_DEBUG_CHANNEL(menu) - +DEFAULT_DEBUG_CHANNEL(menu); +DECLARE_DEBUG_CHANNEL(accel); /* internal popup menu window messages */ @@ -4936,3 +4936,232 @@ UINT WINAPI MenuItemFromPoint(HWND hWnd, HMENU hMenu, POINT ptScreen) hWnd, hMenu, ptScreen.x, ptScreen.y); return 0; } + + +/********************************************************************** + * translate_accelerator + */ +static BOOL translate_accelerator( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, + BYTE fVirt, WORD key, WORD cmd ) +{ + UINT mesg = 0; + + if (wParam != key) return FALSE; + + if (message == WM_CHAR) + { + if ( !(fVirt & FALT) && !(fVirt & FVIRTKEY) ) + { + TRACE_(accel)("found accel for WM_CHAR: ('%c')\n", wParam & 0xff); + goto found; + } + } + else + { + if(fVirt & FVIRTKEY) + { + INT mask = 0; + TRACE_(accel)("found accel for virt_key %04x (scan %04x)\n", + wParam, 0xff & HIWORD(lParam)); + if(GetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT; + if(GetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL; + if(GetKeyState(VK_MENU) & 0x8000) mask |= FALT; + if(mask == (fVirt & (FSHIFT | FCONTROL | FALT))) goto found; + TRACE_(accel)(", but incorrect SHIFT/CTRL/ALT-state\n"); + } + else + { + if (!(lParam & 0x01000000)) /* no special_key */ + { + if ((fVirt & FALT) && (lParam & 0x20000000)) + { /* ^^ ALT pressed */ + TRACE_(accel)("found accel for Alt-%c\n", wParam & 0xff); + goto found; + } + } + } + } + return FALSE; + + found: + if (message == WM_KEYUP || message == WM_SYSKEYUP) + mesg = 1; + else if (GetCapture()) + mesg = 2; + else if (!IsWindowEnabled(hWnd)) + mesg = 3; + else + { + HMENU hMenu, hSubMenu, hSysMenu; + UINT uSysStat = (UINT)-1, uStat = (UINT)-1, nPos; + WND* wndPtr = WIN_FindWndPtr(hWnd); + + hMenu = (wndPtr->dwStyle & WS_CHILD) ? 0 : (HMENU)wndPtr->wIDmenu; + hSysMenu = wndPtr->hSysMenu; + WIN_ReleaseWndPtr(wndPtr); + + /* find menu item and ask application to initialize it */ + /* 1. in the system menu */ + hSubMenu = hSysMenu; + nPos = cmd; + if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND)) + { + SendMessageA(hWnd, WM_INITMENU, (WPARAM)hSysMenu, 0L); + if(hSubMenu != hSysMenu) + { + nPos = MENU_FindSubMenu(&hSysMenu, hSubMenu); + TRACE_(accel)("hSysMenu = %04x, hSubMenu = %04x, nPos = %d\n", hSysMenu, hSubMenu, nPos); + SendMessageA(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, TRUE)); + } + uSysStat = GetMenuState(GetSubMenu(hSysMenu, 0), cmd, MF_BYCOMMAND); + } + else /* 2. in the window's menu */ + { + hSubMenu = hMenu; + nPos = cmd; + if(MENU_FindItem(&hSubMenu, &nPos, MF_BYCOMMAND)) + { + SendMessageA(hWnd, WM_INITMENU, (WPARAM)hMenu, 0L); + if(hSubMenu != hMenu) + { + nPos = MENU_FindSubMenu(&hMenu, hSubMenu); + TRACE_(accel)("hMenu = %04x, hSubMenu = %04x, nPos = %d\n", hMenu, hSubMenu, nPos); + SendMessageA(hWnd, WM_INITMENUPOPUP, (WPARAM)hSubMenu, MAKELPARAM(nPos, FALSE)); + } + uStat = GetMenuState(hMenu, cmd, MF_BYCOMMAND); + } + } + + if (uSysStat != (UINT)-1) + { + if (uSysStat & (MF_DISABLED|MF_GRAYED)) + mesg=4; + else + mesg=WM_SYSCOMMAND; + } + else + { + if (uStat != (UINT)-1) + { + if (IsIconic(hWnd)) + mesg=5; + else + { + if (uStat & (MF_DISABLED|MF_GRAYED)) + mesg=6; + else + mesg=WM_COMMAND; + } + } + else + mesg=WM_COMMAND; + } + } + + if( mesg==WM_COMMAND ) + { + TRACE_(accel)(", sending WM_COMMAND, wParam=%0x\n", 0x10000 | cmd); + SendMessageA(hWnd, mesg, 0x10000 | cmd, 0L); + } + else if( mesg==WM_SYSCOMMAND ) + { + TRACE_(accel)(", sending WM_SYSCOMMAND, wParam=%0x\n", cmd); + SendMessageA(hWnd, mesg, cmd, 0x00010000L); + } + else + { + /* some reasons for NOT sending the WM_{SYS}COMMAND message: + * #0: unknown (please report!) + * #1: for WM_KEYUP,WM_SYSKEYUP + * #2: mouse is captured + * #3: window is disabled + * #4: it's a disabled system menu option + * #5: it's a menu option, but window is iconic + * #6: it's a menu option, but disabled + */ + TRACE_(accel)(", but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg); + if(mesg==0) + ERR_(accel)(" unknown reason - please report!"); + } + return TRUE; +} + +/********************************************************************** + * TranslateAccelerator (USER32.551)(USER32.552)(USER32.553) + */ +INT WINAPI TranslateAccelerator( HWND hWnd, HACCEL hAccel, LPMSG msg ) +{ + /* YES, Accel16! */ + LPACCEL16 lpAccelTbl; + int i; + + if (msg == NULL) + { + WARN_(accel)("msg null; should hang here to be win compatible\n"); + return 0; + } + if (!hAccel || !(lpAccelTbl = (LPACCEL16) LockResource16(hAccel))) + { + WARN_(accel)("invalid accel handle=%x\n", hAccel); + return 0; + } + if ((msg->message != WM_KEYDOWN && + msg->message != WM_KEYUP && + msg->message != WM_SYSKEYDOWN && + msg->message != WM_SYSKEYUP && + msg->message != WM_CHAR)) return 0; + + TRACE_(accel)("TranslateAccelerators hAccel=%04x, hWnd=%04x," + "msg->hwnd=%04x, msg->message=%04x, wParam=%08x, lParam=%lx\n", + hAccel,hWnd,msg->hwnd,msg->message,msg->wParam,msg->lParam); + + i = 0; + do + { + 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); + WARN_(accel)("couldn't translate accelerator key\n"); + return 0; +} + + +/********************************************************************** + * TranslateAccelerator16 (USER.178) + */ +INT16 WINAPI TranslateAccelerator16( HWND16 hWnd, HACCEL16 hAccel, LPMSG16 msg ) +{ + LPACCEL16 lpAccelTbl; + int i; + + if (msg == NULL) + { + WARN_(accel)("msg null; should hang here to be win compatible\n"); + return 0; + } + if (!hAccel || !(lpAccelTbl = (LPACCEL16) LockResource16(hAccel))) + { + WARN_(accel)("invalid accel handle=%x\n", hAccel); + return 0; + } + if ((msg->message != WM_KEYDOWN && + msg->message != WM_KEYUP && + msg->message != WM_SYSKEYDOWN && + msg->message != WM_SYSKEYUP && + msg->message != WM_CHAR)) return 0; + + TRACE_(accel)("TranslateAccelerators hAccel=%04x, hWnd=%04x," + "msg->hwnd=%04x, msg->message=%04x, wParam=%04x, lParam=%lx\n", + hAccel,hWnd,msg->hwnd,msg->message,msg->wParam,msg->lParam); + + i = 0; + do + { + 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); + WARN_(accel)("couldn't translate accelerator key\n"); + return 0; +} diff --git a/windows/input.c b/windows/input.c index 0c242738a67..c33a690f81d 100644 --- a/windows/input.c +++ b/windows/input.c @@ -31,11 +31,9 @@ #include "queue.h" #include "module.h" #include "debugtools.h" -#include "struct32.h" #include "winerror.h" #include "task.h" -DECLARE_DEBUG_CHANNEL(accel); DECLARE_DEBUG_CHANNEL(event); DECLARE_DEBUG_CHANNEL(key); DECLARE_DEBUG_CHANNEL(keyboard); @@ -623,211 +621,6 @@ BOOL16 WINAPI IsUserIdle16(void) } /********************************************************************** - * KBD_translate_accelerator - * - * FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP -messages - */ -static BOOL KBD_translate_accelerator(HWND hWnd,LPMSG msg, - BYTE fVirt,WORD key,WORD cmd) -{ - BOOL sendmsg = FALSE; - - if(msg->wParam == key) - { - if (msg->message == WM_CHAR) { - if ( !(fVirt & FALT) && !(fVirt & FVIRTKEY) ) - { - TRACE_(accel)("found accel for WM_CHAR: ('%c')\n", - msg->wParam&0xff); - sendmsg=TRUE; - } - } else { - if(fVirt & FVIRTKEY) { - INT mask = 0; - TRACE_(accel)("found accel for virt_key %04x (scan %04x)\n", - msg->wParam,0xff & HIWORD(msg->lParam)); - if(GetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT; - if(GetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL; - if(GetKeyState(VK_MENU) & 0x8000) mask |= FALT; - if(mask == (fVirt & (FSHIFT | FCONTROL | FALT))) - sendmsg=TRUE; - else - TRACE_(accel)(", but incorrect SHIFT/CTRL/ALT-state\n"); - } - else - { - if (!(msg->lParam & 0x01000000)) /* no special_key */ - { - if ((fVirt & FALT) && (msg->lParam & 0x20000000)) - { /* ^^ ALT pressed */ - TRACE_(accel)("found accel for Alt-%c\n", msg->wParam&0xff); - sendmsg=TRUE; - } - } - } - } - - if (sendmsg) /* found an accelerator, but send a message... ? */ - { - INT16 iSysStat,iStat,mesg=0; - HMENU16 hMenu; - - if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP) - mesg=1; - else - if (GetCapture()) - mesg=2; - else - if (!IsWindowEnabled(hWnd)) - mesg=3; - else - { - WND* wndPtr = WIN_FindWndPtr(hWnd); - - hMenu = (wndPtr->dwStyle & WS_CHILD) ? 0 : (HMENU)wndPtr->wIDmenu; - iSysStat = (wndPtr->hSysMenu) ? GetMenuState(GetSubMenu16(wndPtr->hSysMenu, 0), - cmd, MF_BYCOMMAND) : -1 ; - iStat = (hMenu) ? GetMenuState(hMenu, - cmd, MF_BYCOMMAND) : -1 ; - - WIN_ReleaseWndPtr(wndPtr); - - if (iSysStat!=-1) - { - if (iSysStat & (MF_DISABLED|MF_GRAYED)) - mesg=4; - else - mesg=WM_SYSCOMMAND; - } - else - { - if (iStat!=-1) - { - if (IsIconic(hWnd)) - mesg=5; - else - { - if (iStat & (MF_DISABLED|MF_GRAYED)) - mesg=6; - else - mesg=WM_COMMAND; - } - } - else - mesg=WM_COMMAND; - } - } - if( mesg==WM_COMMAND ) { - TRACE_(accel)(", sending WM_COMMAND, wParam=%0x\n", 0x10000 | cmd); - SendMessageA(hWnd, mesg, 0x10000 | cmd, 0L); - } else if( mesg==WM_SYSCOMMAND ) { - TRACE_(accel)(", sending WM_SYSCOMMAND, wParam=%0x\n", cmd); - SendMessageA(hWnd, mesg, cmd, 0x00010000L); - } - else - { - /* some reasons for NOT sending the WM_{SYS}COMMAND message: - * #0: unknown (please report!) - * #1: for WM_KEYUP,WM_SYSKEYUP - * #2: mouse is captured - * #3: window is disabled - * #4: it's a disabled system menu option - * #5: it's a menu option, but window is iconic - * #6: it's a menu option, but disabled - */ - TRACE_(accel)(", but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg); - if(mesg==0) - ERR_(accel)(" unknown reason - please report!"); - } - return TRUE; - } - } - return FALSE; -} - -/********************************************************************** - * TranslateAccelerator (USER32.551)(USER32.552)(USER32.553) - */ -INT WINAPI TranslateAccelerator(HWND hWnd, HACCEL hAccel, LPMSG msg) -{ - /* YES, Accel16! */ - LPACCEL16 lpAccelTbl; - int i; - - if (msg == NULL) - { - WARN_(accel)("msg null; should hang here to be win compatible\n"); - return 0; - } - if (!hAccel || !(lpAccelTbl = (LPACCEL16) LockResource16(hAccel))) - { - WARN_(accel)("invalid accel handle=%x\n", hAccel); - return 0; - } - if ((msg->message != WM_KEYDOWN && - msg->message != WM_KEYUP && - msg->message != WM_SYSKEYDOWN && - msg->message != WM_SYSKEYUP && - msg->message != WM_CHAR)) return 0; - - TRACE_(accel)("TranslateAccelerators hAccel=%04x, hWnd=%04x," - "msg->hwnd=%04x, msg->message=%04x, wParam=%08x, lParam=%lx\n", - hAccel,hWnd,msg->hwnd,msg->message,msg->wParam,msg->lParam); - - i = 0; - do - { - if (KBD_translate_accelerator(hWnd,msg,lpAccelTbl[i].fVirt, - lpAccelTbl[i].key,lpAccelTbl[i].cmd)) - return 1; - } while ((lpAccelTbl[i++].fVirt & 0x80) == 0); - WARN_(accel)("couldn't translate accelerator key\n"); - return 0; -} - -/********************************************************************** - * TranslateAccelerator16 (USER.178) - */ -INT16 WINAPI TranslateAccelerator16(HWND16 hWnd, HACCEL16 hAccel, LPMSG16 msg) -{ - LPACCEL16 lpAccelTbl; - int i; - MSG msg32; - - if (msg == NULL) - { - WARN_(accel)("msg null; should hang here to be win compatible\n"); - return 0; - } - if (!hAccel || !(lpAccelTbl = (LPACCEL16) LockResource16(hAccel))) - { - WARN_(accel)("invalid accel handle=%x\n", hAccel); - return 0; - } - if ((msg->message != WM_KEYDOWN && - msg->message != WM_KEYUP && - msg->message != WM_SYSKEYDOWN && - msg->message != WM_SYSKEYUP && - msg->message != WM_CHAR)) return 0; - - TRACE_(accel)("TranslateAccelerators hAccel=%04x, hWnd=%04x,\ -msg->hwnd=%04x, msg->message=%04x, wParam=%04x, lParam=%lx\n", hAccel,hWnd,msg->hwnd,msg->message,msg->wParam,msg->lParam); - - STRUCT32_MSG16to32(msg,&msg32); - - i = 0; - do - { - if (KBD_translate_accelerator(hWnd,&msg32,lpAccelTbl[i].fVirt, - lpAccelTbl[i].key,lpAccelTbl[i].cmd)) - return 1; - } while ((lpAccelTbl[i++].fVirt & 0x80) == 0); - WARN_(accel)("couldn't translate accelerator key\n"); - return 0; -} - - -/********************************************************************** * VkKeyScanA (USER32.573) */ WORD WINAPI VkKeyScanA(CHAR cChar) -- 2.11.4.GIT