11.04.2014 Views

Advanced MFC Programming

Advanced MFC Programming

Advanced MFC Programming

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Chapter 8. DC, Pen, Brush and Palette<br />

Recording One Line<br />

When the left button is pressed down, we need to trace the mouse’s movement until it is released.<br />

During this period, it is possible that mouse may move outside the client window. To enable receiving<br />

mouse message even when it is outside the client window, we need to call function CWnd::SetCapture() to<br />

set window capture. This will direct all the mouse related messages to the window that has the capture no<br />

matter where the mouse is. After the left button is released, we need to call API function<br />

::ReleaseCapture() to release the capture.<br />

In class CGDIView, some new variables are declared to record the starting and ending points of the line<br />

and the window’s capture state:<br />

……<br />

class CGDIView : public CView<br />

{<br />

protected:<br />

CPoint m_ptStart;<br />

CPoint m_ptEnd;<br />

BOOL m_bCapture;<br />

BOOL m_bNeedErase;<br />

}<br />

Variables m_ptStart and m_ptEnd are used to record the starting and ending points of a line,<br />

m_bCapture indicates if the window has the capture. Variable m_bNeedErase indicates if there is an old<br />

outline that needs to be erased. After the user presses down the left button, the initial mouse position will be<br />

stored in variable m_ptStart. Then as the user moves the mouse with the left button held down, m_ptEnd<br />

will be used to store the updated mouse position. A new line is defined by both m_ptStart and m_ptEnd.<br />

The only situation that we don’t need to erase the old line is when m_ptEnd is first updated (before this, it<br />

does not contain valid data).<br />

Two Boolean type variables are initialized in the constructor of CGDIView:<br />

CGDIView::CGDIView()<br />

{<br />

m_bCapture=TRUE;<br />

m_bNeedErase=FALSE;<br />

}<br />

Message handlers of WM_LBUTTONDOWN, WM_MOUSEMOVE and WM_LBUTTONUP can all be added through<br />

using Class Wizard. In the sample, these member functions are CGDIView::OnLButtonDown(…),<br />

CGDIView:: OnMouseMove(…) and CGDIView::OnLButtonUp(…) respectively.<br />

Function CGDIView::OnLButtonDown(…) is implemented as follows:<br />

void CGDIView::OnLButtonDown(UINT nFlags, CPoint point)<br />

{<br />

m_ptStart=point;<br />

SetCapture();<br />

m_bCapture=TRUE;<br />

CView::OnLButtonDown(nFlags, point);<br />

}<br />

When the left button is pressed down, we need to store the current mouse position in m_ptStart. The<br />

second parameter of CView::OnLButtonDown(…) is the current mouse position measured in window’s own<br />

coordinate system, which can be stored directly to m_ptStart. After that, we can set window capture and<br />

set flag m_bCapture.<br />

When mouse is moving, we need to check if the left button is being held down. This can be<br />

implemented by examining the first parameter (nFlags) of function CView::OnMouseMove(…). If its<br />

MK_LBUTTON bit is set, the left button is being held down. We can also check other bits to see if SHIFT,<br />

CTRL key or mouse right button is being held down.<br />

If the left button is being held down, we need to draw the outline using the dotted pen. If there already<br />

exists an old outline, we need to erase it before putting a new one. To draw a line, we need to first call<br />

function CDC::MoveTo(…) to move the DC’s origin to the starting point of the line, then call<br />

205

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!