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 » Toolbar Problem Collapse All
Subject Author Date
Andrew Nanopoulos Apr 13, 2006 - 1:46 PM

In my IE toolbar Impl I have the following problem: When I select a new window(browser instance) from the file menu in IE, the toolbar crashes. It seems that 2 ore more toolbars cant share the same process? I assume that this has somthing to do with g_CmdManager? I guessed that you cant create another identical toolbar in the same process and that you need a new profile for each toolbar, So i did that and I can get the toolbar to load and display for multiple instances but when I press any button I get an assert here:

void CExtToolControlBar::_CloseTrackingMenus()
{
    g_bMenuTracking = false;

//CSingleLock _slCsCB( &g_csCB );
//    _slCsCB.Lock();
    for( INT iBar=0; iBar<g_AllBars.GetSize(); ++iBar )
    {
        CExtControlBar * pBar = g_AllBars[iBar];
---->>        ASSERT_VALID( pBar );
        if( pBar->GetSafeHwnd() == NULL )
            continue;
        CExtToolControlBar * pToolControlBar =
            DYNAMIC_DOWNCAST(CExtToolControlBar,pBar);
        if( pToolControlBar == NULL )
            continue;
        pToolControlBar->_SwitchMenuTrackingIndex();
    }


Do you know what I need to do to solve this issue? I think you can duplicate this problem with that KBBar toolbar that I sent you.

Andrew Nanopoulos Apr 21, 2006 - 9:10 AM

I am still haveing this issue after static linking the MFC and profUIS. I am using a another dll that uses mfc in a dll, could this cause the problem? And what exactly is the problem?

Technical Support Apr 24, 2006 - 4:30 AM

If you use both MFC and the Prof-UIS RDE configuration as static libraries, there should not be any problems. All the global objects in this case are parts of your COM module instance. You can create several instances of your in-process COM object without any problems in this case. If you use Prof-UIS and MFC as DLLs, you can create only one instance of your com object in one process. The problem is in managing the state for global variables.

Andrew Nanopoulos Apr 13, 2006 - 4:11 PM

Call Stack FYI:


CWnd::AssertValid() line 883 + 67 bytes
CControlBar::AssertValid() line 986
CExtToolControlBar::AssertValid() line 8241
AfxAssertValidObject(const CObject * 0x02bb2ad8 {CRSAToolbarWnd}, const char * 0x029fe590 THIS_FILE, int 9389) line 108
CExtToolControlBar::_CloseTrackingMenus() line 9390
CExtBarButton::OnClick(CPoint {x=39 y=15}, unsigned char 1) line 2147
CExtToolControlBar::OnLButtonDown(unsigned int 1, CPoint {x=39 y=15}) line 7578 + 26 bytes
CWnd::OnWndMsg(unsigned int 513, unsigned int 1, long 983079, long * 0x04dbf818) line 1964
CWnd::WindowProc(unsigned int 513, unsigned int 1, long 983079) line 1585 + 30 bytes
CControlBar::WindowProc(unsigned int 513, unsigned int 1, long 983079) line 480 + 20 bytes
CExtControlBar::WindowProc(unsigned int 513, unsigned int 1, long 983079) line 6937
CExtToolControlBar::WindowProc(unsigned int 513, unsigned int 1, long 983079) line 9295
AfxCallWndProc(CWnd * 0x02bc0a48 {CRSAToolbarWnd hWnd=???}, HWND__ * 0x001c0db0, unsigned int 513, unsigned int 1, long 983079) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x001c0db0, unsigned int 513, unsigned int 1, long 983079) line 368
AfxWndProcDllStatic(HWND__ * 0x001c0db0, unsigned int 513, unsigned int 1, long 983079) line 57 + 21 bytes
USER32! 77d48734()
USER32! 77d48816()
USER32! 77d489cd()
USER32! 77d48a10()
BROWSEUI! 75fa6f6d()
BROWSEUI! 75fae942()
BROWSEUI! 75faeab5()
KERNEL32! 7c80b50b()

Technical Support Apr 14, 2006 - 9:52 AM

To resolve this problem, use both Prof-UIS and MFC libraries linked statically. Simply setup your project to use MFC as a static library. The Prof-UIS library will automatically be linked statically. Of course, you need to compile the appropriate configuration of the ProfUISLIB project.

Andrew Nanopoulos May 4, 2006 - 10:43 AM

This does not seem to solve the problem. There is on instance of the g_allbars per process it seems, When I select "new window" from ie it starts a new toolbar in a seperate thread but the gcommandmanager is the same copy etc, (all static vars are shared between threads) :

so it is checking g_Allbars[0] first which is a Cwd in another thread, ie the first toolbar instance, so I get the following assert:

Stack:

CWnd::AssertValid() line 883 + 67 bytes
CControlBar::AssertValid() line 986
CExtToolControlBar::AssertValid() line 8242
AfxAssertValidObject(const CObject * 0x0299c7f8 {RsaToolbar::CRSAToolbarWnd hWnd=0x00180d64}, const char * 0x028cd6e0 THIS_FILE, int 9390) line 108
CExtToolControlBar::_CloseTrackingMenus() line 9391
CExtBarButton::OnClick(CPoint {x=28 y=18}, unsigned char 1) line 2147
CExtToolControlBar::OnLButtonDown(unsigned int 1, CPoint {x=28 y=18}) line 7578 + 26 bytes
CWnd::OnWndMsg(unsigned int 513, unsigned int 1, long 1179676, long * 0x04b8f848) line 1964
CWnd::WindowProc(unsigned int 513, unsigned int 1, long 1179676) line 1585 + 30 bytes
CControlBar::WindowProc(unsigned int 513, unsigned int 1, long 1179676) line 480 + 20 bytes
CExtControlBar::WindowProc(unsigned int 513, unsigned int 1, long 1179676) line 6937
CExtToolControlBar::WindowProc(unsigned int 513, unsigned int 1, long 1179676) line 9296
AfxCallWndProc(CWnd * 0x02995698 {RsaToolbar::CRSAToolbarWnd hWnd=0x001b0d6a}, HWND__ * 0x001b0d6a, unsigned int 513, unsigned int 1, long 1179676) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x001b0d6a, unsigned int 513, unsigned int 1, long 1179676) line 368



in CWnd::AssertValid():

        ASSERT((p = pMap->LookupPermanent(m_hWnd)) != NULL ||
here-->            (p = pMap->LookupTemporary(m_hWnd)) != NULL);
        ASSERT((CWnd*)p == this); // must be us

        // Note: if either of the above asserts fire and you are
        // writing a multithreaded application, it is likely that
        // you have passed a C++ object from one thread to another
        // and have used that object in a way that was not intended.
        // (only simple inline wrapper functions should be used)
        //
        // In general, CWnd objects should be passed by HWND from
        // one thread to another. The receiving thread can wrap
        // the HWND with a CWnd object by using CWnd::FromHandle.
        //
        // It is dangerous to pass C++ objects from one thread to
        // another, unless the objects are designed to be used in
        // such a manner.

...


This problem seems to go away in release mode... but I need debug to work.

Any ideas?

Technical Support May 5, 2006 - 11:34 AM

We believe it’s possible to fix this problem. We need some time to debug this issue carefully. The fix should be based on checking the result of the CWnd::FromHandlePermanent() method’s invocation. Would you send us a simplified/stripped version of your project which produces the problem?

Andrew Nanopoulos May 5, 2006 - 10:06 AM

It seems to be a problem with the in-proc COM object. The static global data only gets one instance per process( the dll is loaded one time). It seems like the static members should be malloc’ed in some way, that way there would be seperate data for each instance of the com object.

Another behavior that I am seeing that I am sure is related: If I select a drop-down menu from one instance and go to the onther instance to select the menu I get the following assert here:

void CExtPopupMenuSite::_Done()
{
here-->    ASSERT( !m_bShutdownMode );
    if( m_pWndToolTip != NULL )
        m_pWndToolTip->Hide();
    m_bShutdownMode = true;
    m_pWndCapture = NULL;
    m_pWndAnimation = NULL;
    m_lpnResultCmdID = NULL;
    if( m_pTopMenu != NULL
...

_CrtDbgReport(int 2, const char * 0x028e62a8 THIS_FILE, int 567, const char * 0x00000000, const char * 0x00000000) line 353
AfxAssertFailedLine(const char * 0x028e62a8 THIS_FILE, int 567) line 39 + 19 bytes
CExtPopupMenuSite::_Done() line 567 + 39 bytes
CExtPopupMenuSite::DoneInstance() line 540
CExtPopupMenuWnd::OnCancelMode() line 11937
CWnd::OnWndMsg(unsigned int 31, unsigned int 0, long 0, long * 0x049ef184) line 1825
CWnd::WindowProc(unsigned int 31, unsigned int 0, long 0) line 1585 + 30 bytes
AfxCallWndProc(CWnd * 0x029af080 {CExtPopupMenuWnd hWnd=???}, HWND__ * 0x00510d10, unsigned int 31, unsigned int 0, long 0) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x00510d10, unsigned int 31, unsigned int 0, long 0) line 368
USER32! 77d48734()
USER32! 77d48816()
USER32! 77d489cd()
USER32! 77d496c7()
CWinThread::PumpMessage() line 853
CExtPopupMenuWnd::PassMsgLoop(unsigned char 0) line 8128 + 21 bytes
CExtPopupMenuWnd::TrackPopupMenu(unsigned long 2724, int 535, int 354, const tagRECT * 0x049ef550 {top=347 bottom=369 left=512 right=561}, void * 0x029a72a8, void (void *, CDC &, const CWnd &, const CRect &, int)* 0x0212c570 CExtToolControlBar::_CbPaintCombinedContent(void *, CDC &, const CWnd &, const CRect &, int), unsigned int * 0x049ef544, unsigned char 1) line 8103 + 11 bytes
CExtBarButton::OnTrackPopup(CPoint {x=535 y=354}, unsigned char 0, unsigned char 0) line 1962 + 58 bytes
CExtBarButton::OnClick(CPoint {x=23 y=8}, unsigned char 1) line 2159 + 28 bytes
CExtToolControlBar::OnLButtonDown(unsigned int 1, CPoint {x=23 y=8}) line 7578 + 26 bytes
CWnd::OnWndMsg(unsigned int 513, unsigned int 1, long 524311, long * 0x049ef848) line 1964
CWnd::WindowProc(unsigned int 513, unsigned int 1, long 524311) line 1585 + 30 bytes
CControlBar::WindowProc(unsigned int 513, unsigned int 1, long 524311) line 480 + 20 bytes
CExtControlBar::WindowProc(unsigned int 513, unsigned int 1, long 524311) line 6938
CExtToolControlBar::WindowProc(unsigned int 513, unsigned int 1, long 524311) line 9296
AfxCallWndProc(CWnd * 0x029a72a8 {RsaToolbar::CRSAToolbarWnd hWnd=???}, HWND__ * 0x00500bc8, unsigned int 513, unsigned int 1, long 524311) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x00500bc8, unsigned int 513, unsigned int 1, long 524311) line 368



Technical Support May 6, 2006 - 9:20 AM

We believe it is possible to resolve any multithreaded conflict. But we need a test project that reproduces problems in the same way as they occur in your real project.