Scrolling and Zooming in a CDialog-Derived Class

Recently, I needed to implement scrolling and zooming in a property page. The property page was too specific, so I thought why not implement them in a CDialog-derived class and present it here in the form of an article?

Now, where do I look for code? As a matter of fact, the CScrollView class, which implements scrolling, already exists. So, I literally copied code from CScrollView into my CDialog-derived class. However, I had to make some minor adjustments to make it work with the CDialog-derived class.

For scrolling, CScrollView works in conjunction with a private MFC class called _AFX_MOUSEANCHORWND that is derived from CWnd. You can find the class declaration and implementation of _AFX_MOUSEANCHORWND in “viewscrl.cpp” that can be found inside MFC’s src folder. Now, _AFX_MOUSEANCHORWND works specifically with CScrollView class; this is evident from its Create function declaration.

BOOL Create(CScrollView* pParent);

In the function above, you can see the the pParent’s type is CScrollView. Initially, I thought of deriving my own mouse anchor wnd class from _AFX_MOUSEANCHORWND, but because the class is declared in an implementation file (viewscrl.cpp) and if I included a .cpp file, it might create more hassles than necessary, I chose instead to create an entirely new class, DlgMouseAnchorWnd (derived from CWnd), that works with CDialog.

Hence, my Create function now looks like this:

BOOL Create(CDialog* pParent)

Throughout the whole code, the afxData variable is used. This is a global data that my MFC uses internally. So, to use this variable, you have to include a file called “afximpl.h” appropriately in your “stdafx.h”.

Note: This file is not present in the usual MFC’s include folder. So, you might need to provide the path to the “afximpl.h” file in Additional Include Directories in project settings.

For the scrolling to work, you just have to call the SetScrollSizes function from the OnInitDialog method the same way that you call SetScrollSizes from the OnInitialUpdate function for the CScrollView class.

Now for zooming, there is the OnZoom public function that is declared as shown below:

void OnZoom(int x, int y, double ZoomFactor);

If you supply ZoomFactor 1.0, it neither zooms in nor zooms out.

For zooming in, use a ZoomFactor greater than 1.0; for zooming out, use a ZoomFactor of less than 1.0. You can, in fact, zoom out so much that the scroll bars turn invisible and by zooming in again, you can see the scroll bars.

I have handled the left mouse button click and right mouse button click to do the zooming. When you click the left mouse button, it does zoom in, and upon right-clicking, it does zoom out.

The following are the two functions:

void CScroomDialogDlg::OnLButtonDown(UINT nFlags, CPoint point)
   // TODO: Add your message handler code here and/or call default
   OnZoom(point.x, point.y, 1.4);
   CDialog::OnLButtonDown(nFlags, point);
}

void CScroomDialogDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
   // TODO: Add your message handler code here and/or call default
   OnZoom(point.x, point.y, 0.714285);
   CDialog::OnRButtonDown(nFlags, point);
}

I hope you enjoyed the article. The demo application and the source are provided here. Thank you!!!

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read