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 Tech Support » crashes in CExtPopupMenuWnd Collapse All
Subject Author Date
Andreas Spachtholz May 5, 2011 - 4:10 AM

Hi, we had several strange crashes in our application, and now we could reproduce them. And at least some of them are related to crashes in CExtPopupMenuWnd. Sometimes it happens, that by calling the function 

CExtPaintManager



::stat_PassPaintMessages();


the destructor of the object is called, and when comming back, the application crashes.

The destructur is call due to a NCDestroy windows message.


The easiest way to reproduce it, is to set breakpoints in the file CExtPopupMenuWnd.cpp in the function


 



BOOL


 


.....


here--->  SetWindowPos(CWnd::wndTopMost, 0, 0, 0, 0,SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZESWP_SHOWWINDOW|SWP_NOZORDERif( bFadeOut || bForceLayered )ASSERT( g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL );CExtPaintManager::stat_PassPaintMessages();g_PaintManager.m_pfnSetLayeredWindowAttributes( m_hWnd, 0, 255, __EXT_MFC_LWA_ALPHA );// if( bFadeOut )else if( ! g_PaintManager.m_bIsWin2000orLater )CExtPaintManager::stat_PassPaintMessages();here--->  ASSERT( IsWindowVisible() );if( ! _FindCustomizeMode() )_SetCapture(); (!defined __EXT_MFC_NO_CUSTOMIZE)elseCExtCustomizeSite * pSite = _FindCustomizeSite();ASSERT( pSite != NULL );pSite->RegisterCommandDropTarget( this, this ); // (!defined __EXT_MFC_NO_CUSTOMIZE)if( m_bTopLevel && (! m_bExpandWasPressed ) && m_bExpandAvailable && g_nAutoExpandTime > 0 )SetTimer( ID_TIMER_AUTO_EXPAND, g_nAutoExpandTime, NULL );return TRUE;


 


&


 


 


|


 


);


 


{


 


 


 


}


 


 


 


 


 


{


 


}


 


#if


 


 


{


 


 


 


}


 


#endif


 


 


 


 


}


 


Due to the debugger, the window looses the focus and it will be destroyed. Unfortunately this also can happen sometimes during a normal run of the application.


 


Any solution for this issue?


 


Thanks


BR,


Andreas


CExtPopupMenuWnd::_TrackPopupMenu 

Technical Support May 10, 2011 - 4:53 AM

The crash occurs because application execution is paused and this lets you activate and focus different windows on the desktop. The code being debugged does not expect this. This is normal situation. The crash will never occur in normal execution mode.

If your app uses some thread wide hooks, the hook handlers can be invoked before the assertion line in popup menu code. If the hook handler displays some modal dialog boxes, the popup menu code generates an assertion failure and crashes. We confirm this. But the solution is: do not to perform heavy user interaction in hook handlers. Hooks must do some work as fast as possible and return execution control.

If the assertion line brings problems, we can comment it. It will not bring any problems in release build.

Andreas Spachtholz May 11, 2011 - 4:11 AM

Sorry, but we do not use threads in an unnormal way.


And the we have many of those crashes in the field. I think our customer are not really happy about that issue, because you never know when the application will disappear suddenly.


We have to find a solution for this issue!


Any idea, how we can make a workaround or a fix?


Thanks


Andreas

Technical Support May 11, 2011 - 7:24 AM

The CExtPaintManager::stat_PassPaintMessages() static method extracts the WM_NCPAINT, WM_ERASEBKGND and WM_PAINT messages and delivers them to appropriate window procedures. This should not cause destructor invocations and generate crashes in your app. Setting break point to the ASSERT( IsWindowVisible() ); line of code can generate crash in debug mode - not in release. But this is just incorrect place for setting break point. How this issue can make the release version of your app disappear?

Andreas Spachtholz May 15, 2011 - 11:54 PM

We got many crash dumps of the release version (post mortem dumps) which show us always the same call stack in the CExtPopupMenuWnd. The problem is, that during the stat_PassPaintMessages the WindowProc Funtion of the CExtPopupMenuWnd is call with all WM_... messages, not only the filtered ones. Thus if a messages (e.g. ACTIVE_APP) is received which will remove the CExtPopupMenuWnd the destructor is called and the object is deleted. Which may happen in the release version e.g. if another application popups during the call of the stat:_PassPaintMessages.


From our point of view this is a bug, and has to be fixed!


BR,


Andreas

Technical Support May 16, 2011 - 12:06 PM

The CExtPaintManager::stat_PassPaintMessages() method delivers only painting messages. This should not cause any destructor invocations, any window handle destroying or exiting your application. We suspect this is specific for your application only. So, we need to reproduce the same using Prof-UIS sample applications, any test projects or debugging your application remotely. I.e. we need your help to fix this issue.

Andreas Spachtholz May 16, 2011 - 11:21 PM

Sorry, but this is not correct.


The filter in the PeekMessage function is valid only for the result you get back from the PeekMessage function. During the PeekMessage call the hooks and WindowProc functions get ALL windows messages! And this is the problem. If an ACTIVE_APP message is in the queue, the application crashes. You can reproduce this, as I described with the ProdUIS Control Demo Application. To enforce the critical situtation set the breakpoints as described.


The breakpoints only help to construc the critical situation which will occu sometimes, e.g. we have a instant messenger which pops up for a new messages. If this happens during the stat_PAssPaintMessages, the application crashes!


I test on Windows 7 32bit and 64bit. But we also got the crash reports from XP systems.


BR,


Andreas

Christian Dangl Apr 30, 2015 - 5:32 AM

Hi,



I got to this page because we have exactly the same problem: The stat_PassPaintMessages triggers an ACTIVE_APP message which causes a deletion of the PopUpMenuWnd. Although Andreas encountered this problem 4 years ago, it is not fixed in ProfUIS 3.01! Were you able to overcome this annoying problem?


any suggestions would be appreciated


thanks,


Manuel

Technical Support May 17, 2011 - 1:31 PM

The following improved version of the CExtPopupMenuWnd::_TrackPopupMenu() method should allow your application to survive:

BOOL CExtPopupMenuWnd::_TrackPopupMenu(
    DWORD dwTrackFlags,
    int x,
    int y,
    LPCRECT lpRect,
    LPVOID pCbPaintCombinedCookie, // = NULL
    pCbPaintCombinedContent pCbPCC, // = NULL
    bool bCookieIsObject // = false
    )
{
    ///////////////////////////// dwTrackFlags |= TPMX_COMBINE_NONE|TPMX_FORCE_NO_ANIMATION|TPMX_NO_DYNAMIC_SHADOWS|TPMX_NO_SHADOWS;
    ASSERT_VALID( this );
    m_bCanceling = false;

    CExtPaintManager::stat_PassPaintMessages();

    ::GetCursorPos( &m_ptTrackInvoked );
    m_ptTrackWatched = m_ptTrackInvoked;

    if( _IsTopLevelPopup() )
        m_bHelperMouseBtnDownOnStart =
            (    IsKeyPressed( VK_LBUTTON )
            ||    IsKeyPressed( VK_RBUTTON )
            ) ? true : false;
    else
        m_bHelperMouseBtnDownOnStart = false;
    if( m_bHelperMouseBtnDownOnStart )
        ::GetCursorPos( &m_ptStartMousePos );
bool bForceExpandRarelyUsed = (dwTrackFlags&TPMX_NO_HIDE_RARELY)
        ? true : false;
    if( ! g_bMenuExpanding )
        bForceExpandRarelyUsed = true;

    ASSERT( m_hWndCmdReceiver != NULL );
    ASSERT( ::IsWindow(m_hWndCmdReceiver) );

    if( GetSafeHwnd() != NULL )
        ::DestroyWindow( m_hWnd ); // fade out animation effect

CExtPopupMenuSite & _site = GetSite();

    if(        (!_FindCustomizeMode())
        &&    (    _site.IsTopPopup(this)
            ||    GetParentMenuWnd() == NULL
            )
        )
    {
        ASSERT( m_bTopLevel );
        MsgPrepareMenuData_t _mpmEntireTree( this );
        _mpmEntireTree.SendMessage( m_hWndCmdReceiver, false );
        if( _mpmEntireTree.m_bMenuCanceled )
            return FALSE;
        if( _mpmEntireTree.m_bMenuChanged )
        {
            _SyncItems();
            _UpdateCmdUI();
        }
        ASSERT( m_bTopLevel );
//        ASSERT( _site.IsTopPopup(this) );
    }
MsgPrepareMenuData_t _mpmOneTreeLevel( this );
    _mpmOneTreeLevel.SendMessage( m_hWndCmdReceiver, true );
    if( _mpmOneTreeLevel.m_bMenuCanceled )
        return FALSE;
    if( _mpmOneTreeLevel.m_bMenuChanged )
    {
        _SyncItems();
        _UpdateCmdUI();
    }

    if( !_FindCustomizeMode() )
    { // BLOCK: update system commands
        INT iter = 0;
        for(; iter < m_items_all.GetSize(); ++iter )
        {
            MENUITEMDATA & mi = ItemGetInfo( iter );
            if( mi.IsSeparator() )
                continue;
            UINT nCmdID = mi.GetCmdID();
            if( ! CExtCmdManager::IsSystemCommand( nCmdID ) )
                continue;
            WINDOWPLACEMENT wndpl;
            ::memset(&wndpl,0,sizeof(WINDOWPLACEMENT));
            wndpl.length = sizeof(WINDOWPLACEMENT);
            VERIFY(
                ::GetWindowPlacement(
                    mi.GetCmdReceiver(),
                    &wndpl
                    )
                );
            __EXT_MFC_LONG_PTR dwWndStyle = ::__EXT_MFC_GetWindowLong( mi.GetCmdReceiver(), GWL_STYLE );
            __EXT_MFC_LONG_PTR dwWndExStyle = ::__EXT_MFC_GetWindowLong( mi.GetCmdReceiver(), GWL_EXSTYLE );
            bool bSysCmdEnabled = false;
            switch( nCmdID )
            {
            case SC_CLOSE:
                {
                    bSysCmdEnabled = true;
                    HMENU hSysMenu = ::GetSystemMenu( mi.GetCmdReceiver(), FALSE );
                    MENUITEMINFO _mii;
                    ::memset( &_mii, 0, sizeof(MENUITEMINFO) );
                    _mii.cbSize = sizeof(MENUITEMINFO);
                    _mii.fMask = MIIM_STATE;
                    if(        hSysMenu != NULL
                        &&    ::GetMenuItemInfo(
                                hSysMenu,
                                SC_CLOSE,
                                FALSE,
                                &_mii
                                )
                        )
                    {
                        if( (_mii.fState & MFS_DISABLED) != 0 )
                            bSysCmdEnabled = false;
                    } // if( hSysMenu != NULL ...
                }
            break;
            case SC_SIZE:
            case SC_MOVE:
                if(        wndpl.showCmd != SW_SHOWMINIMIZED
                    &&    wndpl.showCmd != SW_SHOWMAXIMIZED
                    &&    !g_bFullScreenMode
                    )
                    bSysCmdEnabled = true;
            break;
            case SC_MINIMIZE:
                if(        (dwWndStyle & WS_MINIMIZEBOX) != 0
                    &&    wndpl.showCmd != SW_SHOWMINIMIZED
                    )
                    bSysCmdEnabled = true;
            break;
            case SC_MAXIMIZE:
                if(        (dwWndStyle & WS_MAXIMIZEBOX) != 0
                    &&    wndpl.showCmd != SW_SHOWMAXIMIZED
                    &&    !g_bFullScreenMode
                    )
                    bSysCmdEnabled = true;
            break;
            case SC_RESTORE:
                if(        (dwWndStyle & (WS_MINIMIZEBOX|WS_MAXIMIZEBOX)) != 0
                    &&    (    wndpl.showCmd == SW_SHOWMAXIMIZED
                        ||    wndpl.showCmd == SW_SHOWMINIMIZED
                        //||wndpl.showCmd == SW_SHOWNORMAL
                        )
                    )
                    bSysCmdEnabled = true;
            break;
            case SC_CONTEXTHELP:
                if( (dwWndExStyle & WS_EX_CONTEXTHELP) != 0 )
                    bSysCmdEnabled = true;
            break;
//            case SC_NEXTWINDOW:
//            case SC_PREVWINDOW:
//            case SC_VSCROLL:
//            case SC_HSCROLL:
//            case SC_MOUSEMENU:
//            case SC_KEYMENU:
//            case SC_ARRANGE:
//            case SC_TASKLIST:
//            case SC_SCREENSAVE:
//#if(WINVER >= 0x0400)
//            case SC_DEFAULT:
//            case SC_MONITORPOWER:
//            case SC_SEPARATOR:
//#endif /* WINVER >= 0x0400 */
            case SC_HOTKEY:
            default:
                continue;
            } // switch( nCmdID )
            CExtCmdItem * pCmdItem =
                g_CmdManager->CmdGetPtr(
                    g_CmdManager->ProfileNameFromWnd( m_hWndCmdReceiver ),
                    nCmdID
                    );
            if( pCmdItem == NULL )
            {
                pCmdItem =
                    g_CmdManager->CmdAllocPtr(
                        g_CmdManager->ProfileNameFromWnd( m_hWndCmdReceiver ),
                        nCmdID
                        );
                ASSERT( pCmdItem != NULL );
            }
            pCmdItem->StateEnable( bSysCmdEnabled );
            mi.Enable( bSysCmdEnabled );
            ASSERT( CExtCmdManager::IsSystemCommand( nCmdID ) );
            HWND hWndItemCmdReceiver = mi.GetCmdReceiver();
            HMENU hSysMenu = ::GetSystemMenu( hWndItemCmdReceiver, FALSE );
            if( hSysMenu != NULL )
            {
                MENUITEMINFO _mii;
                ::memset( &_mii, 0, sizeof(MENUITEMINFO) );
                _mii.cbSize = sizeof(MENUITEMINFO);
                _mii.fMask =
                    MIIM_CHECKMARKS|MIIM_DATA|MIIM_ID|MIIM_STATE
                    |MIIM_SUBMENU|MIIM_TYPE;
                _mii.cch = __MAX_UI_ITEM_TEXT;
                CExtSafeString sMenuItemText;
                _mii.dwTypeData = sMenuItemText.GetBuffer( __MAX_UI_ITEM_TEXT );
                ASSERT( _mii.dwTypeData != NULL );
                if( _mii.dwTypeData != NULL )
                {
                    if(    ::GetMenuItemInfo(
                            hSysMenu,
                            nCmdID,
                            FALSE,
                            &_mii
                            )
                        )
                    {
                        sMenuItemText.ReleaseBuffer();
                        sMenuItemText.Replace( _T("\n"), _T("") );
                        sMenuItemText.Replace( _T("\r"), _T("") );
                        sMenuItemText.TrimLeft();
                        sMenuItemText.TrimRight();
                        if( ! sMenuItemText.IsEmpty() )
                        {
                            int nSep =
                                sMenuItemText.ReverseFind( _T(’\t’) );
                            if( nSep >= 0 )
                            {
                                int nLen = sMenuItemText.GetLength();
                                pCmdItem->m_sAccelText = sMenuItemText.Right( nLen - nSep );
                                pCmdItem->m_sAccelText.TrimLeft();
                                pCmdItem->m_sAccelText.TrimRight();
                                pCmdItem->m_sMenuText = sMenuItemText.Left( nSep );
                                pCmdItem->m_sMenuText.TrimLeft();
                                pCmdItem->m_sMenuText.TrimRight();
                            }
                            else
                            {
                                pCmdItem->m_sMenuText = sMenuItemText;
                                pCmdItem->m_sAccelText = _T("");
                            }
                            if( pCmdItem->m_nCmdID == SC_CLOSE )
                            {
                                CWnd * pWnd = CWnd::FromHandlePermanent( hWndItemCmdReceiver );
                                if(        pWnd != NULL
                                    &&    pWnd->IsKindOf( RUNTIME_CLASS(CMDIChildWnd) )
                                    )
                                    pCmdItem->m_sAccelText = _T("Ctrl+F4");
                            }
                            mi.SetPopupText( pCmdItem->m_sMenuText );
                            mi.SetAccelText( pCmdItem->m_sAccelText );
                        } // if( ! sMenuItemText.IsEmpty() )
                    }
                    else
                        sMenuItemText.ReleaseBuffer();
                } // if( _mii.dwTypeData != NULL )
                if( (_mii.fState&MFS_DEFAULT) != 0 )
                    mi.SetDefault();
            } // if( hSysMenu != NULL )
        } // for(; iter < m_items_all.end(); ++iter )
    } // BLOCK: update system commands

CWnd * pWndCmdReceiver =
        CWnd::FromHandle( m_hWndCmdReceiver );
    ASSERT_VALID( pWndCmdReceiver );
//    pWndCmdReceiver->ActivateTopParent();
//    pWndCmdReceiver->BringWindowToTop();
//    pWndCmdReceiver->SetFocus();
    
    //_site._Hook( true );

    // adjust own data
bool bOldTopLevel = m_bTopLevel;
bool bOldExpandAvailable = m_bExpandAvailable;
DWORD dwPortedTrackFlags = m_dwTrackFlags&(TPMX_PALETTE|TPMX_PALETTE_TB_BKGND);
    _Init();
    m_bTopLevel = bOldTopLevel;
    m_bExpandAvailable = bOldExpandAvailable;
    m_dwTrackFlags = dwTrackFlags | dwPortedTrackFlags;
    m_pCbPaintCombinedCookie = pCbPaintCombinedCookie;
    m_pCbPaintCombinedContent = pCbPCC;
    m_bCookieIsObject = bCookieIsObject;
    if( !m_bTopLevel )
    {
        ASSERT( m_pWndParentMenu != NULL );
        if( m_pWndParentMenu->m_bExpandWasPressed )
        {
            if( m_bExpandAvailable )
            {
                m_bExpandAvailable = false;
                m_bExpandWasPressed = true;
                _SyncItems();
            }
            else
                m_bExpandWasPressed = true;
        }
    } // if( !m_bTopLevel )
    else
    {
        if( bForceExpandRarelyUsed )
        {
            if( m_bExpandAvailable )
            {
                m_bExpandAvailable = false;
                m_bExpandWasPressed = true;
                _SyncItems();
            }
            else
                m_bExpandWasPressed = true;
        } // if( bForceExpandRarelyUsed )
        else
            _SyncItems();
    } // else from if( !m_bTopLevel )

    // adjust screen position
    m_ptTrack.x = m_ptTrackOriginal.x = x;
    m_ptTrack.y = m_ptTrackOriginal.y = y;
    if(        ( m_ptTrack.x < -32000 || m_ptTrack.y < -32000 )
        &&    (dwTrackFlags&TPMX_RIBBON_MODE) == 0
        )
    {
        if( ! ::GetCursorPos(&m_ptTrack) )
            return FALSE;
    }

    if( lpRect != NULL )
    {
        m_rcExcludeArea = *lpRect;
        m_bExcludeAreaSpec = true;
    }
    else
    {
        m_bExcludeAreaSpec = false;
        m_rcExcludeArea.left = m_ptTrack.x - __EXCLUDE_AREA_GAP_DX;
        m_rcExcludeArea.right = m_ptTrack.x + __EXCLUDE_AREA_GAP_DX;
        m_rcExcludeArea.top = m_ptTrack.y - __EXCLUDE_AREA_GAP_DY;
        m_rcExcludeArea.bottom = m_ptTrack.y + __EXCLUDE_AREA_GAP_DY;
    }

    // adjust combine with exclude area mode
    m_bCombineWithEA = false;
    if( m_bExcludeAreaSpec )
    {
        switch( (dwTrackFlags&TPMX_COMBINE_MASK) )
        {
        case TPMX_COMBINE_ANY_SUITABLE:
            m_bCombineWithEA = true;
        break;
        case TPMX_COMBINE_DEFAULT:
            m_bCombineWithEA =
                PmBridge_GetPM()->
                    IsMenuMustCombineExcludeArea(
                        bCookieIsObject
                            ? ((CObject*)pCbPaintCombinedCookie)
                            : NULL
                        );
        break;
        } // switch( (dwTrackFlags&TPMX_COMBINE_MASK) )
    } // if( m_bExcludeAreaSpec )

CSize _size = _CalcTrackSize();
bool bPointAdjusted = true;
    if( m_bExcludeAreaSpec )
    {
        bool bRTL = OnQueryLayoutRTL();
        if( bRTL && (!m_bTopLevel) )
        {
            CExtPopupMenuWnd * pTop = m_pWndParentMenu;
            for( ; pTop != NULL; pTop = pTop->GetParentMenuWnd() )
            {
                if( pTop->_IsTopLevelPopup() )
                    break;
            } // for( ; pTop != NULL; pTop = pTop->GetParentMenuWnd() )
            if( pTop != NULL )
            {
                switch( (pTop->m_dwTrackFlags & TPMX_ALIGN_MASK) )
                {
                case TPMX_TOPALIGN:
                case TPMX_BOTTOMALIGN:
                    m_dwTrackFlags &= ~(TPMX_ALIGN_MASK);
                    m_dwTrackFlags |= TPMX_RIGHTALIGN;
                break;
                } // switch( (pTop->m_dwTrackFlags & TPMX_ALIGN_MASK) )
            } // if( pTop != NULL )
        } // if( bRTL && (!m_bTopLevel) )
        switch( (m_dwTrackFlags & TPMX_ALIGN_MASK) )
        {
        case TPMX_LEFTALIGN:
            m_ptTrack.x = m_rcExcludeArea.right;
            m_ptTrack.y = m_rcExcludeArea.top;
        break;
        case TPMX_RIGHTALIGN:
            m_ptTrack.x = m_rcExcludeArea.left - _size.cx;
            m_ptTrack.y = m_rcExcludeArea.top;
        break;
        case TPMX_TOPALIGN:
            m_ptTrack.x = m_rcExcludeArea.left;
            m_ptTrack.y = m_rcExcludeArea.bottom;
        break;
        case TPMX_BOTTOMALIGN:
            m_ptTrack.x = m_rcExcludeArea.left;
            m_ptTrack.y = m_rcExcludeArea.top - _size.cy;
        break;
        default:
            bPointAdjusted = false;
        break;
        } // switch( (m_dwTrackFlags & TPMX_ALIGN_MASK) )
    } // if( m_bExcludeAreaSpec )
    if( ! bPointAdjusted )
    {
        if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_RIGHTALIGN )
            m_ptTrack.x -= _size.cx;
        else
        {
            if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_CENTERALIGN )
                m_ptTrack.x -= _size.cx/2;
        }
        if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_BOTTOMALIGN )
            m_ptTrack.y -= _size.cy;
        else
        {
            if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_VCENTERALIGN )
                m_ptTrack.y -= _size.cy/2;
        }
    } // if( !bPointAdjusted )

//#ifdef _DEBUG
bool bCreateResult =
//#endif // _DEBUG
        _CreateHelper( pWndCmdReceiver );
    //ASSERT( bCreateResult );
    if( !bCreateResult )
        return FALSE;

    if( dwTrackFlags & TPMX_SELECT_ANY )
    {
        int nItem = _GetNextItem(__NI_ANY);
        if( nItem >= 0 )
        {
            HWND hWndOwn = m_hWnd;
            _ItemFocusSet(
                nItem,
                FALSE,
                FALSE
                );
            if( ! ::IsWindow( hWndOwn ) )
                return FALSE;
        }
    }

HWND hWndOwn = m_hWnd;
    if(        (dwTrackFlags&TPMX_FORCE_NO_ANIMATION) != 0
        ||    _FindCustomizeMode()
        )
        m_AnimationType = __AT_NONE;
    else
    {
        m_AnimationType = g_DefAnimationType;
        if( CExtToolControlBar::g_bMenuTracking )
            m_AnimationType = __AT_NONE;
        m_ePlaySoundOnAnimationFinished =
            CExtSoundPlayer::__ON_MENU_POPUP_DISPLAYED;
        _StartAnimation();
        if( ! ::IsWindow( hWndOwn ) )
            return FALSE;
    } // if( _FindCustomizeMode() )
    if( m_AnimationType == __AT_NONE )
    {
        m_AnimationType = __AT_CONTENT_DISPLAY;
        m_ePlaySoundOnAnimationFinished =
            CExtSoundPlayer::__ON_MENU_POPUP_DISPLAYED;
        _StartAnimation();
        if( ! ::IsWindow( hWndOwn ) )
            return FALSE;
        ASSERT( m_AnimationType == __AT_CONTENT_DISPLAY );
    }

    if( m_rgnWnd.GetSafeHandle() != NULL )
    {
        ASSERT( m_bExcludeAreaSpec );
        ASSERT( m_bCombineWithEA );
        ASSERT( m_eCombineAlign != __CMBA_NONE );
        CRgn rgnTmp;
        VERIFY( rgnTmp.CreateRectRgn(0,0,0,0) );
        rgnTmp.CopyRgn( &m_rgnWnd );
        ASSERT( rgnTmp.GetSafeHandle() != NULL );
        VERIFY(
            SetWindowRgn(
                (HRGN)rgnTmp.Detach(),
                FALSE
                )
            );
    } // if( m_rgnWnd.GetSafeHandle() != NULL )
    if( ! g_PaintManager.m_bIsWin2000orLater )
        CExtPaintManager::stat_PassPaintMessages();
bool bFadeOut = _IsFadeOutAnimation();
bool bForceLayered = false;
    if(        (! bFadeOut)
        &&    g_PaintManager.m_bIsWin2000orLater
        &&    g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL
        &&    ( m_AnimationType == __AT_NONE || m_AnimationType == __AT_CONTENT_DISPLAY )
        //&&    ( TrackFlagsGet() & TPMX_RIBBON_RESIZING ) == 0
        )
        bForceLayered = true;
    if( bFadeOut || bForceLayered )
    {
        ASSERT( g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL );
        g_PaintManager.m_pfnSetLayeredWindowAttributes( m_hWnd, 0, 1, __EXT_MFC_LWA_ALPHA );
    } // if( bFadeOut )

    if(        g_PaintManager.m_bIsWinVistaOrLater
        &&    g_PaintManager.m_DWM.IsCompositionEnabled()
        )
    {
        CRect rcCapture;
        GetWindowRect( &rcCapture );
        HBITMAP hBmpScreenSrcAlt = CExtPaintManager::stat_GetScreenSurfacePart( rcCapture );
        if( hBmpScreenSrcAlt != NULL )
        {
            if( m_bmpScreenSrcAlt.GetSafeHandle() != NULL )
                m_bmpScreenSrcAlt.DeleteObject();
            m_bmpScreenSrcAlt.Attach( hBmpScreenSrcAlt );
        }
    }
    SetWindowPos(
        &CWnd::wndTopMost, 0, 0, 0, 0,
        SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE
            |SWP_SHOWWINDOW|SWP_NOZORDER
        );
    if( bFadeOut || bForceLayered )
    {
        ASSERT( g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL );
        CExtPaintManager::stat_PassPaintMessages();
        g_PaintManager.m_pfnSetLayeredWindowAttributes( m_hWnd,  0, 255, __EXT_MFC_LWA_ALPHA );
    } // if( bFadeOut )
    else if( ! g_PaintManager.m_bIsWin2000orLater )
        CExtPaintManager::stat_PassPaintMessages();
    if( ! ::IsWindow( hWndOwn ) )
        return FALSE;

    ASSERT( IsWindowVisible() );

    if( ! _FindCustomizeMode() )
    {
        _SetCapture();
    }
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
    else
    {
        CExtCustomizeSite * pSite = _FindCustomizeSite();
        ASSERT( pSite != NULL );
        pSite->RegisterCommandDropTarget( this, this );
    }
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)

    if( m_bTopLevel && (! m_bExpandWasPressed ) && m_bExpandAvailable && g_nAutoExpandTime > 0 )
        SetTimer( ID_TIMER_AUTO_EXPAND, g_nAutoExpandTime, NULL );

    return TRUE;
}

Technical Support May 6, 2011 - 1:32 AM

Please provide us with the following information:

1) Content copied from the Call Stack window in your Visual Studio when your app crashed and break into debugger.

2) Prof-UIS library configuration used in your app.

3) Visual Studio version.

4) Windows OS version.

Andreas Spachtholz May 6, 2011 - 1:59 AM

Hi, here is the information:


But it’s completely clear why it crashes.


You can reproduce it with the demo application ProfUI:Controls


It would be much easier to send all the stuff to an email. Do you have one where I can send the information to? Thanks.


A) set a breakpoint at the following lines


File: ExtPopupMenuWnd.cpp


CExtPopupMenuWnd::_TrackPopupMenu

at the and of the function:


( &CWnd::wndTopMost, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE |SWP_SHOWWINDOW|SWP_NOZORDER );if( bFadeOut || bForceLayered )ASSERT( g_PaintManager.m_pfnSetLayeredWindowAttributes != NULL );CExtPaintManager::stat_PassPaintMessages();g_PaintManager.m_pfnSetLayeredWindowAttributes( m_hWnd, 0, 255, __EXT_MFC_LWA_ALPHA );// if( bFadeOut ) else if( ! g_PaintManager.m_bIsWin2000orLater )CExtPaintManager::stat_PassPaintMessages();-->>>>HERE ASSERT( IsWindowVisible() );return TRUE;

  B) Start the application


C) Open a Menu


D) The compiler breaks at the first breakpoint - CLICK into the compiler so that the ProfUIS_Control application looses the focus


E) Continue debugging


F) you get the assertion, continue and CRASH!


  


 


 Here the information you asked for:


1)


> mfc100d.dll!CWnd::IsWindowVisible()  Line 160 + 0x2d bytes C++

  ProfUIS290nd.dll!CExtPopupMenuWnd::_TrackPopupMenu(unsigned long dwTrackFlags, int x, int y, const tagRECT * lpRect, void * pCbPaintCombinedCookie, void (void *, CDC &, const CWnd &, const CRect &, int)* pCbPCC, bool bCookieIsObject)  Line 11515 + 0x8 bytes C++

  ProfUIS290nd.dll!CExtPopupMenuWnd::TrackPopupMenu(unsigned long dwTrackFlags, int x, int y, const tagRECT * lpRect, void * pCbPaintCombinedCookie, void (void *, CDC &, const CWnd &, const CRect &, int)* pCbPCC, unsigned int * lpnResultCmdID, bool bCookieIsObject)  Line 10393 + 0x2f bytes C++

  ProfUIS290nd.dll!CExtBarButton::OnTrackPopup(CPoint point, bool bSelectAny, bool bForceNoAnimation)  Line 4150 + 0x42 bytes C++

  ProfUIS290nd.dll!CExtBarButton::OnClick(CPoint point, bool bDown)  Line 4336 + 0x1e bytes C++

  ProfUIS290nd.dll!CExtToolControlBar::OnLButtonDown(unsigned int nFlags, CPoint point)  Line 11457 + 0x1c bytes C++

  ProfUIS290nd.dll!CExtMenuControlBar::OnLButtonDown(unsigned int nFlags, CPoint point)  Line 3279 C++

  mfc100d.dll!CWnd::OnWndMsg(unsigned int message, unsigned int wParam, long lParam, long * pResult)  Line 2495 C++

  mfc100d.dll!CWnd::WindowProc(unsigned int message, unsigned int wParam, long lParam)  Line 2067 + 0x20 bytes C++

  mfc100d.dll!CControlBar::WindowProc(unsigned int nMsg, unsigned int wParam, long lParam)  Line 506 + 0x14 bytes C++

  ProfUIS290nd.dll!CExtControlBar::WindowProc(unsigned int message, unsigned int wParam, long lParam)  Line 8686 C++

  ProfUIS290nd.dll!CExtToolControlBar::WindowProc(unsigned int message, unsigned int wParam, long lParam)  Line 13400 C++

  mfc100d.dll!AfxCallWndProc(CWnd * pWnd, HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam)  Line 248 + 0x1c bytes C++

  mfc100d.dll!AfxWndProc(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam)  Line 411 C++

  mfc100d.dll!AfxWndProcBase(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam)  Line 420 + 0x15 bytes C++

  user32.dll!_InternalCallWinProc@20()  + 0x23 bytes 

  user32.dll!_UserCallWinProcCheckWow@32()  + 0xb7 bytes 

  user32.dll!_DispatchMessageWorker@8()  + 0xed bytes 

  user32.dll!_DispatchMessageA@4()  + 0xf bytes 

  mfc100d.dll!AfxInternalPumpMessage()  Line 183 C++

  mfc100d.dll!CWinThread::PumpMessage()  Line 900 C++

  mfc100d.dll!CWinThread::Run()  Line 629 + 0xd bytes C++

  mfc100d.dll!CWinApp::Run()  Line 822 C++

  Romesd.exe!CRomesApp::Run()  Line 1005 + 0x8 bytes C++

  mfc100d.dll!AfxWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow)  Line 47 + 0xd bytes C++

  Romesd.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow)  Line 26 C++

  Romesd.exe!__tmainCRTStartup()  Line 547 + 0x2c bytes C

  Romesd.exe!WinMainCRTStartup()  Line 371 C

  kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes 

  ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes 

  ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes 


2) MFC ANSI , ProfUIS 2.90


3) 2010


4) It happens on XP and Windows 7


Function: 



->>>>>HERE SetWindowPos


 


{


 


 


 


}


 


 


 


 


 


}


Technical Support May 6, 2011 - 11:29 AM

This is not a bug. You just came across the code which cannot be debugged using breakpoints. The ASSERT( IsWindowVisible() ) generates an assertion failure because Visual Studio window covers the menu window.

Andreas Spachtholz May 9, 2011 - 4:38 AM

This is clear. The assertion is not the problem, but after the assertion a crash occurs!


And this crash can and does occur also during the release version.


If for any reason the user clicks at the wrong moment into another applation the ProfUIS application crashes.


For sure, this doesn’t occur very often, but it does occur, and we think, that crashes must not happen at all.


And if you read my explainations, it’s quite clear why it crashes.


So we really would appreciate, if you could fix this problem.


Thanks


BR,


Andreas

Andreas Spachtholz May 5, 2011 - 5:37 AM

Hi, the problem is the following loop.


During the PeekMessage function, the WindowsProc Function of the PopupWindow is called with ALL messages, not just the PAINT messages. If it get an ACTIVE_APP messages, the crash occurs.


How to fix with problem?


BR,


Andreas


LONG CExtPaintManager::stat_PassPaintMessages(HWND hWnd,bool bPassNcPaint, // = truebool bPassEraseBkgnd, // = truebool bPassPaint // = true nCountPassed = 0L; msg;if( bPassNcPaint )while( ::PeekMessage( &msg, hWnd, WM_NCPAINT, WM_NCPAINT, PM_NOREMOVE ) )if( ! ::PeekMessage( &msg, hWnd, WM_NCPAINT, WM_NCPAINT, PM_REMOVE ) )break;DispatchMessage( &msg );nCountPassed ++;// while( ::PeekMessage( &msg, NULL, WM_NCPAINT, WM_NCPAINT, PM_NOREMOVE ) )// if( bPassNcPaint )if( bPassEraseBkgnd )while( ::PeekMessage( &msg, hWnd, WM_ERASEBKGND, WM_ERASEBKGND, PM_NOREMOVE ) )if( ! ::PeekMessage( &msg, hWnd, WM_ERASEBKGND, WM_ERASEBKGND, PM_REMOVE ) )break;DispatchMessage( &msg );nCountPassed ++;// while( ::PeekMessage( &msg, NULL, WM_ERASEBKGND, WM_ERASEBKGND, PM_NOREMOVE ) )// if( bPassEraseBkgnd )if( bPassPaint )while( ::PeekMessage( &msg, hWnd, WM_PAINT, WM_PAINT, PM_NOREMOVE ) )if( ! ::PeekMessage( &msg, hWnd, WM_PAINT, WM_PAINT, PM_REMOVE ) )break;DispatchMessage( &msg );nCountPassed ++;// while( ::PeekMessage( &msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE ) )// if( bPassPaint )return nCountPassed;


 


 


 


 


 


 


 


)


{


 


LONG


 


MSG


 


{


 


{


 


 


::


 


}


 


}


 


 


{


 


{


 


 


::


 


}


 


}


 


 


{


 


{


 


 


::


 


}


 


}


 


 


}