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 11. Sample: Simple Paint<br />

DWORD nCount;<br />

DWORD nRgnSize;<br />

RECT rcBound;<br />

} RGNDATAHEADER;<br />

Member dwSize specifies the size of this header, and the iType specifies the region type, whose value<br />

must be RDH_RECTANGLES, which means that the region is made up of a number of rectangles. Member<br />

nCount specifies the number of rectangles contained in this region, and rcBound specifies the bounding<br />

rectangle. In order to scale the region, we need to implement a loop, and scale the corresponding rectangle<br />

whose data is contained in the data buffer within each loop.<br />

If we simply want to offset the region, there is a member function of CRgn that can be used to offset the<br />

whole region just like we can offset a rectangle:<br />

int CDC::OffsetClipRgn(int x, int y);<br />

int CDC::OffsetClipRgn(SIZE size);<br />

The region must be selected into a DC in order to call the above member functions.<br />

New Tool<br />

Sample 11.8\GDI is based on sample 11.6\GDI that implements freeform selection. In the sample, first<br />

a new command is added to toolbar IDR_DRAWTOOLBAR, whose ID is ID_BUTTON_FREESEL (Figure 11-12).<br />

Macro TOOL_HEAD_ID is redefined (it represents ID_BUTTON_FREESEL now) to allow this new tool be<br />

automatically considered for message mapping. In order to use old message handlers, the ID of the<br />

freeform selection tool is set to have the following relationship with other IDs:<br />

ID_BUTTON_FREESEL = ID_BUTTON_RECTSEL+1<br />

Figure 11-12. Freeform selection tool<br />

In class CGDIView, like rectangular selection command, we need to handle WM_LBUTTONDOWN,<br />

WM_LBUTTONUP and WM_MOUSEMOVE messages to implement freeform selection tool. In the sample, a new case<br />

is added to the switch statement within each message handler.<br />

Drawing rectangular outline and freeform outline is different. For rectangular selection, whenever<br />

mouse is moving, we erase the old rectangular outline and draw a new one using old mouse position<br />

(recorded when mouse left button was first pressed down) and current mouse position. For freeform<br />

selection, we do not need to erase the old outline: each time the mouse is moving, we just draw a line<br />

between the previous mouse position (recorded when WM_MOUSEMOVE was received last time) and the<br />

current mouse position. For this purpose, a new variable CGDIView::m_ptPrevious is declared, which will<br />

be used to record the previous mouse position. The current mouse position will be passed to the mouse<br />

message handler as a parameter. Since the outline is drawn in the client window, it needs to have a same<br />

ratio with the current displayed bitmap. However, to make it easy for copying and moving the selection, the<br />

path must be recorded with a ratio of 1:1 no matter what the current image ratio is. So for each mouse<br />

move, we must do the following two things: draw a line between the old mouse position and the current<br />

mouse position in the client window, then draw the same thing on the memory bitmap (CGDIView::<br />

m_bmpDraw) for path recording.<br />

To simplify outline drawing, a CPen type variable is declared in class CGDIView and is initialized in the<br />

constructor as follows:<br />

……<br />

……<br />

m_penDot.CreatePen(PS_DOT, 1, RGB(0, 0, 0));<br />

We will use dotted line to draw the outline of irregular selection while the mouse is moving.<br />

To record the selected region, a CRgn type variable is declared in class CGDIView. The following<br />

portion shows how freeform selection is handled after WM_LBUTTONDOWN message is received:<br />

359

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

Saved successfully!

Ooh no, something went wrong!