Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Using the new MFC7/ATL7 shared classes.

0.00/5 (No votes)
15 Oct 2001 1  
This example demonstrates using the new shared ATL/MFC classes such as CPoint, CRect, CSize and CString

Sample Image - SharedClasses.gif

Introduction

Beginning with Visual C++ .NET 7.0, CPoint, CRect, CSize, CString, CImage classes have been written to be library-independent. These classes can be used in either MFC or ATL projects, or in projects that do not use either of these libraries.

This article presents an application called SharedClasses that is a Win32 Project generated by the AppWizard. The application handles mouse input and draws an ellipse based on the mouse movement. The shared MFC/ATL classes are used throughout the application.

The demo app

To draw the ellipse press the left mouse button (it will be the center of the ellipse) and move the mouse while holding the button. The status line at the top of the window shows the center coordinates and the ellipse's dimension (width and height).

The AppWizard generate an application that implements simple window. To add new functionality we have to modify window the procedure (WndProc) function.

We will be using the CString and CRect classes, so to add support for it we need to include the following headers:

#include <atltypes.h>	// CPoint, CRect, CSize support.

#include <atlstr.h>	// CString support.

we also need to include Windowsx.h to use GET_X_LPARAM and GET_Y_LPARAM macros.

#include <Windowsx.h>	// GET_X_LPARAM and GET_Y_LPARAM defined there.

To track mouse input let's add a CRect type variable.

CRect rectEllipse;	// Rectangle to track mouse movement.

To keep status line text we use a CString class.

CString strCoord;	// String to print ellipse coordinates and dimensions.

We also need a flag to keep the state of the left mouse button.

bool bLBtnPressed = false;	// Flag to keep left mouse button state.

To track the mouse input we handle three windows messages: WM_LBUTTONDOWN, WM_LBUTTONUP, and WM_MOUSEMOVE.

Just add following code to the end of switch statement inside WndProc, just before the default label:

case WM_LBUTTONDOWN:
	// Save beginning point.

	rectEllipse.left = GET_X_LPARAM(lParam); 
	rectEllipse.top = GET_Y_LPARAM(lParam);

	// Set flag that keeps mouse button state.

	bLBtnPressed = true;

	// Capture mouse input.

	::SetCapture(hWnd);
	break;

case WM_LBUTTONUP:
	// Reset flag that keeps mouse button state.

	bLBtnPressed = false;

	// Release mouse input.

	::ReleaseCapture();

	// Redraw window.

	::InvalidateRect(hWnd, NULL, TRUE);
	::UpdateWindow(hWnd);
	break;

case WM_MOUSEMOVE:
	// If mouse button is pressed update rectangle that

	// tracks mouse movement with new coordinates,

	// and redraw window.

	if(bLBtnPressed)
	{
		rectEllipse.right = GET_X_LPARAM(lParam); 
		rectEllipse.bottom = GET_Y_LPARAM(lParam);

		::InvalidateRect(hWnd, NULL, TRUE);
		::UpdateWindow(hWnd);
	}
	break;

In the WM_LBUTTONDOWN message handler we store the coordinates of the point where the user pressed the left mouse button. This will be the center of our ellipse. We set the flag that stores mouse button state and capture the mouse input so as to handle mouse input even when it is outside the window.

The WM_MOUSEMOVE message handler checks the state of the mouse button. If it is pressed it updates our rectangle (our CRect class object) with the new mouse coordinates and redraws the window. If the mouse button is not pressed, it does nothing.

In the WM_LBUTTONUP handler we just update the flag that keeps the mouse button state and release the mouse capture. Inside it just draws the ellipse according to the coordinates stored in the CRect object and formats and prints a status string to show information for the ellipse, namely center coordinates and dimensions.

In order to draw our ellipse we have to modify WM_PAINT message handler:

// Draw the ellipse using coordinates from mouse input.

::Ellipse(	hdc, 
		rectEllipse.left - rectEllipse.Width(),
		rectEllipse.top - rectEllipse.Height(),
		rectEllipse.left + rectEllipse.Width(),
		rectEllipse.top + rectEllipse.Height());

// If ellipse is not a dot or line, print center coordinates

// and dimensions. Otherwise print prompt to draw ellipse.

if(rectEllipse.Width() != 0 && rectEllipse.Height() != 0)
{
	strCoord.Format(_T("Center coordinates %d,%d     X-size %d, Y-Size %d"),
			rectEllipse.left,
			rectEllipse.top,
			2 * rectEllipse.Width(),
			2 * rectEllipse.Height());
}
else
	strCoord = _T("Use your mouse to draw ellipse in the window");
::TextOut(hdc, 5, 5 , strCoord, strCoord.GetLength());

History

16 Oct 2001 - updated files for VS beta 2

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here