Monday, March 26, 2012

if edit control has focus, menus periodically freeze message loop

This bug was introduced in V2. FFRend 1.7.3 doesn't exhibit the bug, and the earliest version of V2 (FFRell 1.0.0.1a) does. The cause is a porting error: the following bug fix from version 1.0.3 wasn't ported into V2:
28oct06    add ProcessMessageFilter to fix edit box/menu pauses
ToDo: if an edit control has focus, menus cause periodic pauses in message loop

BOOL CFFRendApp::ProcessMessageFilter(int code, LPMSG lpMsg) 
{
    // If a menu is displayed while an edit control has focus, the message loop
    // pauses periodically until the menu is closed; this applies to all menus,
    // including context and system menus, and it's a problem for timer-driven
    // apps that use edit controls.  The problem is caused by the undocumented
    // WM_SYSTIMER message (0x118), which Windows uses internally for various
    // purposes including scrolling and blinking the caret in an edit control.
    // The solution is to suppress WM_SYSTIMER, but only if the filter code is
    // MSGF_MENU, otherwise the caret won't blink while scrolling.  The caret
    // doesn't blink while a menu is displayed even without this workaround.
    //
    // if displaying a menu and message is WM_SYSTIMER
    if (code == MSGF_MENU && lpMsg->message == 0x118) {
        // use GetClassName because IsKindOf fails if the edit control doesn't
        // have a CEdit instance; see Microsoft knowledge base article Q145616
        TCHAR    szClassName[6];
        if (GetClassName(lpMsg->hwnd, szClassName, 6)
        && !_tcsicmp(szClassName, _T("Edit"))) {    // if recipient is an edit control
            return TRUE;    // suppress WM_SYSTIMER
        }
    }
    return CWinApp::ProcessMessageFilter(code, lpMsg);
}

No comments: