Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS General Discussion » CExtResizableDialog & OnOK() Collapse All
Subject Author Date
Leon Miller Nov 2, 2005 - 9:46 PM

My app is MDI, MainFrame is CMDIFrameWnd. My question is: I have a dialog box class CMyDialog derived from CExtResizableDialog, created as a child of CExtControlBar which is docked to the mainframe. The dialog box contains a CExtComboBox. When the user presses the return/enter key while the CExtComboBox has the focus CMyDialog::OnOK() is not called. If I derive CMyDialog from CDialog, CMyDialog::OnOk() gets called when the user presses the return/enter key!! CMyDialog::OnOK() gets called in both cases when the ’OK’ button is pressed.

Technical Support Nov 14, 2005 - 3:32 AM

Thank you for the bug information. It deals with the message pre-translation in Prof-UIS. Please update the source code for the CExtControlBar::PreTranslateMessage() method:

BOOL CExtControlBar::PreTranslateMessage(MSG* pMsg) 
{
    ASSERT_VALID(this);
    ASSERT(m_hWnd != NULL);
    if( CWnd::PreTranslateMessage(pMsg) )
        return TRUE;
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
CWnd * pWndParent = GetParent();
    if(        pWndParent->GetSafeHwnd() != NULL
        &&    pWndParent->IsKindOf( RUNTIME_CLASS(CExtDockDynBar) )
        &&    pWndParent->PreTranslateMessage(pMsg)
        )
        return TRUE;
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
    if(        (m_nFlags&WF_OLECTLCONTAINER) != NULL
        &&    WM_KEYFIRST <= pMsg->message
        &&    pMsg->message <= WM_KEYLAST
        )
    { // analyze OLE keyboard message translation
        HWND hWndFocus = ::GetFocus();
        if(        hWndFocus != NULL
            &&    ::IsChild( m_hWnd, hWndFocus )
            )
        { // if focus is inside
            HWND hWndOwn = m_hWnd;
            HWND hWnd = hWndFocus;
            for( ; hWnd != NULL && hWnd != hWndOwn; hWnd = ::GetParent(hWnd) )
            {
                if( ! ::IsWindow(hWndOwn) )
                    return FALSE;
                CWnd * pWnd = CWnd::FromHandlePermanent( hWnd );
                if( pWnd == NULL )
                    continue;
                LPUNKNOWN pUnknown = pWnd->GetControlUnknown();
                if( pUnknown != NULL )
                {
                    if( pWnd->PreTranslateMessage( pMsg ) )
                        return TRUE;
                    IOleInPlaceActiveObject * pOleInPlaceActiveObject = NULL;
                    HRESULT hr =
                        pUnknown->QueryInterface(
                            __uuidof(IOleInPlaceActiveObject),
                            (LPVOID*)(&pOleInPlaceActiveObject)
                            );
                    if( hr == S_OK )
                    {
                        ASSERT( pOleInPlaceActiveObject != NULL );
                        hr =
                            pOleInPlaceActiveObject->TranslateAccelerator(
                                pMsg
                                );
                        pOleInPlaceActiveObject->Release();
                        if( hr == S_OK )
                            return TRUE;
                    } // if( hr == S_OK )
                } // if( pUnknown != NULL )
            } // for( ; hWnd != NULL && hWnd != hWndOwn; hWnd = ::GetParent(hWnd) )
        } // if focus is inside
    } // analyze OLE keyboard message translation
CWnd * pOwner = GetOwner();
#if _MFC_VER < 0x700
UINT message = pMsg->message;
    if(    (    (        m_dwStyle & CBRS_FLYBY)
                ||    message == WM_LBUTTONDOWN
                ||    message == WM_LBUTTONUP
                )
            &&
            (    (        message >= WM_MOUSEFIRST
                    &&    message <= WM_MOUSELAST
                    ) ||
                    (    message >= WM_NCMOUSEFIRST
                    && message <= WM_NCMOUSELAST
                )
            )
            &&
            (    (!        CExtToolControlBar::g_bMenuTracking
                    ||    CExtPopupMenuWnd::IsMenuTracking()
                )
            )
         )
    {
        _AFX_THREAD_STATE * pThreadState =
            ::AfxGetThreadState();
        CPoint point = pMsg->pt;
        ScreenToClient( &point );
        TOOLINFO _ti;
        ::memset( &_ti, 0, sizeof(TOOLINFO) );
        _ti.cbSize = sizeof(AFX_OLDTOOLINFO);
        int nHit = OnToolHitTest( point, &_ti );
        if(        _ti.lpszText != NULL
            &&    _ti.lpszText != LPSTR_TEXTCALLBACK
            )
            free( _ti.lpszText );
        BOOL bNotButton =
            message == WM_LBUTTONDOWN && (_ti.uFlags & TTF_NOTBUTTON);
        if (message != WM_LBUTTONDOWN && GetKeyState(VK_LBUTTON) < 0)
            nHit = pThreadState->m_nLastStatus;
        if (nHit < 0 || bNotButton)
        {
            if (GetKeyState(VK_LBUTTON) >= 0 || bNotButton)
            {
                SetStatusText(-1);
                KillTimer(ID_TIMER_CHECK);
            }
        }
        else
        {
            if (message == WM_LBUTTONUP)
            {
                SetStatusText(-1);
                ResetTimer(ID_TIMER_CHECK, 200);
            }
            else
            {
                if ((m_nStateFlags & statusSet) || GetKeyState(VK_LBUTTON) < 0)
                    SetStatusText(nHit);
                else if (nHit != pThreadState->m_nLastStatus)
                    ResetTimer(ID_TIMER_WAIT, 300);
            }
        }
        pThreadState->m_nLastStatus = nHit;
    }
#endif
CFrameWnd* pFrameWnd = GetTopLevelFrame();
    if( pFrameWnd != NULL && pFrameWnd->m_bHelpMode )
        return FALSE;
    if( ! m_bPresubclassDialogMode )
    {
        while( pOwner != NULL )
        {
            HWND hWndOwner = pOwner->GetSafeHwnd();
            ASSERT( hWndOwner != NULL );
            if( !::IsWindow(hWndOwner) )
                break;
            if( CWnd::FromHandlePermanent(hWndOwner) == NULL )
                break;
            if (pOwner->PreTranslateMessage(pMsg))
                return TRUE;
            pOwner = pOwner->GetParentFrame();
        }
        HWND hWndChild = ::GetWindow( m_hWnd, GW_CHILD );
        if(        hWndChild != NULL
            &&    pMsg->hwnd != NULL
            &&    WM_KEYFIRST <= pMsg->message
            &&    pMsg->message <= WM_KEYLAST
            &&    ::IsChild( hWndChild, pMsg->hwnd )
            )
        {
            ::TranslateMessage( pMsg );
            ::DispatchMessage( pMsg );
            return TRUE;
        }
    } // if( !m_bPresubclassDialogMode )
    return PreTranslateInput(pMsg);
}

Leon Miller Sep 7, 2006 - 12:16 PM

Greetings,

I would like to revisit this issue with you.

When I first noticed this problem, I was using the trial version of ProfUIS (I think v2.50).
I have since purchased ProfUIS v2.54. I have found that the code from your reply matches the code in the
PreTranslateMessage method of the CExtControlBar class, yet I am still observing the bug!

I need to trap the Enter keypress when a combo box has input focus.

I have found that I can do any of the following and the OnOK() method DOES get called! (please note that
I find both of these as unacceptable solutions!)

1. Derive CMyDialog from CDialog, vice CExtResizableDialog.
2. Change the ’Style’ property of the dialog template via the VC resource editor, to either Overlapped
or Popup (vice Child) -- however, this causes the dialog to not be properly docked to the CExtControlBar!

Thanks again.

Technical Support Sep 8, 2006 - 12:04 PM

First of all, the dialog inside the resizable bar should be a child dialog and not a popup dialog. We think we should try to find this bug (if any) using a test project or a light-weight version of your project. Could you provide one of these projects?

Leon Miller Sep 8, 2006 - 1:33 PM

Yes, I realize that the dialog inside the resizable bar should be a child dialog - All I am saying is that the bug is only present when the dialog is a child, The OnOK() method does get called when you changed it to a popup. Anyway, please let me know where to send a sample project. I will put one together that demonstrates the bug I am observing. Thanks again.

Technical Support Sep 9, 2006 - 6:58 AM

Please send it to support@prof-uis.com.

Leon Miller Sep 14, 2006 - 7:29 PM

Thanks for the quick response to my sample project, I am posting the solution sent to me via email here in order to help future users encountering the same problem.

The OnOK() method is not called because of internal implementation of the PreTranslateMessage method in CExtResizableDialog. To get it work, please override this method in the following way:

BOOL CTestDlg::PreTranslateMessage(MSG* pMsg)
{
if( WM_KEYFIRST <= pMsg->message
&& pMsg->message <= WM_KEYLAST
&& pMsg->wParam == VK_RETURN
)
return CDialog::PreTranslateMessage(pMsg);
return CExtResizableDialog::PreTranslateMessage(pMsg);
}

This method works great! Thanks! - I have also noticed that if I apply the CProfStudioThinFrame class to the dialog inside the CExtControlBar, the OnOK() method gets called without using the above method. So this looks like a viable solution for me also.

Thanks again!