Codejock Forums Homepage
Forum Home Forum Home > Codejock Products > Visual C++ MFC > Toolkit Pro
  New Posts New Posts RSS Feed - Access violation CXTPMenuBar::LoadMenu
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

Access violation CXTPMenuBar::LoadMenu

 Post Reply Post Reply
Author
Message
franji1 View Drop Down
Groupie
Groupie
Avatar

Joined: 28 June 2005
Status: Offline
Points: 70
Post Options Post Options   Thanks (0) Thanks(0)   Quote franji1 Quote  Post ReplyReply Direct Link To This Post Topic: Access violation CXTPMenuBar::LoadMenu
    Posted: 28 October 2005 at 10:59am

XTP V 8.60
My application is crashing when I use a hot key with my app's "View" menu displayed. The hotkey is tied to bring up a specific view which changes the menu via my main frame's OnInitMenu (see bottom of call stack below).  The last thing my OnInitMenu does is call the CXTPMenuBar::LoadMenu:
GetCommandBars()->GetMenuBar()->LoadMenu(pMenu);

The current menu is still being displayed, but the LoadMenu call starts dealing with loading the new one, the old controls are invalid.  CXTPControl * items in the the CXTPControls::m_arrControls array are invalid.  The pointers are valid, but what they point to is invalid (lots of 0xfeeefeee in debug build). It appears it is dealing with controls that no longer exist, but are still in the container.

It actually crashes in the CXTPControls::CalcDynamicSize method when it attempts to call a method with one of these invalid CXTPControl * pointers:

CSize CXTPControls::CalcDynamicSize(CDC* pDC, int nLength, DWORD dwMode, const CRect& rcBorder, int nWidth)
{
 CSize sizeResult(0,0);
 for (int i = GetCount() - 1; i >=0; i--)
 {
  GetAt(i)->OnCalcDynamicSize(dwMode);  ACCESS VIOLATION HERE
 }

Here's the call stack from my OnInitMenu method (at the bottom) to the crash (at the top).  Any ideas on how to fix this would be very helpful!!

> HEIXTP86d.dll!CXTPControls::CalcDynamicSize(CDC * pDC=0x0012c894, int nLength=952, unsigned long dwMode=11, const CRect & rcBorder={...}, int nWidth=0)  Line 827 + 0x26 C++
  HEIXTP86d.dll!CXTPToolBar::CalcDockingLayout(int nLength=952, unsigned long dwMode=11, int nWidth=0)  Line 621 + 0x29 C++
  HEIXTP86d.dll!CXTPDockBar::_AdjustRow(CArray<CXTPToolBar *,CXTPToolBar *> & arrRow={...}, CPoint pt={...}, int nLength=952, int bHorz=2, AFX_SIZEPARENTPARAMS * lpLayout=0x0012ceb4, int & nRemove=-1)  Line 144 C++
  HEIXTP86d.dll!CXTPDockBar::AdjustRow(CArray<CXTPToolBar *,CXTPToolBar *> & arrRow={...}, CPoint pt={...}, int nLength=952, int bHorz=2, AFX_SIZEPARENTPARAMS * lpLayout=0x0012ceb4)  Line 271 + 0x24 C++
  HEIXTP86d.dll!CXTPDockBar::CalcDynamicLayout(int nLength=952, unsigned long nMode=11, AFX_SIZEPARENTPARAMS * lpLayout=0x0012d3ac)  Line 328 + 0x2c C++
  HEIXTP86d.dll!CXTPDockBar::OnSizeParent(unsigned int __formal=0, long lParam=1233836)  Line 385 C++
  mfc71d.dll!CWnd::OnWndMsg(unsigned int message=865, unsigned int wParam=0, long lParam=1233836, long * pResult=0x0012d1bc)  Line 2013 + 0x11 C++
  mfc71d.dll!CWnd::WindowProc(unsigned int message=865, unsigned int wParam=0, long lParam=1233836)  Line 1745 + 0x1e C++
  mfc71d.dll!AfxCallWndProc(CWnd * pWnd=0x01215f58, HWND__ * hWnd=0x00210560, unsigned int nMsg=865, unsigned int wParam=0, long lParam=1233836)  Line 241 + 0x1a C++
  mfc71d.dll!AfxWndProc(HWND__ * hWnd=0x00210560, unsigned int nMsg=865, unsigned int wParam=0, long lParam=1233836)  Line 389 C++
  mfc71d.dll!AfxWndProcBase(HWND__ * hWnd=0x00210560, unsigned int nMsg=865, unsigned int wParam=0, long lParam=1233836)  Line 209 + 0x15 C++
  user32.dll!77d48734() 
  user32.dll!77d48816() 
  user32.dll!77d4b89b() 
  user32.dll!77d5f3e3() 
  mfc71d.dll!CWnd::RepositionBars(unsigned int nIDFirst=0, unsigned int nIDLast=65535, unsigned int nIDLeftOver=59648, unsigned int nFlags=2, tagRECT * lpRectParam=0x01213c60, const tagRECT * lpRectClient=0x00000000, int bStretch=1)  Line 2982 C++
  mfc71d.dll!CFrameWnd::RecalcLayout(int bNotify=1)  Line 2008 C++
  HEIXTP86d.dll!CXTPTabWorkspace::UpdateContents(int bAddNewWindows=1)  Line 1339 + 0x26 C++
  HEIXTP86d.dll!CXTPTabWorkspace::OnPaint()  Line 1492 C++
  mfc71d.dll!CWnd::OnWndMsg(unsigned int message=15, unsigned int wParam=0, long lParam=0, long * pResult=0x0012d82c)  Line 2023 C++
  mfc71d.dll!CWnd::WindowProc(unsigned int message=15, unsigned int wParam=0, long lParam=0)  Line 1745 + 0x1e C++
  mfc71d.dll!AfxCallWndProc(CWnd * pWnd=0x01213e14, HWND__ * hWnd=0x00260620, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0)  Line 241 + 0x1a C++
  mfc71d.dll!AfxWndProc(HWND__ * hWnd=0x00260620, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0)  Line 389 C++
  mfc71d.dll!AfxWndProcBase(HWND__ * hWnd=0x00260620, unsigned int nMsg=15, unsigned int wParam=0, long lParam=0)  Line 209 + 0x15 C++
  user32.dll!77d48734() 
  user32.dll!77d48816() 
  user32.dll!77d4b4c0() 
  user32.dll!77d4b50c() 
  ntdll.dll!7c90eae3() 
  user32.dll!77d4d83f() 
  user32.dll!77d4d82a() 
  mfc71d.dll!CWnd::UpdateWindow()  Line 127 + 0x36 C++
  HEIXTP86d.dll!CXTPPopupBar::SetTrackingMode(int bMode=0, int bSelectFirst=1, int bKeyboard=0)  Line 988 C++
  HEIXTP86d.dll!CXTPCommandBar::OnDestroy()  Line 172 + 0x22 C++
  mfc71d.dll!CWnd::OnWndMsg(unsigned int message=2, unsigned int wParam=0, long lParam=0, long * pResult=0x0012dd50)  Line 2023 C++
  mfc71d.dll!CWnd::WindowProc(unsigned int message=2, unsigned int wParam=0, long lParam=0)  Line 1745 + 0x1e C++
  mfc71d.dll!AfxCallWndProc(CWnd * pWnd=0x02385548, HWND__ * hWnd=0x003806b4, unsigned int nMsg=2, unsigned int wParam=0, long lParam=0)  Line 241 + 0x1a C++
  mfc71d.dll!AfxWndProc(HWND__ * hWnd=0x003806b4, unsigned int nMsg=2, unsigned int wParam=0, long lParam=0)  Line 389 C++
  mfc71d.dll!AfxWndProcBase(HWND__ * hWnd=0x003806b4, unsigned int nMsg=2, unsigned int wParam=0, long lParam=0)  Line 209 + 0x15 C++
  user32.dll!77d48734() 
  user32.dll!77d48816() 
  user32.dll!77d4c63f() 
  user32.dll!77d4e905() 
  HEIXTP86d.dll!CXTPHookManager::HookWndProc(HWND__ * hWnd=0x003806b4, unsigned int message=2, unsigned int wParam=0, long lParam=0)  Line 92 + 0x1c C++
  user32.dll!77d48734() 
  user32.dll!77d48816() 
  user32.dll!77d4b4c0() 
  user32.dll!77d4b50c() 
  ntdll.dll!7c90eae3() 
  user32.dll!77d4daf6() 
  mfc71d.dll!CWnd::DestroyWindow()  Line 988 + 0xd C++
  HEIXTP86d.dll!CXTPPopupBar::DestroyWindow()  Line 970 C++
  HEIXTP86d.dll!CXTPCommandBar::OnFinalRelease()  Line 111 + 0xd C++
  mfc71d.dll!CCmdTarget::InternalRelease()  Line 139 C++
  HEIXTP86d.dll!CXTPControlPopup::~CXTPControlPopup()  Line 38 C++
  HEIXTP86d.dll!CXTPControlPopup::`vector deleting destructor'()  + 0x6c C++
  mfc71d.dll!CCmdTarget::OnFinalRelease()  Line 597 + 0x1f C++
  mfc71d.dll!CCmdTarget::InternalRelease()  Line 139 C++
  HEIXTP86d.dll!CXTPControls::RemoveAll()  Line 341 C++
  HEIXTP86d.dll!CXTPCommandBar::LoadMenuA(CMenu * pMenu=0x024556cc, int bRemoveControls=1)  Line 497 C++
  Prgrm50.dll!CProgramFrameD::OnInitMenu(CMenu * pMenu=0x024556cc)  Line 1107 C++

Back to Top
franji1 View Drop Down
Groupie
Groupie
Avatar

Joined: 28 June 2005
Status: Offline
Points: 70
Post Options Post Options   Thanks (0) Thanks(0)   Quote franji1 Quote  Post ReplyReply Direct Link To This Post Posted: 28 October 2005 at 2:13pm

I figured out a "fix".  You'll notice that we are calling CXTPControls::RemoveAll.  This method basically cleans up the XTP Controls associated with the menu bar.  There is some smart code here:

void CXTPControls::RemoveAll(void)  ORIGINAL CODE
{
 for (int nIndex = 0; nIndex < GetCount(); nIndex++)
 {
  CXTPControl* pControl = m_arrControls.GetAt(nIndex);
  pControl->m_pControls = NULL;
  pControl->m_pParent = NULL;
  pControl->InternalRelease();
 } 
 m_arrControls.RemoveAll();
}

All references between the container and the menu bar should have been taken care of before the call to InteralRelease (where it's initialyzing the two pointers to NULL).

But for some reason, the InternalRelease call ends up accessing the same container way down the stack in the CXTPControls::CalcDynamicSize method (I checked the pointer of the CXTPControls this pointer, and they match).

I rewrote the CXTPControls::RemoveAll method to basically copy the control pointers into a temporary automatic CArray<CXTPControl*, CXTPControl*> array, call RemoveAll on the CXTPControls::m_arrControls before the loop, then loop through the temporary array.

Here's the new code, but I am not 100% sure if it causes any side effects:

void CXTPControls::RemoveAll(void)  NEW CODE
{
   CArray<CXTPControl*, CXTPControl*> aTemp;  // temp controls container
   const int nSize = GetCount();
   aTemp.SetSize(nSize);  // set temp's container size then copy

   // copy everything from m_arrControls to aTemp
   for (int nIndex = 0; nIndex < nSize; nIndex++)
      {
      aTemp.SetAt(nIndex, m_arrControls.GetAt(nIndex));
      }

   m_arrControls.RemoveAll();  // clear out member container

   // now loop through aTemp and clean up controls
   for (int nIndex = 0; nIndex < nSize; nIndex++)
   {
      CXTPControl* pControl = aTemp.GetAt(nIndex);
      pControl->m_pControls = NULL;
      pControl->m_pParent = NULL;
      pControl->InternalRelease();
   }  
   aTemp.RemoveAll();
}

Anyone want to comment??

Back to Top
Oleg View Drop Down
Admin Group
Admin Group


Joined: 21 May 2003
Location: United States
Status: Offline
Points: 11234
Post Options Post Options   Thanks (0) Thanks(0)   Quote Oleg Quote  Post ReplyReply Direct Link To This Post Posted: 31 October 2005 at 1:48am

Hello,

Can you uattach sample to show what you do to replace menu?

Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS
Back to Top
franji1 View Drop Down
Groupie
Groupie
Avatar

Joined: 28 June 2005
Status: Offline
Points: 70
Post Options Post Options   Thanks (0) Thanks(0)   Quote franji1 Quote  Post ReplyReply Direct Link To This Post Posted: 31 October 2005 at 8:23am

This is the method that calls the LoadMenu method on the MenuBar object (at the bottom of the method).  Below this method is the OnActivateView method which
"calls" the OnInitMenu via the WM_INITMENU message.

void CProgramFrameD::OnInitMenu(CMenu* pMenu)
   {
   char Buffer[100];
   BOOL MainMenu = FALSE;
     
   if (pProj->GetKB())
      {     
      for (UINT x=0; x<pMenu->GetMenuItemCount(); x++)
         {
         pMenu->GetMenuString(x, Buffer, sizeof(Buffer), MF_BYPOSITION);
        
         if (!strcmp(Buffer, (char *) ViewString))   // "&View"
             {
             BuildViewMenu(pMenu->GetSubMenu(x));
             //break;
             }
         else if (!strcmp(Buffer, (char *) FileString))
             {
             if (!pMenu->GetSubMenu(x))
                pMenu->ModifyMenu(x, MF_POPUP | MF_BYPOSITION, (UINT) FileMenu.GetSafeHmenu(), (char *) FileString);
//                 pMenu->ModifyMenu(x, MF_POPUP | MF_BYPOSITION, (UINT) FileMenu, (char *) FileString);
             }
         else if (!strcmp(Buffer, (char *) HelpString))
             {
             if (!pMenu->GetSubMenu(x))
                pMenu->ModifyMenu(x, MF_POPUP | MF_BYPOSITION, (UINT) HelpMenu.GetSafeHmenu(), (char *) HelpString);
//                 pMenu->ModifyMenu(x, MF_POPUP | MF_BYPOSITION, (UINT) HelpMenu, (char *) HelpString);
             }
         else if (!strcmp(Buffer, (char *) WindowString))       &nbs p;
             {
             if (!pMenu->GetSubMenu(x))
                pMenu->ModifyMenu(x, MF_POPUP | MF_BYPOSITION, (UINT) WindowMenu.GetSafeHmenu(), (char *) WindowString);
//                 pMenu->ModifyMenu(x, MF_POPUP | MF_BYPOSITION, (UINT) WindowMenu, (char *) WindowString);
             }
         else if (!strcmp(Buffer, (char *) ToolsString))         ;
             {
             if (!pMenu->GetSubMenu(x))
                pMenu->ModifyMenu(x, MF_POPUP | MF_BYPOSITION, (UINT) ToolsMenu.GetSafeHmenu(), (char *) ToolsString);
//                 pMenu->ModifyMenu(x, MF_POPUP | MF_BYPOSITION, (UINT) ToolsMenu, (char *) ToolsString);
             }
         }
      }
  
//   CHostMDI::OnInitMenu(pMenu);
     
   // If we have a knowledge base then let it have a chance to change the menu.
   if (pProj->GetKB())
      pProj->GetKB()->HostMessage(ONINITMENU, (LPARAM) this, (LPARAM)pMenu);

   BroadcastProgramMessage(ONINITMENU, (LPARAM) this, (LPARAM) pMenu);

   // Doug 6/14/05 - Don't update the XTPro Menu here.  Otherwise, we
   //                  get the local menu showing up on the menu bar after
   //                  a right-click.  See DSP5 Problem #49.
   // Update XTPro menu
   // Doug 6/23/05 - Ok, lets go back and fix the problem I created by
   //                  removing the LoadMenu call.  We need this call to be
   //                  made if and only if we are dealing with the main
   //                  menu...
 
   CString ItemName;
  
   pMenu->GetMenuString(0, ItemName, MF_BYPOSITION);
    
   if (!strncmp(ItemName.GetBuffer(0), (char *) FileString, ItemName.GetLength()))
      GetCommandBars()->GetMenuBar()->LoadMenu(pMenu);

   }

Here's the method that "calls" OnInitMenu for the specific view in question (other views have similar structure).  Only the "CLadView" has an accelerator key assigned to it (Ctrl+L) to bring it up.  It only crashes when it must create the view.  It does not crash if the view already exists and we are only changing focus to that existing view.

void CLadView::OnActivateView( BOOL bActivate, CView* pActivateView, CView* pDeactiveView)
   {
   CGraphicalView::OnActivateView( bActivate, pActivateView, pDeactiveView);
  
   HPrivateIni HostIni(AfxGetHostApp()->GetIniFile());
   //STRINGFIND==OFF
   m_bLadderPalette = HostIni.GetInt(String(IDS_INI_SETUP), "LadderPalette", 1); //STRINGFIND==ON

   if( InEditMode() )
      {
//      HTRACE("CLadView::OnActivateView(%d) calling ShowPalette\n", bActivate);
      //ShowPalette(bActivate && m_bLadderPalette);
      if (!(bActivate && m_bLadderPalette))
         {
         LadderDataClass *pDC = (LadderDataClass *) Proj->GetData(DT_LADDER);
         if (GetPaletteBar())
             {
             delete GetPaletteBar();
             pDC->pPaletteBar = NULL;
             }
         }
      }
  
//   if (SubView && bActivate)
   if (bActivate)
      {
      // Change to the correct menu!
      CMDIChildWnd *pChild = (CMDIChildWnd *) GetParentFrame();
     
      if (pChild)
         {
         CMDIFrameWnd* pFrame = pChild->GetMDIFrame();
     
         if (pFrame)
             {
               LadderDataClass *pLDC = (LadderDataClass *)Proj->GetData(DT_LADDER);

             ::SendMessage(pFrame->m_hWndMDIClient, WM_MDISETMENU, (WPARAM)pLDC->hSharedMenu,
                (LPARAM)(pFrame->GetWindowMenuPopup(pLDC->hSharedMenu) ));
               
             pChild->SendMessage(WM_SETACCELTABLE, 0, (LPARAM) (void *) pLDC->hSharedAccelTable);
        
             pFrame->DrawMenuBar();

             GetProgramFrame()->SendMessage(WM_INITMENU, (WPARAM)pLDC->hSharedMenu, 0);
             }
         }
      }
   }

Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down

Forum Software by Web Wiz Forums® version 12.04
Copyright ©2001-2021 Web Wiz Ltd.

This page was generated in 0.172 seconds.