本节中的示例说明了如何使用矩形函数。它由一个应用程序的主窗口过程组成,使得用户可以移动和定位位图。
当应用程序启动时,它在屏幕的左上角绘制一个32像素×32像素的位图。用户可以通过拖动来移动位图。要使位图大小,用户通过拖动鼠标创建一个目标矩形,然后拖动位图,并将其放在目标矩形上。应用程序通过将位图复制到目标矩形中进行响应。
以下示例给出了允许用户移动位图大小的窗口过程。
LRESULT CALLBACK 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; /* device context (DC) for window */
RECT rcTmp; /* temporary rectangle */
PAINTSTRUCT ps; /* paint data for Begin/EndPaint */
POINT ptClientUL; /* client area upper left corner */
POINT ptClientLR; /* client area lower right corner */
static HDC hdcCompat; /* DC for copying bitmap */
static POINT pt; /* x and y coordinates of cursor */
static RECT rcBmp; /* rectangle that encloses bitmap */
static RECT rcTarget; /* rectangle to receive bitmap */
static RECT rcClient; /* client-area rectangle */
static BOOL fDragRect; /* TRUE if bitmap rect. is dragged */
static HBITMAP hbmp; /* handle of bitmap to display */
static HBRUSH hbrBkgnd; /* handle of background-color brush */
static COLORREF crBkgnd; /* color of client-area background */
static HPEN hpenDot; /* handle of dotted pen */
开关(uMsg){
case WM_CREATE:
/ *加载位图资源。*/
hbmp = LoadBitmap(hinst, MAKEINTRESOURCE(1));
/*
*创建一个设备上下文(DC)来保存位图。
*位图从该DC复制到窗口的DC
*每当它必须绘制
*/
hdc = GetDC(hwnd);
hdcCompat = CreateCompatibleDC(hdc);
SelectObject(hdcCompat, hbmp);
/*
*创建与背景颜色相同的画笔
*的客户区域。刷子随后用于擦除
*复制位图之前的旧位图
*目标矩形。
*/
crBkgnd = GetBkColor(hdc);
hbrBkgnd = CreateSolidBrush(crBkgnd);
ReleaseDC(hwnd, hdc);
/*
*创建一个虚线笔。笔用来画画
*位图矩形,因为用户拖动它。
*/
hpenDot = CreatePen(PS_DOT, 1, RGB(0, 0, 0));
/*
*设置位图的初始矩形。注意
*此应用程序仅支持32位32像素
*位图。矩形略大于
*位图。
*/
SetRect(&rcBmp, 1, 1, 34, 34);
return 0;
case WM_PAINT:
/*
*绘制位图矩形并将位图复制到
* it.32像素×32像素位图为中心
*在矩形中通过向左和向上加1
*位图矩形的坐标,并减去
* 2从右下坐标。
*/
BeginPaint(hwnd, &ps);
Rectangle(ps.hdc,rcBmp.left,rcBmp.top,
rcBmp.right, rcBmp.bottom);
StretchBlt(ps.hdc,rcBmp.left + 1,rcBmp.top + 1,
(rcBmp.right - rcBmp.left) - 2,
(rcBmp.bottom - rcBmp.top) - 2,hdcCompat,
0, 0, 32, 32, SRCCOPY);
EndPaint(hwnd, &ps);
break;
case WM_MOVE:
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);
/*
*如果用户点击了位图矩形,重画
*它使用虚线笔。将fDragRect标志设置为
*表示用户即将拖动
* 长方形。
*/
if(PtInRect(& rcBmp,pt)){
hdc = GetDC(hwnd);
SelectObject(hdc, hpenDot);
Rectangle(hdc,rcBmp.left,rcBmp.top,rcBmp.right,
rcBmp.bottom);
fDragRect = TRUE;
ReleaseDC(hwnd, hdc);
}
return 0;
case WM_MOUSEMOVE:
/*
*绘制目标矩形或拖动位图
*矩形,取决于fDragRect的状态
*标志。
*/
if((wParam & & MK_LBUTTON)
& &!fDragRect){/ *绘制目标矩形* /
/*
*设置混合模式,使笔的颜色为
*背景颜色的倒数。以前的
*矩形可以通过绘图来擦除
*其上一个矩形。
*/
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);
}
else if((wParam & & MK_LBUTTON)
& & fDragRect){/ *拖动位图矩形* /
/*
*设置混合模式,使笔的颜色为
*背景颜色的倒数。
*/
hdc = GetDC(hwnd);
SetROP2(hdc, R2_NOTXORPEN);
/*
*将虚线笔选入直流并擦除
*以前的位图矩形通过绘图
*其上一个矩形。
*/
SelectObject(hdc, hpenDot);
Rectangle(hdc,rcBmp.left,rcBmp.top,
rcBmp.right, rcBmp.bottom);
/*
*设置位图的新坐标
*矩形,然后重画。
*/
OffsetRect(& rcBmp,LOWORD(lParam) - pt.x,
HIWORD(lParam) - pt.y);
Rectangle(hdc,rcBmp.left,rcBmp.top,
rcBmp.right, rcBmp.bottom);
ReleaseDC(hwnd, hdc);
/ *保存鼠标光标的坐标。*/
pt.x = (LONG) LOWORD(lParam);
pt.y = (LONG) HIWORD(lParam);
}
return 0;
case WM_LBUTTONUP:
/*
*如果位图矩形和目标矩形
*相交,将位图复制到目标中
* 长方形。否则,将位图复制到
*在其新位置的矩形位图。
*/
if(IntersectRect(& rcTmp,& rcBmp,& rcTarget)){
/*
*通过填写位图矩形来擦除位图
*背景颜色。
*/
hdc = GetDC(hwnd);
FillRect(hdc, &rcBmp, hbrBkgnd);
/*
*由于零件重新绘制目标矩形
*与位图矩形相交
*通过致电FillRect删除。
*/
Rectangle(hdc,rcTarget.left,rcTarget.top,
rcTarget.right, rcTarget.bottom);
/ *将位图复制到目标矩形中。*/
StretchBlt(hdc,rcTarget.left + 1,rcTarget.top + 1,
(rcTarget.right - rcTarget.left) - 2,
(rcTarget.bottom - rcTarget.top) - 2,hdcCompat,
0, 0, 32, 32, SRCCOPY);
/*
*将目标矩形复制到位图
*矩形,设置目标的坐标
*矩形为0,然后重置fDragRect标志。
*/
CopyRect(&rcBmp, &rcTarget);
SetRectEmpty(&rcTarget);
ReleaseDC(hwnd, hdc);
fDragRect = FALSE;
}
else if(fDragRect){
/*
*绘制位图矩形,将位图复制到
*它,并重置fDragRect标志。
*/
hdc = GetDC(hwnd);
Rectangle(hdc,rcBmp.left,rcBmp.top,
rcBmp.right, rcBmp.bottom);
StretchBlt(hdc,rcBmp.left + 1,rcBmp.top + 1,
(rcBmp.right - rcBmp.left) - 2,
(rcBmp.bottom - rcBmp.top) - 2,hdcCompat,
0, 0, 32, 32, SRCCOPY);
ReleaseDC(hwnd, hdc);
fDragRect = FALSE;
}
/ *释放鼠标光标。*/
ClipCursor((LPRECT) NULL);
return 0;
case WM_DESTROY:
/*
*破坏背景画笔,兼容位图,
*和位图。
*/
DeleteObject(hbrBkgnd);
DeleteDC(hdcCompat);
DeleteObject(hbmp);
PostQuitMessage(0);
break;
默认:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return (LRESULT) NULL;
}