PRB: Mnemonic Differences Between MFC 4.0 and Visual Basic 4.0Last reviewed: July 31, 1997Article ID: Q145698 |
The information in this article applies to:
SYMPTOMSAn accelerator table provided by way of COleControl::OnGetControlInfo that describes an OLE control's mnemonic keys does not work in both MFC 4.0 and Visual Basic 4.0 OLE control containers.
CAUSEVisual Basic 4.0 and MFC 4.0 provide different mnemonic handling implementations, so they require different accelerator table entries.
RESOLUTIONCreate accelerator table entries that will allow a control's mnemonics to be handled in both a Visual Basic 4.0 and MFC 4.0 OLE control container.
STATUSThis behavior is by design.
MORE INFORMATIONAn OLE control overrides the virtual COleControl::OnGetControlInfo method to allow its container to get a description of the control's mnemonic keys. The OnGetControlInfo method returns a filled-out structure of type CONTROLINFO that contains, among other things, a handle to an accelerator table. This accelerator table is used by the container to do checks for mnemonic keys. When the container determines that a control's mnemonic key was pressed, it calls the control's IOleControl::OnMnemonic method. This causes the MFC framework to call the virtual COleControl::OnMnemonic method, which the control can override to do special processing. The Visual Basic 4.0 and MFC 4.0 OLE control mnemonic handling implementations have different requirements for the entries in the accelerator table returned by way of OnGetControlInfo. An accelerator key used in an accelerator table is defined by the ACCEL structure. The ACCEL structure has the following definition:
typedef struct tagACCEL { BYTE fVirt; WORD key; WORD cmd; } ACCEL;The fVirt member specifies the accelerator flags. This member can be a combination of the following values:
Value Meaning --------------------------------------------------------------------- FALT The ALT key must be held down when the accelerator key is pressed. FCONTROL The CTRL key must be held down when the accelerator key is pressed. FNOINVERT Specifies that no top-level menu item is highlighted when the accelerator is used. If this flag is not specified, a top-level menu item will be highlighted, if possible, when the accelerator is used. FSHIFT The SHIFT key must be held down when the accelerator key is pressed. FVIRTKEY The key member specifies a virtual-key code. If this flag is not specified, key is assumed to specify an ASCII character code.The key member specifies the accelerator key. This member can be either a virtual-key code or an ASCII character code. The cmd member specifies the accelerator identifier. This value is placed in the low-order word of the wParam parameter of the WM_COMMAND or WM_SYSCOMMAND message when the accelerator is pressed. Visual Basic 4.0 has the following requirements for accelerator table entries used for mnemonic handling:
NOTE: Overriding PreTranslateMessage is not necessary if the control is generated with Visual C++ 5.0 because OnMnemonic will be called when the control is UI active. The following sample code shows an overridden OnGetControlInfo, PreTranslateMessage, and OnMnemonic that allow a control's mnemonics to work correctly in both an MFC 4.0 OLE control container as well as a Visual Basic 4.0 container.
Sample Code
/* Compile options needed: None */ #define NUM_ENTRIES 4 void CMnemonicCtrl::OnGetControlInfo(LPCONTROLINFO lpi){ HACCEL hAccel = NULL; TCHAR ch = 'm'; // Hard code the mnemonic key to 'm' for this // example. ACCEL accKey[NUM_ENTRIES]; // Accel table entries 0 and 1 are to work with Visual Basic 4.0 as a // container. Visual Basic 4.0 has the following requirements for // accel table entries for a control's mnemonics: // // (fVirt == FVIRTKEY | FALT) || (fVirt == FVIRTKEY | FALT | FSHIFT) // key must be uppercase // (cmd != 0) accKey[0].fVirt = FVIRTKEY | FALT; accKey[1].fVirt = FVIRTKEY | FALT | FSHIFT; accKey[0].key = accKey[1].key = LOBYTE(VkKeyScan(ch)); accKey[0].cmd = accKey[1].cmd = 1; // Accel table entries 2 and 3 are to work with MFC 4.0 containers. // MFC containers have the following requirements for accel table // entries for a control's mnemonics: // // (fVirt == FALT) || (fVirt == 0) // key should be lowercase // cmd is ignored accKey[2].fVirt = FALT; accKey[3].fVirt = 0; accKey[2].key = accKey[3].key = ch; accKey[2].cmd = accKey[3].cmd = 1; // Create the accel table. hAccel = CreateAcceleratorTable(accKey, NUM_ENTRIES); if (hAccel != NULL) { // Fill in the CONTROLINFO structure passed in. lpi -> hAccel = hAccel; lpi -> cAccel = NUM_ENTRIES; lpi -> dwFlags = 0; } else COleControl::OnGetControlInfo(lpi);}
// NO need to override PreTranslateMessage if the control is generated in // Visual C++ 5.00.BOOL CMnemonicCtrl::PreTranslateMessage( MSG * pMsg ) { // Check for ALT-M key combination. if(pMsg->message == WM_SYSKEYDOWN) { if((pMsg->wParam == 'm')||(pMsg->wParam == 'M')) { // Do mnemonic key processing here. return TRUE; } } return COleControl::PreTranslateMessage(pMsg);}
void CMnemonicCtrl::OnMnemonic(LPMSG pMsg){ if ((pMsg->message == WM_SYSKEYDOWN)|| (pMsg->message == WM_SYSCHAR)) { if ((pMsg->wParam == 'm')||(pMsg->wParam == 'M')) { // Do mnemonic key processing here. return; } } COleControl::OnMnemonic(pMsg);} Keywords : MfcOLE kbcode kbprb Technology : kbMfc Version : 1.5 1.51 1.52 2.0 2.1. 2.2 4.0 Platform : NT WINDOWS |
================================================================================
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |