Breaking the CScrollView 32768 size limitation with CBigScrollView

For true graphic applications, it is necessary to zoom into the view to see details of the drawing. Using CScrollView to minimize programming effort, the only way to do this is to set the scroll size bigger according to the zoom factor. As an example, if you have an A4 document size (210mm x 296mm), you can tell CSrollView that your document size is 420mm x 592mm so you have a zoom of 2. To do this, simply call SetScrollSizes(MM_LOMETRIC, CSize(4200, 5920)). When doing this, we have a problem. The maximal size of CScrollView is 32768 x 32768. In other words, the zoom is limited to 32768/2960=11.07.

bigscroll1.gif

Extending the scroll size capability.

To surpass the limitation of CScrollView, it is possible to calculate a new CBigScrollView size that surpass the limitation of 32768 and calculate the origin of the CScrollView inside this new virtual size.

bigscroll2.gif

Using CScrollView to scroll, the client size moves only into CScrollView size. Reaching the sides of CScrollView size, the CScrollSize moves into CBigScrollView size. The only problem doing this it that the scroll bars doesn't reflect the CBigScrollView size but the CScrollSize instead. This is acceptable else it is necessary to rewrite entirely CScrollView. Zoom is limited to 2,147,483,648/2960=725.50.

CBigScrollView has the same properties than CScrollView. You can set the mapping mode like CScrollView. CBigScrollView doesn't use float type but only long type. No float arithmetic is made.

A problem using GDI functions is that clipping is doing only in valid range. When you draw a line into virtual range, you are responsible to clip the line into valid range like client rectangle or CScrollView size. This sample implements a line-clipping algorithm.

Using CBigScrollView to Zoom into the view.

This sample use CBigScrollView to implement a CAppScrollView view with Zoom capabilities. MM_LOMETRIC is used as mapping mode but you can use any valid mapping mode.

A problem zooming into the view is that the user expects that the center of the client size remains the same. To do this, it is necessary to save the center of the client size before zooming and restore it after this. This is true also when resizing the window.

This sample implements Zoom In, Zoom Out, Zoom Default, Zoom with rectangle and hand move functions. In Hand mode, when pressing the left mouse button, you can move the view. In the other mode selected with the toolbar or the right button, you can select a zooming rectangle.

Changing document size with Printer setup.

For true graphic applications, it is necessary to set the document size according to the printer paper size. This sample reflects exactly the paper size. If you change the orientation or the paper size, a message is send to the document to update views.

Download demo application (without source)- 15 KB

Download demo project - 75 KB

Date Last Updated: February 14, 1999



Comments

  • CMyiew (this is all you have to do

    Posted by Legacy on 11/21/2003 12:00am

    Originally posted by: youfenman

    BOOL 
    
    CMyiew::OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll)
    {
    if (GetTotalSize().cx >= SHRT_MAX || GetTotalSize().cy >= SHRT_MAX )
    {
    SCROLLINFO info;
    info.cbSize = sizeof(SCROLLINFO);
    info.fMask = SIF_TRACKPOS;

    //nPos is valid only is scroll code is SB_THUMBTRACK
    if (LOBYTE(nScrollCode) == SB_THUMBTRACK)
    {
    GetScrollInfo(SB_HORZ, &info);
    nPos = info.nTrackPos;
    }
    else if (HIBYTE(nScrollCode) == SB_THUMBTRACK)
    {
    GetScrollInfo(SB_VERT, &info);
    nPos = info.nTrackPos;
    }
    }

    BOOL ret = CScrollView::OnScroll(nScrollCode, nPos, bDoScroll);


    return ret;
    }

    Reply
  • BigScrl still doesn't scroll correctly

    Posted by Legacy on 07/31/2003 12:00am

    Originally posted by: Tim

    This program still has a problem with scrolling, so I don't know how it's going to help anyone. When you zoom in beyond the 32K limit, and then you try to scroll to the edges, you can't. You're forced to use the grabby hand, and then the scroll bars reposition and allow you to continue scrolling to the hidden edge. Try it!

    Does anyone know how to make it so you can zoom all the way in and scroll to all four edges using only the scroll bars?

    Reply
  • Drawing problems

    Posted by Legacy on 05/15/2003 12:00am

    Originally posted by: Sabotto Massimo

    Very very Great work! Thank you for sharing the code.
    I'm experiencing problems on using your class in an MFC app.
    I only substituted your demo drawing code with GDI+ functions that draw images on screen. Nothing appears!.
    The drawing function return success so I think I'm doing something wrong but I don't know what and where!
    Have you got some ideas or any suggestions?
    Should your class work with any system metrics?

    Thank you in advance

    Massimo

    Reply
  • Fix when scroll bars are hidden

    Posted by Legacy on 04/24/2003 12:00am

    Originally posted by: Mark Husted

    Great piece of work! It truly saved me a lot of time to get the type of functionality that you have here.

    I did find one problem; when you maximize the screen and the horizontal scrool bar is hidden, you could still grab the image with the HandTracker and move it horizontally. It does not crash, but it does mess up the picture. I found the problem and provide a solution.

    It appears that when the screen is maximized, the scroll bar is hidden, but not disabled. Thus if you start tracking around the screen the MS CScrollView code still believes that there is a horizontal scroll bar with the size set to the last value when it was visible.

    The solution was to duplicate some code that is buried in CScrollView in the CBigScrollView::OnSize function that tests to see if the scroll bars are needed. If they are not, then I update the scroll bar info with the new size. It is not the cleanest solution, but it works.

    I pasted the modified OnSize function below:

    void CBigScrollView::OnSize(UINT nType, int cx, int cy)
    {
    CScrollView::OnSize(nType, cx, cy);

    ///////////////////////////////////
    //
    // added to help determine if the scrollbar

    CPoint ptMove;
    CSize needSb;
    CSize sizeRange;
    CSize sizeClient;
    CSize sizeSb;

    GetTrueClientSize(sizeClient, sizeSb) ;

    // get the current scroll bar state given the true client area
    GetScrollBarState(sizeClient, needSb, sizeRange, ptMove, TRUE);
    if( !needSb.cx )
    {
    SCROLLINFO info;
    info.fMask = SIF_PAGE|SIF_RANGE;
    info.nMin = 0;
    info.nPage = sizeClient.cx;
    info.nMax = m_totalDev.cx-1;
    SetScrollInfo(SB_HORZ, &info, TRUE);
    }

    if( !needSb.cy )
    {
    SCROLLINFO info;
    info.fMask = SIF_PAGE|SIF_RANGE;
    info.nMin = 0;
    info.nPage = sizeClient.cy;
    info.nMax = m_totalDev.cy-1;
    SetScrollInfo(SB_VERT, &info, TRUE) ;

    }

    //
    // END ADDED CODE
    ////////////////////////////////////////////

    // if ScrollView is not initialized, exit
    if (m_nMapMode == MM_NONE) return;

    // if changing size, restore client center
    if (nType == SIZE_RESTORED || nType == SIZE_MAXIMIZED)
    if (IsWindowVisible())
    RestoreClientCenter();
    }

    If you add this, it will help the viewed area behave a little better.

    Reply
  • Initial value for CBigScrollview

    Posted by Legacy on 11/13/2001 12:00am

    Originally posted by: Natz

    Great source for standard application that uses any paper size as the inital document size.
    For my application i need the size of the actual view as the inital document size. So my output has always the extention of the view or if it is zoomed it is bigger. Resizing the view means to resizing m_sizeDoc. I've made a lot of tests but i get no good result.
    It would be nice if you can give me a short tip how i can change your source so that the inital m_sizeDoc is not a value of a papersize but of the viewsize.

    Reply
  • It is possible to load image using the view

    Posted by Legacy on 03/20/2000 12:00am

    Originally posted by: Venkatesh N.K.

    Please help me to load image(BMP)using this (Zoomin & Zoomout) option with scrollview

    Reply
  • Project is not full

    Posted by Legacy on 01/28/2000 12:00am

    Originally posted by: VOX

    Where are THE HEADER's files?

    Reply
  • About Scroll function

    Posted by Legacy on 05/27/1999 12:00am

    Originally posted by: John

    I found you are very familiar with the Scroll function, I have a question:
    
    I try to add a control into a dialog. The function of the control
    is similar to the CScrollView. But I found that I cannot
    use CScrollView as the basic class of the control.
    So I use Cwnd and declare class CscrollCtrl:public CWnd;
    I added the scrollbar into the control.
    But the problem is I really don't know how to do this.
    such as, if the client area (visible area) of the class(CscrollCtrl)
    is ((0,0),(100,100)), how to setup the scroll area as ((0,0),(200,200))?
    and then, how to use CDC member function (such as Line(..)) to draw in that scroll area?
    finally, how to show such unvisible area in the scroll area when call OnHScroll(..), OnVScroll(..)

    If you can teach me that, please tell me ASAP. If you can, could u provide some simple sample code?
    I really appreciate that!
    Thanks very much!

    Reply
  • Only 16bit problem

    Posted by Legacy on 02/15/1999 12:00am

    Originally posted by: ray auchterlounie

    This limit to +/- 32k for coordinates only affects 16bit Windows - which unfortunately includes 95/98 (this is just one of many indications that they are still 16bit).

    On NT / Windows2000 the limits are +/- 2GB.

    Also it should perhaps be noted that _all_ GDI coordinates (not just line drawing as mentioned in the article) need to be clipped if outside the valid range - otherwise the 16bit GDI layers will simply truncate them into the valid range, which won't be the desired result.

    ray

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: August 14, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Data protection has long been considered "overhead" by many organizations in the past, many chalking it up to an insurance policy or an extended warranty you may never use. The realities of today make data protection a must-have, as we live in a data driven society. The digital assets we create, share, and collaborate with others on must be managed and protected for many purposes. Check out this upcoming eSeminar and join eVault Chief Technology …

  • Hybrid cloud platforms need to think in terms of sweet spots when it comes to application platform interface (API) integration. Cloud Velocity has taken a unique approach to tight integration with the API sweet spot; enough to support the agility of physical and virtual apps, including multi-tier environments and databases, while reducing capital and operating costs. Read this case study to learn how a global-level Fortune 1000 company was able to deploy an entire 6+ TB Oracle eCommerce stack in Amazon Web …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds