CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 2 of 2
  1. #1
    Join Date
    Apr 1999
    Posts
    2

    How to add a ScrollView to Dialog??



    Hi,


    Does any one know how to add a scroll view to a dialog box? Can we add any view to dialog?


    Yusheng

  2. #2
    Join Date
    Mar 1999
    Location
    St. Louis
    Posts
    45

    Re: How to add a ScrollView to Dialog??

    Views and dialogs do not get along. I tried many, many combinations. If you want a dialog like interface in a view then use CFormView.

    If you want a smart scrolling control in a dialog then you need to write much of the scrolling yourself.

    These were written for some QuickTime controls- you'll see some Mac-Like code.

    Here is a class ( a hack more like ;-&gt to activate scrollbars for controls in dialogs and views.



    // class to be used in a control that belongs in a dialog
    class CWndScroller
    {
    public:
    CWndScroller(CWnd &inWnd);

    virtual ~CWndScroller()
    {
    }
    virtual void SetScrollSizes(
    const SIZE& sizeImage,
    const SIZE& sizePage = CScrollView::sizeDefault,
    const SIZE& sizeLine = CScrollView::sizeDefault);
    virtual void AdjustFrame();
    virtual void ResizeImage(const SIZE& sizeImage);
    virtual bool OnScroll(int inBar, UInt sbCode, UInt pos, CScrollBar *bar);
    virtual void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);

    virtual CSize GetImageSize()
    {
    return mImageSize;
    }
    virtual void ScrollTo(UInt32 x, UInt32 y)
    {
    mCurrentPos.x = x;
    mCurrentPos.y = y;
    mSubject.SetScrollPos(x, y);
    }
    virtual CPoint GetPosition()
    {
    mSubject.GetScrollInfo(SB_HORZ, &mInfo);
    mCurrentPos.x = mInfo.nPos;
    mSubject.GetScrollInfo(SB_VERT, &mInfo);
    mCurrentPos.y = mInfo.nPos;
    return mCurrentPos;
    }

    virtual void EraseEmptyRgn();
    virtual void ResizeParentToFit(BOOL bShrinkOnly = TRUE);

    private:
    protected:
    SCROLLINFO mInfo;

    CWnd &mSubject;
    CSize mImageSize;
    CSize mPageSize;
    CSize mLineSize;
    CPoint mCurrentPos;

    void UpdateCurrentPostion();
    };

    // class to be used in a CView subclass
    class CViewScroller : public CWndScroller
    {
    public:
    CViewScroller(CWnd &inWnd) : CWndScroller(inWnd)
    {
    }
    virtual void AdjustFrame();
    };

    CWndScroller::CWndScroller(CWnd &inWnd) : mSubject(inWnd)
    {
    mInfo.cbSize = sizeof(SCROLLINFO);
    mInfo.cbSize = 0;
    mInfo.fMask = 0;
    mInfo.nMin = 0;
    mInfo.nMax = 0;
    mInfo.nPage = 0;
    mInfo.nPos = 0;
    mInfo.nTrackPos = 0;
    }

    void CWndScroller::SetScrollSizes(
    const SIZE& sizeImage,
    const SIZE& sizePage,
    const SIZE& sizeLine)
    {

    // CWnd *scroll = mSubject.GetScrollBarCtrl(SB_HORZ);
    // if (scroll) scroll->ModifyStyle(0, SIF_DISABLENOSCROLL, 0);
    // scroll = mSubject.GetScrollBarCtrl(SB_HORZ);
    // if (scroll) scroll->ModifyStyle(0, SIF_DISABLENOSCROLL, 0);

    mPageSize = sizePage;
    mLineSize = sizeLine;
    this->ResizeImage(sizeImage);
    }

    void CWndScroller::ResizeImage(const SIZE& sizeImage)
    {
    mImageSize = sizeImage;
    this->AdjustFrame();
    }

    void CViewScroller::AdjustFrame()
    {
    mInfo.fMask = SIF_RANGE;
    mInfo.nMin = 0;

    CRect r;
    mSubject.GetWindowRect(r);

    SInt32 xRange = mImageSize.cx - (r.right-r.left);
    SInt32 yRange = mImageSize.cy - (r.bottom-r.top);

    SInt32 xScrollWidth = xRange > 0 ? ::GetSystemMetrics(SM_CXHSCROLL) : 0;
    SInt32 yScrollWidth = yRange > 0 ? ::GetSystemMetrics(SM_CYHSCROLL) : 0;

    SInt32 xBorder2 = ::GetSystemMetrics(SM_CXFRAME); // 4
    SInt32 yBorder2 = ::GetSystemMetrics(SM_CYFRAME);

    SInt32 xTotalWidth = xRange > 0 or yScrollWidth ? xRange + yScrollWidth : 0;
    SInt32 yTotalWidth = yRange > 0 or xScrollWidth ? yRange + xScrollWidth : 0;

    mInfo.nMax = xTotalWidth + ( xTotalWidth ? xBorder2 : 0 );
    mSubject.SetScrollInfo(SB_HORZ, &mInfo);

    mInfo.nMax = yTotalWidth + ( yTotalWidth ? yBorder2 : 0 );
    mSubject.SetScrollInfo(SB_VERT, &mInfo);

    this->UpdateCurrentPostion();
    }

    void CWndScroller::AdjustFrame()
    {
    mInfo.fMask = SIF_RANGE;
    mInfo.nMin = 0;

    CRect r;
    mSubject.GetWindowRect(r);

    SInt32 xRange = mImageSize.cx - (r.right-r.left);
    SInt32 yRange = mImageSize.cy - (r.bottom-r.top);

    SInt32 hScrollHeight = ::GetSystemMetrics(SM_CYHSCROLL);
    SInt32 vScrollWidth = ::GetSystemMetrics(SM_CXVSCROLL);

    SCROLLINFO info;
    mSubject.GetScrollInfo( SB_VERT, &info );
    if ( info.nPage != 0 ) xRange += vScrollWidth;

    mSubject.GetScrollInfo( SB_HORZ, &info );
    if ( info.nPage != 0 ) yRange += hScrollHeight;

    mInfo.nMax = xRange;
    mSubject.SetScrollInfo(SB_HORZ, &mInfo);

    mInfo.nMax = yRange;
    mSubject.SetScrollInfo(SB_VERT, &mInfo);

    this->UpdateCurrentPostion();
    }

    void CWndScroller::UpdateCurrentPostion()
    {
    mSubject.GetScrollInfo(SB_HORZ, &mInfo);
    mCurrentPos.x = mInfo.nPos;
    mSubject.GetScrollInfo(SB_VERT, &mInfo);
    mCurrentPos.y = mInfo.nPos;
    }

    bool CWndScroller::OnScroll(int inBar, UInt sbCode, UInt pos, CScrollBar *bar)
    {
    if (bar) return false; // why should bar be null ??

    mSubject.GetScrollInfo(inBar, &mInfo);
    switch (inBar)
    {
    case SB_HORZ:
    switch (sbCode)
    {
    case SB_LINEDOWN:
    mInfo.nPos += mLineSize.cx;
    if (mInfo.nPos > mImageSize.cx) mInfo.nPos = mImageSize.cx;
    break;
    case SB_LINEUP:
    mInfo.nPos -= mLineSize.cx;
    if (mInfo.nPos < 0) mInfo.nPos = 0;
    break;
    case SB_THUMBPOSITION:
    case SB_THUMBTRACK:
    mInfo.nPos = pos;
    break;
    case SB_PAGEDOWN:
    mInfo.nPos += mPageSize.cx;
    if (mInfo.nPos > mImageSize.cx) mInfo.nPos = mImageSize.cx;
    break;
    case SB_PAGEUP:
    mInfo.nPos -= mPageSize.cx;
    if (mInfo.nPos < 0) mInfo.nPos = 0;
    break;
    }
    mCurrentPos.x = mInfo.nPos;
    break;
    case SB_VERT:
    switch (sbCode)
    {
    case SB_LINEDOWN:
    mInfo.nPos += mLineSize.cy;
    if (mInfo.nPos > mImageSize.cy) mInfo.nPos = mImageSize.cy;
    break;
    case SB_LINEUP:
    mInfo.nPos -= mLineSize.cy;
    if (mInfo.nPos < 0) mInfo.nPos = 0;
    break;
    case SB_THUMBPOSITION:
    case SB_THUMBTRACK:
    mInfo.nPos = pos;
    break;
    case SB_PAGEDOWN:
    mInfo.nPos += mPageSize.cy;
    if (mInfo.nPos > mImageSize.cy) mInfo.nPos = mImageSize.cy;
    break;
    case SB_PAGEUP:
    mInfo.nPos -= mPageSize.cy;
    if (mInfo.nPos < 0) mInfo.nPos = 0;
    break;
    }
    mCurrentPos.y = mInfo.nPos;
    break;
    }
    return mSubject.SetScrollInfo(inBar, &mInfo);
    }

    void CWndScroller::OnKeyDown(UINT nChar, UINT, UINT)
    {
    switch (nChar)
    {
    case VK_HOME:
    this->OnScroll(SB_VERT, SB_TOP, 0, NULL);
    this->OnScroll(SB_HORZ, SB_LEFT, 0, NULL);
    break;
    case VK_END:
    this->OnScroll(SB_VERT, SB_BOTTOM, 0, NULL);
    this->OnScroll(SB_HORZ, SB_RIGHT, 0, NULL);
    break;
    case VK_UP:
    this->OnScroll(SB_VERT, SB_LINEUP, 0, NULL);
    break;
    case VK_DOWN:
    this->OnScroll(SB_VERT, SB_LINEDOWN, 0, NULL);
    break;
    case VK_PRIOR:
    this->OnScroll(SB_VERT, SB_PAGEUP, 0, NULL);
    break;
    case VK_NEXT:
    this->OnScroll(SB_VERT, SB_PAGEDOWN, 0, NULL);
    break;
    case VK_LEFT:
    this->OnScroll(SB_HORZ, SB_LINELEFT, 0, NULL);
    break;
    case VK_RIGHT:
    this->OnScroll(SB_HORZ, SB_LINERIGHT, 0, NULL);
    break;
    default:
    break;
    }
    }

    void CWndScroller::ResizeParentToFit(BOOL bShrinkOnly)
    {
    // adjust parent rect so client rect is appropriate size
    // ASSERT(m_nMapMode != MM_NONE); // mapping mode must be known
    CSize m_totalDev = mImageSize;

    // determine current size of the client area as if no scrollbars present
    CRect rectClient;
    mSubject.GetWindowRect(rectClient);
    CRect rect = rectClient;
    mSubject.CalcWindowRect(rect);
    rectClient.left += rectClient.left - rect.left;
    rectClient.top += rectClient.top - rect.top;
    rectClient.right -= rect.right - rectClient.right;
    rectClient.bottom -= rect.bottom - rectClient.bottom;
    rectClient.OffsetRect(-rectClient.left, -rectClient.top);
    ASSERT(rectClient.left == 0 && rectClient.top == 0);

    // determine desired size of the view
    CRect rectView(0, 0, m_totalDev.cx, m_totalDev.cy);
    if (bShrinkOnly)
    {
    if (rectClient.right <= m_totalDev.cx)
    rectView.right = rectClient.right;
    if (rectClient.bottom <= m_totalDev.cy)
    rectView.bottom = rectClient.bottom;
    }
    mSubject.CalcWindowRect(rectView, CWnd::adjustOutside);
    rectView.OffsetRect(-rectView.left, -rectView.top);
    ASSERT(rectView.left == 0 && rectView.top == 0);
    if (bShrinkOnly)
    {
    if (rectClient.right <= m_totalDev.cx)
    rectView.right = rectClient.right;
    if (rectClient.bottom <= m_totalDev.cy)
    rectView.bottom = rectClient.bottom;
    }

    // dermine and set size of frame based on desired size of view
    CRect rectFrame;
    CFrameWnd* pFrame = mSubject.GetParentFrame();
    ASSERT_VALID(pFrame);
    pFrame->GetWindowRect(rectFrame);
    CSize size = rectFrame.Size();
    size.cx += rectView.right - rectClient.right;
    size.cy += rectView.bottom - rectClient.bottom;
    pFrame->SetWindowPos(NULL, 0, 0, size.cx, size.cy,
    SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE);
    }

    void CWndScroller::EraseEmptyRgn()
    {

    CRect winRect;
    mSubject.GetWindowRect(winRect);
    winRect.OffsetRect(-winRect.left, -winRect.top);

    Rect portRect, vertRect, horzRect;
    RgnHandle vertRgn = nil;
    RgnHandle horzRgn = nil;
    RgnHandle finalRgn = nil;
    ARectToRect(winRect, portRect);

    if (mImageSize.cx < winRect.right-winRect.left)
    {
    ::MacSetRect(&vertRect, mImageSize.cx, 0, portRect.right, portRect.bottom);
    vertRgn = ::NewRgn();
    ::RectRgn(vertRgn, &vertRect);
    finalRgn = vertRgn;
    }
    if (mImageSize.cy < winRect.bottom-winRect.top)
    {
    ::MacSetRect(&horzRect, 0, mImageSize.cy, portRect.right, portRect.bottom);
    horzRgn = ::NewRgn();
    ::RectRgn(horzRgn, &horzRect);
    finalRgn = horzRgn;
    }
    if (vertRgn and horzRgn)
    {
    ::MacUnionRgn(vertRgn, horzRgn, horzRgn);
    }
    if (finalRgn)
    {
    RGBColor c = {65535, 65535, 65535};
    ::RGBForeColor(&c);
    ::RGBBackColor(&c);
    ::EraseRgn(finalRgn);
    }
    if (vertRgn) :isposeRgn(vertRgn);
    if (horzRgn) :isposeRgn(horzRgn);
    }

    // declare a view or control

    class CMyWnd : public CWnd
    {
    public:
    CMyWnd() : mScroller(*this);
    protected:
    CWndScroller mScroller;
    // CViewScroller mScroller;
    }

    // these are example overrides and message mappings
    // mQT is my interal representation of a QuickTime graphic
    // do whatever translations you need to do

    bool CMyWndMakeFit(SInt32 resizeStyle, bool inRefresh)
    {
    mScroller.ScrollTo(0, 0);
    if (mQT) mQT->TranslateTo(0, 0);

    if (not mQT) resizeStyle = resize_NoQT;
    switch (resizeStyle)
    {
    case resize_ImageToQT:
    if (mQT->Ready())
    {
    SDimension16 p;
    mQT->GetVisualSize(p);
    if (inRefresh) this->Invalidate(true);
    CSize sizeTotal(p.width, p.height);
    CSize sizePage(sizeTotal.cx / 2, sizeTotal.cy / 2);
    CSize sizeLine(sizeTotal.cx / 50, sizeTotal.cy / 50);
    mScroller.SetScrollSizes(sizeTotal, sizePage, sizeLine);
    if (inRefresh) this->OnNcPaint();
    return true;
    }
    break;
    case resize_QTToView:
    if (mQT->Ready())
    {

    return true;
    }
    break;
    case resize_ViewToQT:
    if (mQT->Ready())
    {
    SDimension16 p;
    mQT->GetVisualSize(p);
    CSize sizeTotal(p.width, p.height);
    CSize sizePage(0, 0);
    CSize sizeLine(0, 0);
    mScroller.SetScrollSizes(sizeTotal, sizePage, sizeLine);

    mScroller.ResizeParentToFit();
    if (inRefresh) this->OnNcPaint();
    return true;
    }
    break;
    case resize_NoQT:
    {
    CSize sizeTotal(0, 0);
    CSize sizePage(0, 0);
    CSize sizeLine(0, 0);
    mScroller.SetScrollSizes(sizeTotal, sizePage, sizeLine);
    if (inRefresh) this->OnNcPaint();
    return true;
    }
    break;
    case resize_None:
    if (inRefresh) this->OnNcPaint();
    return true;
    break;
    }
    return false;
    }


    void CMyWnd OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
    {
    mScroller.OnKeyDown(nChar, nRepCnt, nFlags);
    }

    void CMyWnd::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
    if (mScroller.OnScroll(SB_HORZ, nSBCode, nPos, pScrollBar))
    {
    CPoint p = mScroller.GetPosition();
    if (mQT) mQT->TranslateTo(-p.x, -p.y);
    this->OnNcPaint();
    }
    }

    void CMyWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
    if (mScroller.OnScroll(SB_VERT, nSBCode, nPos, pScrollBar))
    {
    CPoint p = mScroller.GetPosition();
    if (mQT) mQT->TranslateTo(-p.x, -p.y);
    this->OnNcPaint();
    }
    }

    void CMyWnd::OnSize(UINT nType, int cx, int cy)
    {
    CWnd::OnSize(nType, cx, cy);
    if ((mResizeStyle == resize_ViewToQT or mResizeStyle == resize_QTToView) and mQT)
    {
    SDimension16 p = { cx, cy };
    mQT->ChangeVisualSize(p);
    CSize s(cx, cy);
    mScroller.ResizeImage(s);
    }
    else
    {
    CPoint p = mScroller.GetPosition();
    mScroller.AdjustFrame();
    }
    }





    I hope this code works for you.

    Dave


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