|
Using Filled Shapes
This section illustrates how to use filled shape functions. The example uses
the main window procedure from an application that enables the user to draw
ellipses, rectangles, and rectangles with rounded corners.
The user draws a filled shape by selecting a particular shape from the menu,
positioning the cursor at the upper left corner of the shape (or the shape's
bounding rectangle in the case of an ellipse), and then dragging the mouse until
the desired dimensions are obtained.
The following illustration shows three filled shapes drawn using the sample
code in this section.
To enable the user to draw filled shapes, include the following code in your
application.
LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)
HWND hwnd; /* handle of window */
UINT uMsg; /* message */
WPARAM wParam; /* first message parameter */
LPARAM lParam; /* second message parameter */
{
HDC hdc; /* handle of device context (DC) */
PAINTSTRUCT ps; /* paint data for Begin/EndPaint */
POINT ptClientUL; /* client area upper left corner */
POINT ptClientLR; /* client area lower right corner */
static HDC hdcCompat;/* handle of DC for bitmap */
static POINT pt; /* x- and y-coordinates of cursor */
static RECT rcTarget; /* rect to receive filled shape */
static RECT rcClient; /* client area rectangle */
static BOOL fSizeEllipse; /* TRUE if ellipse is sized */
static BOOL fDrawEllipse; /* TRUE if ellipse is drawn */
static BOOL fDrawRectangle; /* TRUE if rectangle is drawn */
static BOOL fSizeRectangle; /* TRUE if rectangle is sized */
static BOOL fSizeRoundRect; /* TRUE if rounded rect is sized */
static BOOL fDrawRoundRect; /* TRUE if rounded rect is drawn */
static int nEllipseWidth; /* width for round corners */
static int nEllipseHeight; /* height for round corners */
switch (uMsg) {
case WM_COMMAND:
switch (wParam) {
/*
* Set the appropriate flag to indicate which
* filled shape the user is drawing.
*/
case IDM_ELLIPSE:
fSizeEllipse = TRUE;
break;
case IDM_RECTANGLE:
fSizeRectangle = TRUE;
break;
case IDM_ROUNDRECT:
fSizeRoundRect = TRUE;
break;
default:
return DefWindowProc(hwnd, uMsg, wParam,
lParam);
}
break;
case WM_CREATE:
nEllipseWidth = 20;
nEllipseHeight = 20;
return 0;
case WM_PAINT:
BeginPaint(hwnd, &ps);
/*
* Because the default brush is white, select
* a different brush into the device context
* to demonstrate the painting of filled shapes.
*/
SelectObject(ps.hdc, GetStockObject(GRAY_BRUSH));
/*
* If one of the filled shape "draw" flags is TRUE,
* draw the corresponding shape.
*/
if (fDrawEllipse) { /* draws ellipse */
Ellipse(ps.hdc, rcTarget.left, rcTarget.top,
rcTarget.right, rcTarget.bottom);
fDrawEllipse = FALSE;
rcTarget.left = rcTarget.right = 0;
rcTarget.top = rcTarget.bottom = 0;
}
if (fDrawRectangle) { /* Draws rectangle */
Rectangle(ps.hdc, rcTarget.left, rcTarget.top,
rcTarget.right, rcTarget.bottom);
fDrawRectangle = FALSE;
rcTarget.left = rcTarget.right = 0;
rcTarget.top = rcTarget.bottom = 0;
}
if (fDrawRoundRect) { /* Draws rounded rectangle */
RoundRect(ps.hdc, rcTarget.left, rcTarget.top,
rcTarget.right, rcTarget.bottom,
nEllipseWidth, nEllipseHeight);
fDrawRectangle = FALSE;
rcTarget.left = rcTarget.right = 0;
rcTarget.top = rcTarget.bottom = 0;
}
EndPaint(hwnd, &ps);
break;
case WM_SIZE:
/*
* Convert the client coordinates of the client area
* rectangle to screen coordinates and save them in a
* rectangle. The rectangle is passed to the ClipCursor
* function during WM_LBUTTONDOWN processing.
*/
GetClientRect(hwnd, &rcClient);
ptClientUL.x = rcClient.left;
ptClientUL.y = rcClient.top;
ptClientLR.x = rcClient.right;
ptClientLR.y = rcClient.bottom;
ClientToScreen(hwnd, &ptClientUL);
ClientToScreen(hwnd, &ptClientLR);
SetRect(&rcClient, ptClientUL.x, ptClientUL.y,
ptClientLR.x, ptClientLR.y);
return 0;
case WM_LBUTTONDOWN:
/*
* Restrict the cursor to the client area.
* This ensures that the window receives a matching
* WM_LBUTTONUP message.
*/
ClipCursor(&rcClient);
/* Save the coordinates of the cursor. */
pt.x = (LONG) LOWORD(lParam);
pt.y = (LONG) HIWORD(lParam);
/*
* If the user chooses one of the filled shapes,
* set the appropriate flag to indicate that the
* shape is being sized.
*/
if (fDrawEllipse)
fSizeEllipse = TRUE;
return 0;
case WM_MOUSEMOVE:
/*
* If one of the "size" flags is set, draw
* the target rectangle as the user drags
* the mouse.
*/
if ((wParam && MK_LBUTTON)
&& (fSizeEllipse || fSizeRectangle
|| fSizeRoundRect)) { /* draws target rect. */
/*
* Set the mixing mode so that the pen color is the
* inverse of the background color. The previous
* rectangle can then be erased by drawing
* another rectangle on top of it.
*/
hdc = GetDC(hwnd);
SetROP2(hdc, R2_NOTXORPEN);
/*
* If a previous target rectangle exists, erase
* it by drawing another rectangle on top.
*/
if (!IsRectEmpty(&rcTarget))
Rectangle(hdc, rcTarget.left, rcTarget.top,
rcTarget.right, rcTarget.bottom);
/*
* Save the coordinates of the target rectangle.
* Avoid invalid rectangles by ensuring that the
* value of the left coordinate is greater than
* that of the right, and that the value of the
* bottom coordinate is greater than that of
* the top.
*/
if ((pt.x < (LONG) LOWORD(lParam)) &&
(pt.y > (LONG) HIWORD(lParam)))
SetRect(&rcTarget, pt.x, HIWORD(lParam),
LOWORD(lParam), pt.y);
else if ((pt.x > (LONG) LOWORD(lParam)) &&
(pt.y > (LONG) HIWORD(lParam)))
SetRect(&rcTarget, LOWORD(lParam),
HIWORD(lParam), pt.x, pt.y);
else if ((pt.x > (LONG) LOWORD(lParam)) &&
(pt.y < (LONG) HIWORD(lParam)))
SetRect(&rcTarget, LOWORD(lParam), pt.y,
pt.x, HIWORD(lParam));
else
SetRect(&rcTarget, pt.x, pt.y, LOWORD(lParam),
HIWORD(lParam));
/* Draw the new target rectangle. */
Rectangle(hdc, rcTarget.left, rcTarget.top,
rcTarget.right, rcTarget.bottom);
ReleaseDC(hwnd, hdc);
}
return 0;
case WM_LBUTTONUP:
/*
* If one of the "size" flags is TRUE, reset
* it to FALSE, and then set the corresponding
* "draw" flag.
* Invalidate the appropriate rectangle and issue
* a WM_PAINT message.
*/
if (fSizeEllipse) {
fSizeEllipse = FALSE;
fDrawEllipse = TRUE;
}
if (fSizeRectangle) {
fSizeRectangle = FALSE;
fDrawRectangle = TRUE;
}
if (fSizeRoundRect) {
fSizeRoundRect = FALSE;
fDrawRoundRect = TRUE;
}
if (fDrawEllipse || fDrawRectangle || fDrawRoundRect)
{
InvalidateRect(hwnd, &rcTarget, TRUE);
UpdateWindow(hwnd);
}
/* Release the cursor. */
ClipCursor((LPRECT) NULL);
return 0;
case WM_DESTROY:
/*
* Destroy the background brush, compatible bitmap,
* and bitmap.
*/
DeleteDC(hdcCompat);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return (LRESULT) NULL;
}
| Last news from Greatis Software |
 |
|
Nostalgia .Net |
|
.Net is powerful, but not all-powerful, so sometimes we need to use Win32 API for our .Net applications. It's simple enough with Platform Invoke if you have Win32 skill, but we do not always have time to dig the ancient documentation, declare the special types that are compatible with Win32, find the values of the Win32's constants and so on. Nostalgia .Net offers several simple-to-use classes, and components that will allow you to forget about the headache of Win32 and just use the power of Win32 in your application the same way as you use the native. Net classes. More » |
| Recommended software for developers |
 |
|
Ultimate Pack |
|
Component pack for Delphi and C++ Builder that contains runtime form designer, runtime object inspector, print suite and much more for the very special price. More » |
 |
|
Form Designer .Net |
|
Unique runtime form design solution that allows to edit any form in .Net WinForms application at runtime with full source codes for only 300 euro! More » |
 |
|
Print Suite .Net |
|
Print Suite .Net is a set of components for easy printing texts, images and grids from your WinForms applications. Full C# source codes are available More » |
 |
|
Gradient Controls .Net |
|
Gradient Controls .Net offers controls with gradient background feature. Labels, panels and so on... Full C# source codes are available More » |
 |
|
Greatis iGrid |
|
iGrid plots drawing grid right over your desktop, so you can use it everywhere, with any drawing application without any special plugins for different graphic editors. More » |
All the contacts and projectsDmitry Vasiliev (just.dmitry)
Related LinksSoftware for Visual Studio .NET developers Software for Delphi and C++ Builder developers Software for Visual Basic 6 developers Delphi Tips&Tricks MegaDetailed.NET More Online Helps Win32 Programmer's Reference Win32 Multimedia Programmer's Reference OLE Programmer's Reference Microsoft Windows Pen API Programmer's Reference Microsoft Windows Sockets 2 Reference Microsoft Windows Telephony API (TAPI) Programmer's Reference Unix Manual Pages
|