Tutorials

 

Home
About
How it Works
Documentation
Tutorials

Examples

Links
Contact

 

 

Menu of tutorials

Tutorial 1:   The Simplest Window
Tutorial 2:   Using Classes and Inheritance
Tutorial 3:   Using Messages to Create a Scribble Window
Tutorial 4:   Repainting the Window
Tutorial 5:   Wrapping a Frame around our Scribble Window
Tutorial 6:   Customising Window Creation
Tutorial 7:   Customising the ToolBar
Tutorial 8:   Loading and Saving Files
Tutorial 9:   Printing
Tutorial 10: Print Previewing
Tutorial 11: Finishing Touches

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.