15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Violation destroying a CListCtrl when it

Stephan
Monday, February 05, 1996


Hello, MFC World:

I am stumped over this one.

Environment:
 ------------
     MSVC 4.0 (with service pack 1 applied)
     MFC 4.0
     Windows NT 3.51 (not using the new shell)

Symptoms:
 ---------
     I dynamically create a CListCtrl as a child window of a CTabCtrl. 
 (Both are members of the CView-derived object.)  When I close the view, I 
get
     "Unhandled exception in Test.exe (COMCTL32.DLL): 0xC0000005:  Access 
Violation."
and the debugger plops me in assembly code within COMCTL32.DLL.

Details:
 --------
     I have reproduced this consistently in a minimal application which does 
little more than create the CTabCtrl and create the CListCtrl (as a child of 
the CTabCtrl) within a view.  The access violation seems to occur before any 
of my objects' destructors get called, and even before any WM_DESTROY 
message handlers.

     The problem does NOT occur if:
 - I create the CListCtrl as a child of the CView instead of the CTabCtrl
 - or, I use any other control (CStatic, CListBox) instead of a CListCtrl.

    Here is the relevant code snippets from my minimal app:

class CTest32View : public CView
{
protected: // create from serialization only
     CTest32View();
     DECLARE_DYNCREATE(CTest32View)

// Attributes
public:
     CTest32Doc* GetDocument();

     CTabCtrl  m_TabCtrl;
     CListCtrl m_ListCtrl;         // works if change "CListCtrl" -> 
"CListBox".

     ...etc.
}

int CTest32View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
     if (CView::OnCreate(lpCreateStruct) == -1)
          return -1;

     // Create the main tab control.
     CRect rect;
     rect.SetRectEmpty();     // irrelevant for this minimal app.

     if( !m_TabCtrl.Create(
          WS_CHILD | WS_VISIBLE | WS_TABSTOP
          | TCS_TABS | TCS_SINGLELINE,
          rect,
          this,
          IDC_TAB_CTRL ) ) {
          ASSERT( FALSE );
          return -1;
     }

     if( !m_ListCtrl.Create(
          WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,
          rect,
          &m_TabCtrl,         // Works if change "&m_TabCtrl" -> "this".
          IDC_LIST_CTRL ) ) {
          ASSERT( FALSE );
          return -1;
     }
     return 0;
}


Thanks in advance for any (CGoodHint *)'s.  :-)


Stephan Jou,
stephan@synapse.net, Stephan.Jou@cognos.com




Mike Blaszczak -- mikeblas@interserv.com
Tuesday, February 06, 1996

[Mini-digest: 2 responses]

On Mon, 05 Feb 1996, Stephan.Jou@Cognos.COM (Jou, Stephan) wrote:
>Environment:
> ------------
>     MSVC 4.0 (with service pack 1 applied)
>     MFC 4.0
>     Windows NT 3.51 (not using the new shell)

Thanks.

>     I dynamically create a CListCtrl as a child window of a CTabCtrl. 
> (Both are members of the CView-derived object.)  When I close the view, I 
>get
>     "Unhandled exception in Test.exe (COMCTL32.DLL): 0xC0000005:  Access 
>Violation."
>and the debugger plops me in assembly code within COMCTL32.DLL.

Why is the CListCtrl a child of the CTabCtrl?  This seems wierd.  I think it 
should be a child of the CView, too.  I don't think CTabCtrls, like me, 
expect to have children.

.B ekiM
--
TCHAR szScratched[] = _T("Someone tried to tow my motorcycle.  _Once_.");

-----From: Mackay 

My guess would be that it is a NULL pointer. Look at your call stack and =
retrace the code backwards from here. Check the pointers that are =
created, passed into functions etc (you are using VC++ 4.0 so you should =
have the luxury of data tips) - everyone else including myself would =
have to resign themselves to the Watch window.=20

Just work backwards in each function from where the wee green arrow is =
to the beginning of the function and then to the next function down in =
the call stack (with in reason). You should find that you are passing a =
null pointer and that is causing your errors.

I have found that the best way to detect NULL pointers before anything =
else does is to put a line like

ASSERT(pMyPointer);  // This should not be a NULL pointer.

before using it, or at the beginning of functions, for pointers being =
passed in. This will not affect the release code, but is a fantatic =
debugging tool as it will abort the program and put a marker on the line =
containing the ASSERT so you can tell instantly what went wrong.

I hope this is useful and you manage to track down the error (what ever =
it may be).


Colin Angus Mackay  --  gs94@dial.pipex.com



------ =_NextPart_000_01BAF494.3A3B1E40
Content-Type: application/ms-tnef




| Вернуться в корень Архива |