使用鼠标绘制线

【勇芳软件工作室】汉化HomePreviousNext

本节中的示例演示如何跟踪鼠标光标。它包含窗口过程的一部分,使得用户可以通过拖动鼠标在窗口的客户区中绘制线条。

当窗口过程接收到WM_LBUTTONDOWN消息时,它捕获鼠标并使用坐标作为行的起点保存光标的坐标。它还使用ClipCursor函数在行绘制操作期间将光标限制在客户区。

在第一个WM_MOUSEMOVE消息中,窗口过程从起始点到光标的当前位置绘制一条线。在随后的WM_MOUSEMOVE消息中,窗口过程通过用反转的笔颜色绘制来擦除上一行。然后它从起始点到光标的新位置绘制一条新行。

WM_LBUTTONUP消息表示绘图操作的结束。窗口过程释放鼠标捕获,并从客户端区域释放鼠标。

LRESULT APIENTRY MainWndProc(hwndMain,uMsg,wParam,lParam)en

HWND hwndMain;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

{

HDC hdc; /* handle of device context */

RECT rcClient; /* client area rectangle */

POINT ptClientUL; /* client upper left corner */

POINT ptClientLR; /* client lower right corner */

static POINTS ptsBegin; /* beginning point */

static POINTS ptsEnd; /* new endpoint */

static POINTS ptsPrevEnd; /* previous endpoint */

static BOOL fPrevLine = FALSE; /* previous line flag */

开关(uMsg){

case WM_LBUTTONDOWN:

/ *捕获鼠标输入。*/

SetCapture(hwndMain);

/*

*检索客户区域的屏幕坐标,

*并将其转换为客户端坐标。

/*

GetClientRect(hwndMain, &rcClient);

ptClientUL.x = rcClient.left;

ptClientUL.y = rcClient.top;

/*

*添加一个到右侧和底部,因为

*由GetClientRect检索的坐标不要

*包括最左边和最下面的像素。

*/

ptClientLR.x = rcClient.right + 1;

ptClientLR.y = rcClient.bottom + 1;

ClientToScreen(hwndMain, &ptClientUL);

ClientToScreen(hwndMain, &ptClientLR);

/*

*复制客户端区域的客户端坐标

*到rcClient结构。限制鼠标光标

*通过传递rcClient结构到客户端区域

*到ClipCursor函数。

*/

SetRect对(& RC客户机,ptClientUL.x,ptClientUL.y,

ptClientLR.x, ptClientLR.y);

ClipCursor(&rcClient);

/*

*将光标坐标转换为POINTS

*结构,它定义了起点

*在WM_MOUSEMOVE消息中绘制的行。

*/

ptsBegin = MAKEPOINTS(lParam);

return 0;

case WM_MOUSEMOVE:

/*

*移动鼠标时,用户必须按住

*鼠标左键绘制线条。

*/

if(wParam & MK_LBUTTON){

/*

*检索客户端的设备上下文(DC)

*区域。

*/

hdc = GetDC(hwndMain);

/*

*以下功能确保像素

*以前绘制的线条设置为白色

*新线的设置为黑色。

*/

SetROP2(hdc, R2_NOTXORPEN);

/*

*如果在早些时候画了一条线

* WM_MOUSEMOVE消息,画出它。这擦除

*通过将其像素的颜色设置为该行

*白色。

*/

if(fPrevLine){

MoveToEx(hdc,ptsBegin.x,ptsBegin.y,

(LPPOINT) NULL);

LineTo(hdc, ptsPrevEnd.x, ptsPrevEnd.y);

}

/*

*将当前光标坐标转换为a

* POINTS结构,然后画一条新行。

*/

ptsEnd = MAKEPOINTS(lParam);

MoveToEx(hdc,ptsBegin.x,ptsBegin.y,

(LPPOINT) NULL);

LineTo(hdc, ptsEnd.x, ptsEnd.y);

/*

*设置前一行标志,保存结束

*点新线,然后释放DC。

*/

fPrevLine = TRUE;

ptsPrevEnd = ptsEnd;

ReleaseDC(hwndMain, hdc);

}

break;

case WM_LBUTTONUP:

/*

*用户已经完成绘制线。重置

*上一行标志,释放鼠标光标,和

*释放鼠标捕获。

*/

fPrevLine = FALSE;

ClipCursor(NULL);

ReleaseCapture();

return 0;

case WM_DESTROY:

PostQuitMessage(0);

break;

.

./ *处理其他消息。*/

.