HomeC&C++WainTutorialsSamplesTip&TrickTools


Next we will learn how the user can draw lines on the window.
First we create a class that implements one line:
class LineClass
{
public:
   LineClass(POINT aStart, POINT aEnd) :
      Start(aStart), End(aEnd)
   {}
   POINT Start;
   POINT End;
   void Draw(HDC &dc);
};
The constructor takes two POINTS as arguments, the start and end point.
The Draw function is ment to draw the line on the device context, it could be implemented as:
void LineClass::Draw(HDC &dc)
{
   HPEN Pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
   HPEN OldPen = (HPEN )SelectObject(dc, Pen);
   MoveToEx(dc, Start.x, Start.y, 0);
   LineTo(dc, End.x, End.y);
   SelectObject(dc, OldPen);
}
We will use a std::vector to hold the list of lines:
std::vector<LineClass >Lines;
For this first version we will do it the simple way. When the user press the left button, we will store the mouse point as the start, when he release the button we will use the mouse point as end, and draw the line. The user can thus not see the line while draging the mouse.
We need to handle the mouse down and up events:
      case WM_LBUTTONDOWN:
         OnLButtonDown(hwnd, LOWORD(lParam), HIWORD(lParam));
         break;
      case WM_LBUTTONUP:
         OnLButtonUp(hwnd, LOWORD(lParam), HIWORD(lParam));
         break;
LOWORD(lParam is the x coordinate for the mouse, HIWORD(lParam) is the y coordinate.
Our OnLButtonDown function could look like this:
POINT CurStart;
bool IsDrawing;

void OnLButtonDown(HWND aHwnd, int aX, int aY)
{
   CurStart.x = aX;
   CurStart.y = aY;
   IsDrawing = true;
}
And the OnLButtonUp function:
void OnLButtonUp(HWND aHwnd, int aX, int aY)
{
   if(IsDrawing)
   {
      POINT End;
      End.x = aX;
      End.y = aY;
      LineClass Line(CurStart, End);
      HDC dc = GetDC(aHwnd);
      Line.Draw(dc);
      ReleaseDC(aHwnd, dc);
      IsDrawing = false;
      Lines.push_back(Line);
   }
}
We create a Line object, ask it to draw itself, and add it to the list of lines.
Now we are allmost done, but if another window popup in front of ours, we have to draw the lines when our application becomes visible again.
For this purpose we must handle the WM_PAINT event:
      case WM_PAINT:
         OnPaint(hwnd);
         break;
The OnPaint function must draw all the lines:
void OnPaint(HWND aHwnd)
{
   PAINTSTRUCT PaintStruct;
   BeginPaint(aHwnd, &PaintStruct);
   size_t i;
   for(i = 0; i < Lines.size(); i++)
      Lines[i].Draw(PaintStruct.hdc);
   EndPaint(aHwnd, &PaintStruct);
}
Notice that we call BeginPaint() and EndPaint(). They must be called for the WM_PAINT event and only for the WM_PAINT event.
The complete code for the application can be found here