Поскольку объявленные переменные являются локальными переменными, переменные могут быть объявлены с помощью 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);
}