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 General Discussion » right click menu extscrollbar Collapse All
Subject Author Date
Dirk Lindner Nov 19, 2009 - 5:56 AM

Hello, i have written a styled cextscrollbar rightclickmenu.
But i have problems with large ClistView controls (120.000) items.
The listview dont scroll to ottom or a large position within the listview.
It also crashes from time to time at the following postion:

Run-Time Check Failure #2 - Stack around the variable ’pt’ was corrupted.

ProfUIS287md.dll!CExtPopupMenuWnd::_EndSequenceEx(CExtPopupMenuWnd::MENUITEMDATA & mi={...}) Zeile 14399 + 0x1c    C++

Any idea ?

Thanks


extscrollwnd.h

#define ID_PROFUIS_SCROLL_BAR 30
#define ID_PROFUIS_SCROLL_HERE 31
#define ID_PROFUIS_SCROLL_TOP 32
#define ID_PROFUIS_SCROLL_BOTTOM 33
#define ID_PROFUIS_SCROLL_UP                 34
#define ID_PROFUIS_SCROLL_DOWN                 35
#define ID_PROFUIS_SCROLL_UP2                 36
#define ID_PROFUIS_SCROLL_DOWN2                 37
#define ID_PROFUIS_SCROLL_LEFT     38
#define ID_PROFUIS_SCROLL_RIGHT     39
#define ID_PROFUIS_SCROLL_SITE_LEFT     40
#define ID_PROFUIS_SCROLL_SITE_RIGHT     41
#define ID_PROFUIS_SCROLL_LEFT2     42
#define ID_PROFUIS_SCROLL_RIGHT2 43


    //Scroll
    afx_msg void OnScrollHere();
    afx_msg void OnScrollBottom();
    afx_msg void OnScrollTop();
    afx_msg void OnScrollUp();
    afx_msg void OnScrollDown();
    afx_msg void OnScrollSiteUp();
    afx_msg void OnScrollSiteDown();
    CPoint m_point;

extscrollwnd.cpp

void CExtScrollBar::OnContextMenu(CWnd* pWnd, CPoint point)
{
ASSERT_VALID( this );

    CFrameWnd* pFrame = GetParentFrame();
    if(!pFrame)
        return;
    HWND hwnd = m_hWnd;
    if( !IsWindow(hwnd ) || hwnd == NULL )
        return;
    __EXT_MFC_SAFE_LPCTSTR sProfileName = g_CmdManager->ProfileNameFromWnd( hwnd );


    //Popup Menu erzeugen
    CExtPopupMenuWnd* pPopup = new CExtPopupMenuWnd;
    pPopup->CreatePopupMenu(hwnd);


    CString str;

    //ID_PROFUIS_SCROLL_HERE
    LRESULT lresult = pFrame->SendMessage(ID_PROFUIS_SCROLL_BAR, ID_PROFUIS_SCROLL_HERE , ((LPARAM) &str));
    if(!(bool)lresult)
        return;
    CExtCmdItem _cmd;
    _cmd.m_sMenuText = str;
    _cmd.m_nCmdID = ID_PROFUIS_SCROLL_HERE;
    g_CmdManager->CmdSetup(sProfileName,_cmd);
    pPopup->ItemInsert(    ID_PROFUIS_SCROLL_HERE,-1,str,NULL,hwnd );
    pPopup->ItemInsert();//seperator einfuegen

    eScrollerOrientation_t ot = GetScrollerOrientation();

    if(ot == __ESO_LEFT || ot == __ESO_RIGHT ){//Vertikaler Bildlauf
        //ID_PROFUIS_SCROLL_TOP
        LRESULT lresult = pFrame->SendMessage(ID_PROFUIS_SCROLL_BAR, ID_PROFUIS_SCROLL_TOP ,((LPARAM) &str));
        if(!(bool)lresult)
            return;
        CExtCmdItem _cmd;
        _cmd.m_sMenuText = str;
        _cmd.m_nCmdID = ID_PROFUIS_SCROLL_TOP;
        g_CmdManager->CmdSetup(sProfileName,_cmd);
        pPopup->ItemInsert(ID_PROFUIS_SCROLL_TOP,-1,    str,NULL, hwnd );
        //ID_PROFUIS_SCROLL_BOTTOM
        lresult = pFrame->SendMessage(ID_PROFUIS_SCROLL_BAR, ID_PROFUIS_SCROLL_BOTTOM , ((LPARAM) &str));
        if(!(bool)lresult)
            return;
        _cmd.m_sMenuText = str;
        _cmd.m_nCmdID = ID_PROFUIS_SCROLL_BOTTOM;
        g_CmdManager->CmdSetup(sProfileName,_cmd);
        pPopup->ItemInsert(    ID_PROFUIS_SCROLL_BOTTOM,-1,    str,NULL,hwnd );

        pPopup->ItemInsert();//seperator einfügen

        //ID_PROFUIS_SCROLL_UP
        lresult = pFrame->SendMessage(ID_PROFUIS_SCROLL_BAR, ID_PROFUIS_SCROLL_UP , ((LPARAM) &str));
        if(!(bool)lresult)
            return;
        _cmd.m_sMenuText = str;
        _cmd.m_nCmdID = ID_PROFUIS_SCROLL_UP;
        g_CmdManager->CmdSetup(sProfileName,_cmd);
        pPopup->ItemInsert(    ID_PROFUIS_SCROLL_UP,-1,str,NULL,hwnd);
        
        //ID_PROFUIS_SCROLL_DOWN
        lresult = pFrame->SendMessage(ID_PROFUIS_SCROLL_BAR, ID_PROFUIS_SCROLL_DOWN , ((LPARAM) &str));
        if(!(bool)lresult)
            return;
        _cmd.m_sMenuText = str;
        _cmd.m_nCmdID = ID_PROFUIS_SCROLL_DOWN;
        g_CmdManager->CmdSetup(sProfileName,_cmd);
        pPopup->ItemInsert(    ID_PROFUIS_SCROLL_DOWN,-1,str,NULL,hwnd );

        pPopup->ItemInsert();//seperator einfügen

        //ID_PROFUIS_SCROLL_UP2
        lresult = pFrame->SendMessage(ID_PROFUIS_SCROLL_BAR, ID_PROFUIS_SCROLL_UP2 , ((LPARAM) &str));
        if(!(bool)lresult)
            return;
        _cmd.m_sMenuText = str;
        _cmd.m_nCmdID = ID_PROFUIS_SCROLL_UP2;
        g_CmdManager->CmdSetup(sProfileName,_cmd);
        pPopup->ItemInsert(ID_PROFUIS_SCROLL_UP2,-1,str,NULL,hwnd );

        //ID_PROFUIS_SCROLL_DOWN2
        lresult = pFrame->SendMessage(ID_PROFUIS_SCROLL_BAR, ID_PROFUIS_SCROLL_DOWN2 , ((LPARAM) &str));
        if(!(bool)lresult)
            return;
        _cmd.m_sMenuText = str;
        _cmd.m_nCmdID = ID_PROFUIS_SCROLL_DOWN2;
        g_CmdManager->CmdSetup(sProfileName,_cmd);
        pPopup->ItemInsert(    ID_PROFUIS_SCROLL_DOWN2,-1,    str,NULL,hwnd );
    }else if(ot == __ESO_TOP || ot == __ESO_BOTTOM ){//Horizentaler Bildlauf

        //ID_PROFUIS_SCROLL_LEFT
        LRESULT lresult = pFrame->SendMessage(ID_PROFUIS_SCROLL_BAR, ID_PROFUIS_SCROLL_LEFT ,((LPARAM) &str));
        if(!(bool)lresult)
            return;
        CExtCmdItem _cmd;
        _cmd.m_sMenuText = str;
        _cmd.m_nCmdID = ID_PROFUIS_SCROLL_LEFT;
        g_CmdManager->CmdSetup(sProfileName,_cmd);
        pPopup->ItemInsert(    ID_PROFUIS_SCROLL_LEFT, -1,    str,NULL, hwnd );

        //ID_PROFUIS_SCROLL_RIGHT
        lresult = pFrame->SendMessage(ID_PROFUIS_SCROLL_BAR, ID_PROFUIS_SCROLL_RIGHT , ((LPARAM) &str));
        if(!(bool)lresult)
            return;
        _cmd.m_sMenuText = str;
        _cmd.m_nCmdID = ID_PROFUIS_SCROLL_RIGHT;
        g_CmdManager->CmdSetup(sProfileName,_cmd);
        pPopup->ItemInsert(    ID_PROFUIS_SCROLL_RIGHT,-1,    str,NULL, hwnd );

        pPopup->ItemInsert();//seperator einfügen

        //ID_PROFUIS_SCROLL_SITE_LEFT
        lresult = pFrame->SendMessage(ID_PROFUIS_SCROLL_BAR, ID_PROFUIS_SCROLL_SITE_LEFT , ((LPARAM) &str));
        if(!(bool)lresult)
            return;
        _cmd.m_sMenuText = str;
        _cmd.m_nCmdID = ID_PROFUIS_SCROLL_SITE_LEFT;
        g_CmdManager->CmdSetup(sProfileName,_cmd);
        pPopup->ItemInsert(    ID_PROFUIS_SCROLL_SITE_LEFT, -1,    str, NULL, hwnd );

        //ID_PROFUIS_SCROLL_SITE_RIGHT
        lresult = pFrame->SendMessage(ID_PROFUIS_SCROLL_BAR, ID_PROFUIS_SCROLL_SITE_RIGHT , ((LPARAM) &str));
        if(!(bool)lresult)
            return;
        _cmd.m_sMenuText = str;
        _cmd.m_nCmdID = ID_PROFUIS_SCROLL_SITE_RIGHT;
        g_CmdManager->CmdSetup(sProfileName,_cmd);
        pPopup->ItemInsert( ID_PROFUIS_SCROLL_SITE_RIGHT, -1, str, NULL, hwnd );

        pPopup->ItemInsert();//seperator einfügen

        //ID_PROFUIS_SCROLL_RIGHT2
        lresult = pFrame->SendMessage(ID_PROFUIS_SCROLL_BAR, ID_PROFUIS_SCROLL_LEFT2 , ((LPARAM) &str));
        if(!(bool)lresult)
            return;
        _cmd.m_sMenuText = str;
        _cmd.m_nCmdID = ID_PROFUIS_SCROLL_LEFT2;
        g_CmdManager->CmdSetup(sProfileName,_cmd);
        pPopup->ItemInsert(    ID_PROFUIS_SCROLL_LEFT2,-1,    str, NULL, hwnd    );

        //ID_PROFUIS_SCROLL_RIGHT2
        lresult = pFrame->SendMessage(ID_PROFUIS_SCROLL_BAR, ID_PROFUIS_SCROLL_RIGHT2 , ((LPARAM) &str));
        if(!(bool)lresult)
            return;
        _cmd.m_sMenuText = str;
        _cmd.m_nCmdID = ID_PROFUIS_SCROLL_RIGHT2;
        g_CmdManager->CmdSetup(sProfileName,_cmd);
        pPopup->ItemInsert(    ID_PROFUIS_SCROLL_RIGHT2,-1, str, NULL,hwnd );
    }

    UINT nCmd;
    POINT pt;
::GetCursorPos( &pt );
    pPopup->TrackPopupMenu( TPMX_SELECT_ANY,pt.x,pt.y,NULL,NULL,NULL,&nCmd);
}


void CExtScrollBar::OnScrollHere()
{
    int nStart,nRange;
    GetScrollRange(&nStart,&nRange);
    long nWidth;
    CRect rect;
    GetClientRect(&rect);
    CPoint tmp;
    eScrollerOrientation_t ot = GetScrollerOrientation();
    if(ot == __ESO_LEFT || ot == __ESO_RIGHT ){//Vertikaler Bildlauf
        nWidth = rect.Height()-(m_nHorzBarHeight*2);
        long pos = (nRange *(m_point.y - m_nHorzBarHeight ))/(nWidth);
        tmp = m_point;
        _SetScrollPos(pos);
    }else{
        nWidth = rect.Width()-(m_nHorzBarHeight*2);
        long pos = (nRange *(m_point.x - m_nHorzBarHeight ))/(nWidth);
        _SetScrollPos(pos);
    }
}

void CExtScrollBar::OnScrollBottom()
{
    int nStart,nRange;
    GetScrollRange(&nStart,&nRange);
    _SetScrollPos(nRange-nStart);
}

void CExtScrollBar::OnScrollTop()
{
    _SetScrollPos(0);
}

void CExtScrollBar::OnScrollUp()
{
    int nPos = GetScrollPos();
    _SetScrollPos(nPos-m_nStepSize);
}

void CExtScrollBar::OnScrollSiteUp()
{
    SCROLLINFO scrollInfo;
    GetScrollInfo(&scrollInfo);
    int nPos = GetScrollPos();
    _SetScrollPos(nPos-scrollInfo.nPage);

}
void CExtScrollBar::OnScrollDown()
{
    int nPos = GetScrollPos();
    CString str;
    _SetScrollPos(nPos+m_nStepSize);
}

void CExtScrollBar::OnScrollSiteDown()
{
    int nPos = GetScrollPos();
    SCROLLINFO scrollInfo;
    GetScrollInfo(&scrollInfo);
    _SetScrollPos(nPos+scrollInfo.nPage);
}


void CExtScrollBar::OnRButtonDown(UINT nFlags, CPoint point)
{
        ASSERT_VALID( this );
if( ! m_bCompleteRepaint ){//tod notwendig ?
CScrollBar::OnRButtonDown( nFlags, point );
return;
}
        CExtPopupMenuTipWnd * pATTW =
        OnAdvancedPopupMenuTipWndGet();
        if( pATTW != NULL )
            pATTW->Hide();
        m_point = point;
        OnContextMenu(this,point);
}

bool CExtScrollBar::ScrollBar_OnMouseClickMsg( MSG * pMSG ){

            if(GetParent())
                GetParent()->SetFocus();
ASSERT_VALID( this );
ASSERT( pMSG != NULL );
            bool bRetVal = true;
            bool bRightClickMsg = false;

switch( pMSG->message ){
                case WM_LBUTTONDOWN:
                            ScrollBar_TrackMouseLButtonDown( pMSG );
                break;
                case WM_RBUTTONDOWN:
                            bRightClickMsg = true;
                case WM_RBUTTONUP:
                case WM_RBUTTONDBLCLK:
                            //bRetVal = false;
                case WM_LBUTTONUP:
                case WM_LBUTTONDBLCLK:
                case WM_MBUTTONDOWN:
                case WM_MBUTTONUP:
                case WM_MBUTTONDBLCLK:
                {
                        CExtPopupMenuTipWnd * pATTW = OnAdvancedPopupMenuTipWndGet();
                            if( pATTW != NULL )
                                    pATTW->Hide();
                            if( bRightClickMsg ){
                                POINT pt;
                                ::GetCursorPos( &pt );
                                SendMessage( WM_CONTEXTMENU, WPARAM(m_hWnd), MAKELPARAM(pt.x,pt.y) );
                            }

                }
                break;
                default:
                            bRetVal = false;
                break;
                } // switch( pMSG->message )
return bRetVal;
}
//sroll>>

Dirk Lindner Nov 22, 2009 - 8:30 AM

here is an exmple app and  the  extscrollwnd files


example.rar


 

Technical Support Nov 25, 2009 - 3:44 AM

Thank you for sharing ideas with us. Here is the updated scroll bar code:

http://www.prof-uis.com/download/forums/tmp/ScrollBar288.zip

The 120 thousand problem is not solved yet. The list view common control’s window procedure returns the 100 thousand scrolling range when it handles the SBM_GETSCROLLINFO message - it never returns a greater range nevertheless the native non-client area scroll bars support this. It looks like we will need to re-code list view control from scratch.

Dirk Lindner Nov 20, 2009 - 3:18 AM

First there comes a asser
>    mfc71d.dll!AfxAssertValidObject(const CObject * pOb=0xfeeefeee, const char * lpszFileName=0x01400174, int nLine=3749) Zeile 86    C++
    ProfUIS287md.dll!CExtPopupMenuWnd::MENUITEMDATA::GetCmdNode() Zeile 3752    C++
    ProfUIS287md.dll!CExtPopupMenuWnd::_EndSequenceEx(CExtPopupMenuWnd::MENUITEMDATA & mi={...}) Zeile 14325 + 0x8    C++
    ProfUIS287md.dll!CExtPopupMenuWnd::_OnMouseClick(unsigned int nFlags=514, CPoint point={...}, bool & bNoEat=false) Zeile 14304 + 0x17    C++
    ProfUIS287md.dll!CExtPopupMenuSite::_HookMouseProc(int nCode=0, unsigned int wParam=514, long lParam=1244740) Zeile 1271 + 0x29    C++
    user32.dll!7e381923()     
    ntdll.dll!7c925d47()     
    user32.dll!7e378ea0()     
    user32.dll!7e37b317()     
    ntdll.dll!7c925d47()     
    user32.dll!7e3816c8()     
    ntdll.dll!7c91e473()     
    user32.dll!7e3818d1()     
    user32.dll!7e3691be()     
    user32.dll!7e37776b()     
    ntdll.dll!7c925d47()     
    mfc71d.dll!AfxInternalPumpMessage() Zeile 158 + 0x13    C++
    mfc71d.dll!CWinThread::PumpMessage() Zeile 916    C++
    mfc71d.dll!CWinThread::Run() Zeile 637 + 0xb    C++
    mfc71d.dll!CWinApp::Run() Zeile 701    C++
    mfc71d.dll!AfxWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00141f1f, int nCmdShow=1) Zeile 49 + 0xb    C++
    LucGismo_Debug.exe!WinMainCRTStartup() Zeile 390 + 0x39    C
    kernel32.dll!7c817077()     
    ntdll.dll!7c925d47()

then
Run-Time Check Failure #2 - Stack around the variable ’pt’ was corrupted.
the message apears not always

>    ProfUIS287md.dll!CExtPopupMenuWnd::_EndSequenceEx(CExtPopupMenuWnd::MENUITEMDATA & mi={...}) Zeile 14397 + 0x1c    C++
    ProfUIS287md.dll!CExtPopupMenuWnd::_OnMouseClick(unsigned int nFlags=514, CPoint point={...}, bool & bNoEat=false) Zeile 14304 + 0x17    C++
    ProfUIS287md.dll!CExtPopupMenuSite::_HookMouseProc(int nCode=0, unsigned int wParam=514, long lParam=1244740) Zeile 1271 + 0x29    C++
    user32.dll!7e381923()     
    ntdll.dll!7c925d47()     
    user32.dll!7e378ea0()     
    user32.dll!7e37b317()     
    ntdll.dll!7c925d47()     
    user32.dll!7e3816c8()     
    ntdll.dll!7c91e473()     
    user32.dll!7e3818d1()     
    user32.dll!7e3691be()     
    user32.dll!7e37776b()     
    ntdll.dll!7c925d47()     
    mfc71d.dll!AfxInternalPumpMessage() Zeile 158 + 0x13    C++
    mfc71d.dll!CWinThread::PumpMessage() Zeile 916    C++
    mfc71d.dll!CWinThread::Run() Zeile 637 + 0xb    C++
    mfc71d.dll!CWinApp::Run() Zeile 701    C++
    mfc71d.dll!AfxWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00141f1f, int nCmdShow=1) Zeile 49 + 0xb    C++
    LucGismo_Debug.exe!WinMainCRTStartup() Zeile 390 + 0x39    C
    kernel32.dll!7c817077()     
    ntdll.dll!7c925d47()     

Technical Support Nov 20, 2009 - 2:37 PM

First of all, your menu construction code contains lines like these:

LRESULT lresult = pFrame->SendMessage(ID_PROFUIS_SCROLL_BAR, ID_PROFUIS_SCROLL_HERE , ((LPARAM) &str));

The ID_PROFUIS_SCROLL_BAR constant is used as a message number and it’s defined as:
#define ID_PROFUIS_SCROLL_BAR 30

Please note, 30 equals to 0x1E and Win32 SDK contains the following definition:
#define WM_TIMECHANGE                   0x001E

Please switch using some WM_USER-based message number.
Second, the CExtPopupMenuWnd::MENUITEMDATA::GetCmdNode() method is invoked at very beginning of the CExtPopupMenuWnd::_EndSequenceEx() method where the reference to the CExtPopupMenuWnd::MENUITEMDATA object cannot be invalid:
void CExtPopupMenuWnd::_EndSequenceEx(
            CExtPopupMenuWnd::MENUITEMDATA & mi
            )
{
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
            _KeyTipsShow( false );
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)

            if(                     (! _IsFadeOutAnimation() )
                        &&        m_ctrlShadow.GetSafeHwnd() != NULL
                        )
                        m_ctrlShadow.DestroyWindow();

#if (!defined __EXT_MFC_NO_CUSTOMIZE)
CExtCustomizeCmdTreeNode * pNode = mi.GetCmdNode();
. . .

This means, unfortunately, the call stack listing didn’t help us in this case. Is it possible to insert your source code in any of Prof-UIS sample apps or in some test project, make it reproducing this crash and send it to us?

Technical Support Nov 19, 2009 - 1:52 PM

You should send the SB_BOTTOM notification through the WM_VSCROLL message to your list view control if you want to scroll it to the bottom vertically. Do not compute any exact scrolling position in this case. The list view control use very specific scrolling parameters which can be either pixel-by-pixel based or item-by-item based.

The menu crash is very interesting. Please show us the entire call stack listing.