[英]draw line doesn't work, what might be the problem?
我想通過在行應開始的第一個坐標和行應結束的第二個坐標上單擊鼠標來繪制線。 當我運行我的項目時,什么也沒有發生。 我找不到我的代碼丟失了。
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;
}
從根本上講,問題是因為您的數據都沒有持久性。 由於它們都是局部變量,因此WndProc
返回時它們的內容就會消失。 對於每條消息, fDraw
都設置為FALSE
,並且對於WM_LBUTTONDOWN或WM_MOUSEMOVE消息永遠不會為true。 因此什么也沒發生。
您將要創建某種類型的類來保存fDraw
, ptPrevious
和一個結構來保存要繪制的線的坐標。 在WM_MOUSEMOVE和WM_LBUTTONUP消息中使用InvalidateRect
。 然后僅響應WM_PAINT消息(使用繪制消息中提供的DC)繪制它們。
使用CWnd
MFC類可以大大簡化這些任務。
不要獲取DC三次,請獲取一次,然后用鼠標將其釋放。 同樣,您的圖形將最終得到驗證,因此您需要記錄鼠標的移動並在WM_PAINT處理程序中重復此操作。
由於聲明的變量是局部變量,因此可以使用靜態聲明變量。
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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.