我想通过在线应该开始的第一个坐标上单击鼠标来绘制线,以及线应该结束的第二个坐标。当我运行我的项目时没有任何反应。我无法找出我的代码丢失的内容。
LONG WINAPI WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
BOOL fDraw = FALSE;
POINT ptPrevious = { 0 };
HPEN Pen = CreatePen(PS_SOLID, 3, RGB(0, 0, 255));
switch (Message) {
case WM_LBUTTONDOWN: {
fDraw = TRUE;
ptPrevious.x = LOWORD(lParam);
ptPrevious.y = HIWORD(lParam);
break;
}
case WM_LBUTTONUP: {
if (fDraw)
{
hdc = GetDC(hWnd);
MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, LOWORD(lParam), HIWORD(lParam));
ReleaseDC(hWnd, hdc);
}
fDraw = FALSE;
break;
}
case WM_MOUSEMOVE: {
if (fDraw)
{
hdc = GetDC(hWnd);
MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, ptPrevious.x = LOWORD(lParam),
ptPrevious.y = HIWORD(lParam));
ReleaseDC(hWnd, hdc);
}
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, Message, wParam, lParam);
}
return 0;
}
因为声明的变量是局部变量,所以可以使用Static声明变量。
static BOOL fDraw = FALSE;
static POINT ptPrevious = { 0 };
此外,您忘记使用SelectObject功能选择笔进入DC。
您还可以使用WM_PAINT重绘来改进代码:
例:
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
static BOOL fDraw = FALSE;
static BOOL fDraw_begin = FALSE;
static POINT ptPrevious;
static RECT rcClient;
static POINT pt;
static HPEN Pen;
switch (message)
{
case WM_CREATE:
{
Pen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));
break;
}
case WM_LBUTTONDOWN:
{
ptPrevious.x = (LONG)LOWORD(lParam);
ptPrevious.y = (LONG)HIWORD(lParam);
return 0;
}
case WM_LBUTTONUP:
{
if (fDraw = TRUE)
{
fDraw = FALSE;
fDraw_begin = TRUE;
InvalidateRect(hwnd, &rcClient, TRUE);
UpdateWindow(hwnd);
}
return 0;
}
case WM_MOUSEMOVE:
{
if (wParam && MK_LBUTTON)
{
GetClientRect(hwnd, &rcClient);
hdc = GetDC(hwnd);
SetROP2(hdc, R2_NOTXORPEN);
if (!IsRectEmpty(&rcClient)) // Detecting whether the rectangular area is empty
{
MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, (LONG)LOWORD(lParam),
(LONG)HIWORD(lParam));
}
MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, (LONG)LOWORD(lParam),
(LONG)HIWORD(lParam));
pt.x = (LONG)LOWORD(lParam);
pt.y = (LONG)HIWORD(lParam);
fDraw = TRUE;
ReleaseDC(hwnd, hdc);
}
return 0;
}
case WM_PAINT:
{
hdc = BeginPaint(hwnd, &ps);
SelectObject(hdc, Pen);
if (fDraw_begin)
{
fDraw_begin = FALSE;
MoveToEx(hdc, ptPrevious.x, ptPrevious.y, NULL);
LineTo(hdc, pt.x,
pt.y);
}
EndPaint(hwnd, &ps);
ReleaseDC(hwnd, hdc);
return 0;
}
case WM_DESTROY:
{
DeleteObject(Pen);
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
从根本上说,问题是因为没有一个数据是持久的。因为它们都是局部变量,所以当WndProc
返回时它们的内容会消失。 fDraw
在每条消息上都设置为FALSE
,对于WM_LBUTTONDOWN或WM_MOUSEMOVE消息永远不会成立。因此没有任何反应
你需要创建一些类来保存fDraw
,ptPrevious
和一个结构来保存要绘制的线的坐标。在WM_MOUSEMOVE和WM_LBUTTONUP消息中使用InvalidateRect
。然后只绘制它们以响应WM_PAINT消息(使用绘制消息中提供的DC)。
使用CWnd
MFC类可以大大简化这些任务。
不要让DC三次,得到它一次并在鼠标上释放它。此外,您的绘图最终将被验证,因此您需要记录鼠标移动并在WM_PAINT处理程序中重复此内容。