3: Using Messages

Win32++

Tutorials

Menu of tutorials

Tutorial 1:   The Simplest WindowTutorial 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: 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 uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_LBUTTONDOWN:
        OnLButtonDown(lParam);
        break;

    case WM_MOUSEMOVE:
        OnMouseMove(wParam, lParam);
        break;

    case WM_LBUTTONUP:
        OnLButtonUp(lParam);
        break;
    }

    //Use the default message handling for remaining messages
    return WndProcDefault(uMsg, 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.

void CView::OnLButtonDown(LPARAM lParam)
{
  // Capture mouse input.
  SetCapture();

  m_OldPt.x = GET_X_LPARAM(lParam);
  m_OldPt.y = GET_Y_LPARAM(lParam);
}
void CView::OnLButtonUp(LPARAM lParam)
{
  {
    //Release the capture on the mouse
    ReleaseCapture();
  }
}
void CView::OnMouseMove(WPARAM wParam, LPARAM lParam)
{
  // hold down the left mouse button and move mouse to draw lines.
  if (wParam & MK_LBUTTON)
  {
    DrawLine(LOWORD(lParam), HIWORD(lParam));
    m_OldPt.x = GET_X_LPARAM(lParam);
    m_OldPt.y = GET_Y_LPARAM(lParam);
  }
}

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.