CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Oct 2005
    Posts
    230

    CDockablePane and Scrollbar

    Hi all

    Im in the situation where i need a child window of a CDockablePane to be scrollable.

    I thought this would be incredibly simple. Create a CWnd child window, enable the scroll bars and it would all be ok..

    Unfortunately when i click on the scroll bars the messages arnt getting to the window. a click and drag on the scroll bar wil drag the dockable window and therefor un-dock it.

    Is there any simple way to have a scrollable child window in this situation?

    Regards,
    UnfitElf
    Learning somthing new every day!

  2. #2
    Join Date
    Oct 2005
    Posts
    230

    Re: CDockablePane and Scrollbar

    Anyone?
    Learning somthing new every day!

  3. #3
    Join Date
    Oct 2005
    Posts
    230

    Re: CDockablePane and Scrollbar

    I checked with Spy++ today, it does seem the window is getting messages (hittest ones @ least).

    Is there more to creating a scrollable window than setting the scrollbar styles and the scroll size?
    Learning somthing new every day!

  4. #4
    Join Date
    Nov 2002
    Location
    Sofia, Bulgaria
    Posts
    661

    Re: CDockablePane and Scrollbar

    Curiously it doesn't work. I had (and still have) the same predicament.
    Thanks to a class from CodeProject ( http://www.codeproject.com/KB/dialog...spx?fid=195884 )
    I almost got it to work but
    1. the scrollbars are sometimes invisible.
    2. although the mouse wheel does work, the scrollbars respond only on double clicking. If you try my code, just double-click on the scrollbars and they will be active.

    I have no idea why this is caused. The CodeProject CScrollHelper class, works perfectly on a separate project, without dockable panes. I looked at the greater part of the dockable panes' source and still have no clue.

    If you want you may take it from here. Right now I've stopped working on that problem and have left if for later.

    If you have any progress, please share.

    Here the code of my dockable pane:

    Code:
    //mypane.h
    class CMyPane : public CDockablePane
    {
    	DECLARE_DYNAMIC(CMyPane)
    
    public:
    	CMyPane();
    	virtual ~CMyPane();
    
    protected:
    	afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    	afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    	afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
    	afx_msg void OnSize(UINT nType, int cx, int cy);
    	afx_msg int  OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
    	
    	//CScrollHelper from http://www.codeproject.com/KB/dialog/scrolling_support.aspx?fid=195884
    	CScrollHelper m_ScrollHelper;
    	
    	DECLARE_MESSAGE_MAP()
    };
    
    //mypane.cpp
    
    IMPLEMENT_DYNAMIC(CMyPane, CDockablePane)
    
    CMyPane::CMyPane()
    {
    	m_ScrollHelper.AttachWnd(this);
    	m_ScrollHelper.SetDisplaySize(50, 1000);
    }
    
    CMyPane::~CMyPane()
    {
    }
    
    BEGIN_MESSAGE_MAP(CMyPane, CDockablePane)
    	ON_WM_MOUSEACTIVATE()
    	ON_WM_HSCROLL()
    	ON_WM_VSCROLL()
    	ON_WM_MOUSEWHEEL()
    	ON_WM_SIZE()
    END_MESSAGE_MAP()
    
    void CMyPane::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
    {
    	m_ScrollHelper.OnHScroll(nSBCode, nPos, pScrollBar);
    }
    
    void CMyPane::OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
    {
    	m_ScrollHelper.OnVScroll(nSBCode, nPos, pScrollBar);
    }
    
    BOOL CMyPane::OnMouseWheel( UINT nFlags, short zDelta, CPoint pt )
    {
    	return m_ScrollHelper.OnMouseWheel(nFlags, zDelta, pt);
    }
    
    void CMyPane::OnSize( UINT nType, int cx, int cy )
    {
    	CDockablePane::OnSize(nType, cx, cy);
    
    	m_ScrollHelper.OnSize(nType, cx, cy);
    }
    
    int CMyPane::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
    {
    	int status = CDockablePane::OnMouseActivate(pDesktopWnd, nHitTest, message);
    	
    	SetFocus();
    	
    	return status;
    }
    It's only when you look at an ant through a magnifying glass on a sunny day that you realise how often they burst into flames

  5. #5
    Join Date
    Sep 2020
    Posts
    1

    Resolved Re: CDockablePane and Scrollbar

    Quote Originally Posted by SeventhStar View Post
    Curiously it doesn't work. I had (and still have) the same predicament.
    Thanks to a class from CodeProject ( http://www.codeproject.com/KB/dialog...spx?fid=195884 )
    I almost got it to work but
    1. the scrollbars are sometimes invisible.
    2. although the mouse wheel does work, the scrollbars respond only on double clicking. If you try my code, just double-click on the scrollbars and they will be active.

    I have no idea why this is caused. The CodeProject CScrollHelper class, works perfectly on a separate project, without dockable panes. I looked at the greater part of the dockable panes' source and still have no clue.

    If you want you may take it from here. Right now I've stopped working on that problem and have left if for later.

    If you have any progress, please share.

    Here the code of my dockable pane:

    Code:
    //mypane.h
    class CMyPane : public CDockablePane
    {
    	DECLARE_DYNAMIC(CMyPane)
    
    public:
    	CMyPane();
    	virtual ~CMyPane();
    
    protected:
    	afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    	afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    	afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
    	afx_msg void OnSize(UINT nType, int cx, int cy);
    	afx_msg int  OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
    	
    	//CScrollHelper from http://www.codeproject.com/KB/dialog/scrolling_support.aspx?fid=195884
    	CScrollHelper m_ScrollHelper;
    	
    	DECLARE_MESSAGE_MAP()
    };
    
    //mypane.cpp
    
    IMPLEMENT_DYNAMIC(CMyPane, CDockablePane)
    
    CMyPane::CMyPane()
    {
    	m_ScrollHelper.AttachWnd(this);
    	m_ScrollHelper.SetDisplaySize(50, 1000);
    }
    
    CMyPane::~CMyPane()
    {
    }
    
    BEGIN_MESSAGE_MAP(CMyPane, CDockablePane)
    	ON_WM_MOUSEACTIVATE()
    	ON_WM_HSCROLL()
    	ON_WM_VSCROLL()
    	ON_WM_MOUSEWHEEL()
    	ON_WM_SIZE()
    END_MESSAGE_MAP()
    
    void CMyPane::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
    {
    	m_ScrollHelper.OnHScroll(nSBCode, nPos, pScrollBar);
    }
    
    void CMyPane::OnVScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar )
    {
    	m_ScrollHelper.OnVScroll(nSBCode, nPos, pScrollBar);
    }
    
    BOOL CMyPane::OnMouseWheel( UINT nFlags, short zDelta, CPoint pt )
    {
    	return m_ScrollHelper.OnMouseWheel(nFlags, zDelta, pt);
    }
    
    void CMyPane::OnSize( UINT nType, int cx, int cy )
    {
    	CDockablePane::OnSize(nType, cx, cy);
    
    	m_ScrollHelper.OnSize(nType, cx, cy);
    }
    
    int CMyPane::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
    {
    	int status = CDockablePane::OnMouseActivate(pDesktopWnd, nHitTest, message);
    	
    	SetFocus();
    	
    	return status;
    }


    Year 2020, VC 2019,MFC is still alive, your post helped me out of a dilema.
    I guess there is a much better way, but your post was best I found, and probably others will find.
    So I improved your code a little bit and now it is working fine for me

    Code:
    // 2. although the mouse wheel does work, the scrollbars respond only on double-clicking.
    // let's overwrite the double-click and make it a click
    // The scrollbar is in the NoneClient Area: Nc
    // Don't forget the MESSAGE_MAP
    
    ...
    ON_WM_NCLBUTTONDOWN
    ...
    void CMyPane::OnNcLButtonDown(UINT nHitTest, CPoint point)
    {
        // "OnNonClientAreaLeftMouseButtonDown"
        // to OnNonClientAreaLeftMouseButtonDoubleClick
       // Hack:
        CMyPane::OnNcLButtonDblClk(nHitTest, point);
    }
    
    // 1. the scrollbars are sometimes invisible. 
    // Let s have a function to insert at various points to force them to appear
    // The scrollbar appears, when you scroll the mouse with your OnMouseWheel function, let s make use of this
    
    void CMyPane::ShowBars()
    {
    // Hack: you may see a flicker
         OnMouseWheel(SB_VERT, -40, CPoint(0,0));
         OnMouseWheel(SB_VERT, 40, CPoint(0,0));
    // SB_HORZ accordingly
    
    }

  6. #6
    Join Date
    Jun 2021
    Posts
    1

    Re: CDockablePane and Scrollbar

    There are two bugs in CDockablePane. CDockablePane::OnNcPaint() erases the scroll bar. CDockablePane::OnNcLButtonDown does not call CPane::OnNcLButtonDown if not docked.

    Add two overrides to your derived class:


    Code:
    void CPaneSensorGraph::OnNcPaint()
    {
        CDockablePane::OnNcPaint();
    
    
        SCROLLINFO si;
        si.cbSize = sizeof(si);
        BOOL result = GetScrollInfo(SB_HORZ, &si);
        SetScrollInfo(SB_HORZ, &si, FALSE);
    }
    
    
    
    
    void CPaneSensorGraph::OnNcLButtonDown(UINT nHitTest, CPoint point)
    {
        CDockablePane::OnNcLButtonDown(nHitTest, point);
        CPane::OnNcLButtonDown(nHitTest, point);
    }
    Refreshing SetScrollInfo repaints the scrollbar. There may be a better way of doing it.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured