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 » Double clicking CExtGridWnd causes access violation in exthook.cpp:243 Collapse All
Subject Author Date
Scott Moore May 17, 2007 - 9:31 AM

We are having a problem with CExtGridWnd that is really perplexing. We never had this problem with 2.62 when compiled under VS 2003, but when we upgraded to 2.64 and VS 2005, we occasionally get this problem when double-clicking an item in the grid. I would say it happens about 10% of the time. We double-click the grid (while debugging in VS 2005 SP1) and it gives us this error message:

Unhandled exception at 0x00ce68f1 (ProfUIS264ud.dll) in DemoD.exe: 0xC0000005: Access violation reading location 0x00000000.

The location is exthook.cpp, line 243.

        if( ::IsWindow( hWndHooked ) )
        {
            nSinkCount = (int)m_HookSinkArray.GetSize();
            for( nSinkIdx = 0; nSinkIdx < nSinkCount; nSinkIdx++ )
            {
                CExtHookSink * pHookSink =
                    m_HookSinkArray[ nSinkIdx ]; // <<== error is right here
                if( pHookSink == NULL )
                    continue;
                pHookSink->OnPostHookWndMsg(
                    lResult,
                    m_hWndHooked,
                    nMessage,
                    wParam,
                    lParam
                    );
            } // for( nSinkIdx = 0; nSinkIdx < nSinkCount; nSinkIdx++ )
        } // if( ::IsWindow( hWndHooked ) )

nSinkIdx == 0
nSinkCount is garbage (56648900)
m_HookSinkArray is basically NULL (m_pData internally is NULL)


The call stack is:

    ProfUIS264ud.dll!CExtHookSink::HookChains_t::HookChainsWindowProc(unsigned int nMessage=515, unsigned int & wParam=1, long & lParam=3014806) Line 243 + 0xf bytes    C++
    ProfUIS264ud.dll!CExtHookSink::HookChains_t::g_HookWndProc(HWND__ * hWnd=0x00050ac0, unsigned int nMessage=515, unsigned int wParam=1, long lParam=3014806) Line 287 + 0x14 bytes    C++
    user32.dll!7e418734()     
    [Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]    
    user32.dll!7e418816()     
    user32.dll!7e4189cd()     
    user32.dll!7e418a10()     
    mfc80ud.dll!AfxInternalPumpMessage() Line 183    C++
    mfc80ud.dll!CWinThread::PumpMessage() Line 896    C++
    mfc80ud.dll!CWinThread::Run() Line 625 + 0xd bytes    C++
    mfc80ud.dll!CWinApp::Run() Line 894    C++
    mfc80ud.dll!AfxWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, wchar_t * lpCmdLine=0x00020b4e, int nCmdShow=1) Line 47 + 0xd bytes    C++
    DemoD.exe!wWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, wchar_t * lpCmdLine=0x00020b4e, int nCmdShow=1) Line 33    C++
    DemoD.exe!__tmainCRTStartup() Line 589 + 0x35 bytes    C
    DemoD.exe!wWinMainCRTStartup() Line 414    C



The CExtGridWnd class that we are using is actually a derived class. The real class is this:


class CNwGridWnd : public CExtGridWnd
{

protected:
    
    DECLARE_MESSAGE_MAP()
    
    virtual bool OnGbwAnalyzeCellMouseClickEvent(
        UINT nChar,
        UINT nRepCnt,
        UINT nFlags,
        CPoint point
        );

    afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
};

We don’t do much with the methods except send another windows message to our parent window:


bool CNwGridWnd::OnGbwAnalyzeCellMouseClickEvent(
        UINT nChar,
        UINT nRepCnt,
        UINT nFlags,
        CPoint point
        )
{
    ASSERT_VALID(this);

    CExtGridHitTestInfo htInfo(point);
    HitTest( htInfo, false, true );

    if (VK_LBUTTON == nChar
             && ( !htInfo.IsHoverEmpty() || htInfo.IsValidRect() ) // A valid location in the grid
             && 0 == htInfo.GetInnerOuterTypeOfColumn()         // An inner column cell
             && 0 == htInfo.GetInnerOuterTypeOfRow())             // An inner row cell

    {
        if (2 == nRepCnt)
        {
            bool ret = CExtGridWnd::OnGbwAnalyzeCellMouseClickEvent(
                nChar, nRepCnt, nFlags, point);
            GetOwner()->SendMessage(WM_GRID_DBLCLK, htInfo.m_nColNo, htInfo.m_nRowNo);
            return ret;
        }
        else if (nRepCnt < 2)
        {
            bool ret = CExtGridWnd::OnGbwAnalyzeCellMouseClickEvent(
                nChar, nRepCnt, nFlags, point);
            GetOwner()->SendMessage(WM_GRID_CLK, htInfo.m_nColNo, htInfo.m_nRowNo);
            return ret;
        }
    }

    return CExtGridWnd::OnGbwAnalyzeCellMouseClickEvent(
        nChar, nRepCnt, nFlags, point);
}

void CNwGridWnd::OnLButtonDblClk(UINT nFlags, CPoint point)
{
    CWnd* parentWnd = GetOwner();
    CExtGridWnd::OnLButtonDblClk(nFlags, point);
    parentWnd->SendMessage(WM_GRID_DBLCLK, point.x, point.y);
}




So, given all that info, do you have any ideas what the problem might be? Creating a small sample program to demonstrate the problem would be a last resort for us, as it would take some time with no guarantees that the problem could be duplicated.

Thank you for taking the time to look at this.

Scott

Scott Moore May 17, 2007 - 11:42 AM

Well, the windows message I send is sent to the parent CExtResizableDlg, which gets the selection from the grid and acts upon it. You could do the same thing by just handling the message and displaying a MessageBox().

But what would cause m_HookSinkArray to be invalid? That’s the real source of the problem.

Technical Support May 18, 2007 - 5:07 AM

We still failed to reproduce the crash. We used the following method in the CDemoGrid class in the SimpleGrids sample:

      virtual bool OnGbwAnalyzeCellMouseClickEvent(
                  UINT nChar,
                  UINT nRepCnt,
                  UINT nFlags,
                  CPoint point
                  )
      {
            ASSERT_VALID(this);

            CExtGridHitTestInfo htInfo(point);
            HitTest( htInfo, false, true );

            if (VK_LBUTTON == nChar
                         && ( !htInfo.IsHoverEmpty() || htInfo.IsValidRect() ) // A valid location in the grid
                         && 0 == htInfo.GetInnerOuterTypeOfColumn()         // An inner column cell
                         && 0 == htInfo.GetInnerOuterTypeOfRow())             // An inner row cell

            {
                  if (2 == nRepCnt)
                  {
                        bool ret = CExtGridWnd::OnGbwAnalyzeCellMouseClickEvent(
                              nChar, nRepCnt, nFlags, point);
//                      GetOwner()->SendMessage(WM_GRID_DBLCLK, htInfo.m_nColNo, htInfo.m_nRowNo);
/* point 1 */ AfxMessageBox( _T("1") );
                        return ret;
                  }
                  else if (nRepCnt < 2)
                  {
                        bool ret = CExtGridWnd::OnGbwAnalyzeCellMouseClickEvent(
                              nChar, nRepCnt, nFlags, point);
//                      GetOwner()->SendMessage(WM_GRID_CLK, htInfo.m_nColNo, htInfo.m_nRowNo);
/* point 2 */ AfxMessageBox( _T("2") );
                        return ret;
                  }
            }

            return CExtGridWnd::OnGbwAnalyzeCellMouseClickEvent(
                  nChar, nRepCnt, nFlags, point);
      }


Technical Support May 17, 2007 - 11:30 AM

We used your version of the OnGbwAnalyzeCellMouseClickEvent() method in the CDemoGrid class in the SimpleGrids sample application:

      virtual bool OnGbwAnalyzeCellMouseClickEvent(
                  UINT nChar,
                  UINT nRepCnt,
                  UINT nFlags,
                  CPoint point
                  )
      {
            ASSERT_VALID(this);

            CExtGridHitTestInfo htInfo(point);
            HitTest( htInfo, false, true );

            if (VK_LBUTTON == nChar
                         && ( !htInfo.IsHoverEmpty() || htInfo.IsValidRect() ) // A valid location in the grid
                         && 0 == htInfo.GetInnerOuterTypeOfColumn()         // An inner column cell
                         && 0 == htInfo.GetInnerOuterTypeOfRow())             // An inner row cell

            {
                  if (2 == nRepCnt)
                  {
                        bool ret = CExtGridWnd::OnGbwAnalyzeCellMouseClickEvent(
                              nChar, nRepCnt, nFlags, point);
//                      GetOwner()->SendMessage(WM_GRID_DBLCLK, htInfo.m_nColNo, htInfo.m_nRowNo);
                        return ret;
                  }
                  else if (nRepCnt < 2)
                  {
                        bool ret = CExtGridWnd::OnGbwAnalyzeCellMouseClickEvent(
                              nChar, nRepCnt, nFlags, point);
//                      GetOwner()->SendMessage(WM_GRID_CLK, htInfo.m_nColNo, htInfo.m_nRowNo);
                        return ret;
                  }
            }

            return CExtGridWnd::OnGbwAnalyzeCellMouseClickEvent(
                  nChar, nRepCnt, nFlags, point);
      }
All the grids in this sample application are derived from the CDemoGrid with different selection models and grid cell highlighting options. We did not see any crashes when using Prof-UIS 2.64. But, as you may have noted, we commented out the WM_GRID_CLK code because we have no idea what the message handler for it should do? May be, you will be able to repeat the same experiment May be we need to know some more details about how should we double click the grid cell, were exactly and which cell type should be used?