本节说明如何使用填充形状函数。该示例使用来自允许用户绘制椭圆,矩形和圆角的矩形的应用程序的主窗口过程。
用户通过从菜单中选择一个特定的形状来绘制一个填充的形状,将光标定位在形状的左上角(或者在椭圆的情况下是形状的边界矩形),然后拖动鼠标直到所需的尺寸为获得。
下图显示了使用本节中的示例代码绘制的三个填充形状。
要使用户绘制填充的形状,请在应用程序中包含以下代码。
LRESULT APIENTRY MainWndProc(hwnd,uMsg,wParam,lParam)en
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 */
开关(uMsg){
case WM_COMMAND:
开关(wParam){
/*
*设置适当的标志来指示哪一个
*用户正在绘制的填充形状。
*/
case IDM_ELLIPSE:
fSizeEllipse = TRUE;
break;
case IDM_RECTANGLE:
fSizeRectangle = TRUE;
break;
case IDM_ROUNDRECT:
fSizeRoundRect = TRUE;
break;
默认:
返回DefWindowProc(hwnd,uMsg,wParam,
lParam);
}
break;
case WM_CREATE:
nEllipseWidth = 20;
nEllipseHeight = 20;
return 0;
case WM_PAINT:
BeginPaint(hwnd, &ps);
/*
*由于默认画笔为白色,请选择
*一个不同的画笔进入设备上下文
*展示填充形状的绘画。
*/
SelectObject(ps.hdc, GetStockObject(GRAY_BRUSH));
/*
*如果填充形状“绘制”标志之一为TRUE,
*绘制相应的形状。
*/
if(fDrawEllipse){/ *绘制椭圆* /
椭圆(ps.hdc,rcTarget.left,rcTarget.top,
rcTarget.right, rcTarget.bottom);
fDrawEllipse = FALSE;
rcTarget.left = rcTarget.right = 0;
rcTarget.top = rcTarget.bottom = 0;
}
if(fDrawRectangle){/ *绘制矩形* /
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){/ *绘制圆角矩形* /
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:
/*
*转换客户端区域的客户端坐标
*矩形屏幕坐标并将其保存在
* 长方形。矩形传递给ClipCursor
*功能在WM_LBUTTONDOWN处理。
*/
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对(& RC客户机,ptClientUL.x,ptClientUL.y,
ptClientLR.x, ptClientLR.y);
return 0;
case WM_LBUTTONDOWN:
/*
*将光标限制在客户区。
*这样可以确保窗口接收到匹配
* WM_LBUTTONUP消息。
*/
ClipCursor(&rcClient);
/ *保存光标的坐标。*/
pt.x = (LONG) LOWORD(lParam);
pt.y = (LONG) HIWORD(lParam);
/*
*如果用户选择填充形状之一,
*设置相应的标志来指示
*形状正在大小。
*/
if(fDrawEllipse)
fSizeEllipse = TRUE;
return 0;
case WM_MOUSEMOVE:
/*
*如果设置了“大小”标志之一,则绘制
*用户拖动的目标矩形
*鼠标。
*/
if((wParam & & MK_LBUTTON)
& &(fSizeEllipse || fSizeRectangle
|| fSizeRoundRect)){/ *绘制目标矩形。*/
/*
*设置混合模式,使笔的颜色为
*背景颜色的倒数。以前的
*矩形可以通过绘图来擦除
*其上一个矩形。
*/
hdc = GetDC(hwnd);
SetROP2(hdc, R2_NOTXORPEN);
/*
*如果存在上一个目标矩形,请擦除
*通过在顶部绘制另一个矩形。
*/
if(!IsRectEmpty(& rcTarget))
Rectangle(hdc,rcTarget.left,rcTarget.top,
rcTarget.right, rcTarget.bottom);
/*
*保存目标矩形的坐标。
*避免无效的矩形,确保
*左坐标值大于
*的权利,以及的价值
*底部坐标大于
* 顶端。
*/
if((pt.x {98??9796003}(LONG)LOWORD(lParam))& &
(pt.y >(LONG)HIWORD(lParam)))
SetRect(& rcTarget,pt.x,HIWORD(lParam),
LOWORD(lParam), pt.y);
else if((pt.x {98??9796004}(LONG)LOWORD(lParam))& &
(pt.y >(LONG)HIWORD(lParam)))
SetRect(& rcTarget,LOWORD(lParam),
HIWORD(lParam), pt.x, pt.y);
else if((pt.x {98??9796004}(LONG)LOWORD(lParam))& &
(pt.y <(LONG)HIWORD(lParam)))
SetRect(& rcTarget,LOWORD(lParam),pt.y,
pt.x, HIWORD(lParam));
其他
SetRect(& rcTarget,pt.x,pt.y,LOWORD(lParam),
HIWORD(lParam));
/ *绘制新的目标矩形。*/
Rectangle(hdc,rcTarget.left,rcTarget.top,
rcTarget.right, rcTarget.bottom);
ReleaseDC(hwnd, hdc);
}
return 0;
case WM_LBUTTONUP:
/*
*如果“大小”标志之一为TRUE,请重置
*将其设为FALSE,然后设置相应的
*“画”标志。
*无效适当的矩形和问题
*一个WM_PAINT消息。
*/
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);
}
/ *释放光标。*/
ClipCursor((LPRECT) NULL);
return 0;
case WM_DESTROY:
/*
*破坏背景画笔,兼容位图,
*和位图。
*/
DeleteDC(hdcCompat);
PostQuitMessage(0);
break;
默认:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return (LRESULT) NULL;
}