Print Page | Close Window

Access violation CXTPMenuBar::LoadMenu

Printed From: Codejock Forums
Category: Codejock Products
Forum Name: Toolkit Pro
Forum Description: Topics Related to Codejock Toolkit Pro
URL: http://forum.codejock.com/forum_posts.asp?TID=3123
Printed Date: 06 October 2024 at 7:23am
Software Version: Web Wiz Forums 12.04 - http://www.webwizforums.com


Topic: Access violation CXTPMenuBar::LoadMenu
Posted By: franji1
Subject: Access violation CXTPMenuBar::LoadMenu
Date 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++




Replies:
Posted By: franji1
Date 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??



Posted By: Oleg
Date 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


Posted By: franji1
Date 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);
             }
         }
      }
   }




Print Page | Close Window

Forum Software by Web Wiz Forums® version 12.04 - http://www.webwizforums.com
Copyright ©2001-2021 Web Wiz Ltd. - https://www.webwiz.net