Tutorial 3: Using Messages to create a Scribble Application
Each external event that a window might need to respond to is sent to the
window by way of a message. Its now time to control the way our window
behaves by handling some of these messages. Each CWnd
object
handles its own messages in the WndProc
function. In this
example we will create a simple scribble program by handling the left mouse
button messages. We allow the user to draw on the window by responding to
the mouse messages. A line is drawn on the window when the user moves the
mouse while pressing the left mouse button down.
The WM_LBUTTONDOWN message is sent to the window when the left button is
clicked, and the cursor is over the window's client area. We capture the
mouse input and store the current mouse position in the m_oldPt
member variable.
The WM_MOUSEMOVE message is posted to a window when the cursor moves. If
the mouse is not captured, the message is posted to the window that contains
the cursor. Otherwise, the message is posted to the window that has captured
the mouse. We check that the left button is also down, and call
DrawLine to draw the line in the view window.
The WM_LBUTTTONUP message is sent to the window when the left mouse
button changed from down to up during mouse capture.
A window receives messages through its window procedure. We intercept
these messages and take our own actions by overriding the WndProc
function.
LRESULT CView::WndProc(UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (uMsg)
{
case WM_LBUTTONDOWN: return OnLButtonDown(msg, wparam, lparam);
case WM_MOUSEMOVE: return OnMouseMove(msg, wparam, lparam);
case WM_LBUTTONUP: return OnLButtonUp(msg, wparam, lparam);
}
// Use the default message handling for remaining messages.
return WndProcDefault(msg, wparam, lparam);
}
These are the definitions of the functions used in WndProc
.
When the WM_LBUTTONDOWN message is received, we use SetCapture
to capture the mouse input. This allows our window to receive the mouse
messages even if the mouse cursor is moved outside our window. We stop
capturing the mouse input with ReleaseCapture when the left mouse button is
released.
LRESULT CView::OnLButtonDown(UINT, WPARAM, LPARAM lparam)
{
// Capture mouse input.
SetCapture();
m_oldPt.x = GET_X_LPARAM(lparam);
m_oldPt.y = GET_Y_LPARAM(lparam);
return 0;
}
LRESULT CView::OnLButtonUp(UINT, WPARAM, LPARAM lparam)
{
UNREFERENCED_PARAMETER(lparam);
// Release the capture on the mouse.
ReleaseCapture();
return 0;
}
LRESULT CView::OnMouseMove(UINT, WPARAM wparam, LPARAM lparam)
{
// Hold down the left mouse button and move mouse to draw lines.
if (wparam & MK_LBUTTON)
{
DrawLine(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam));
m_oldPt.x = GET_X_LPARAM(lparam);
m_oldPt.y = GET_Y_LPARAM(lparam);
}
return 0;
}
The source code for this tutorial is located within the Tutorial folder
of the software available from SourceForge at
http://sourceforge.net/projects/win32-framework.