CScrollView comes in handy whenever you need to provide scrolling capability to your view. However, there are several limitations. First,
CScrollView is derived from
CView, so it is designed to work with the document-view architecture. If you attempt to nest a
CScrollView inside a normal
CWnd or a
CDialog, you will get into a big heap of trouble. If your application requires simple and lightweight scrolling support,
CScrollView becomes awkward and costly. Second, the size of the scrolling region is bound to the signed 16-bit limit. Your application may require painting on a large logical area. A map editor or a graphics design application is a good example for such a situation.
CScrollWindow was created to address the above problems.
Basing on the MFC source code of
CScrollView, I made some modifications to achieve my targets. To avoid creating bugs, I tried to make as few changes as possible. However, I know that I am just as imperfect as
CScrollWindow, so bugs may still exist.
CScrollView, my class
CScrollWindow is derived from
CWnd so that it can be put inside any other
CWnd. If you want it on a view, nest it inside a
CView or any derived class. In this way, you can still make
CScrollWindow play nicely with the document-view architecture, of cource with more effort than if you use
CScrollView. However, flexibility is what you get in exchange for the effort.
CScrollView uses functions
DPtoLP to convert points from device unit to logical unit and vice versa. These functions accept only 16-bit values. Therefore, you get errors when your total width or height is greater than
32767. To avoid these errors, I do not use these functions, which means that
CScrollWindow does not support mapping modes. The only supported unit of length is pixel. If you want to support other units of measure or even zooming, you have to implement it on your own, given the background that
CScrollWindow provides to you.
One important point is that
uses 16-bit position data provided by
CScrollWindow instead calls
GetScrollInfo to get 32-bit position data.
Using the Code
CScrollWindow works with any
CWnd and derivatives, including
CDialog, I embed it in a
CFrameWnd in the demo project in this article. You would typically add a member of the type
CScrollWindow or derivatives in your
OnCreate of your
CFrameWnd, create the scroll window and set the scroll sizes.
if (!m_ScrollWindow.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
TRACE0("Failed to create scroll window\n");
Running the Demo
The demo creates a scroll window with a large total size. Scroll around using the scroll bars to verify that you can view any part of the total area.
March 23, 2008
- Uploaded the first version
September 12, 2015
- Changed the project name from
- Converted the project format so that it can be built in Visual Studio 2008
- Removed the
SystemInformation class, thereby simplifying the code
- Modified the drawing code in the demo project
- Revised the tip