我写的一个很简单的画直线的程序,你多画几条线就会发现,有些地方被擦掉了,有时候两条线交叉的时候可以看到很明显的空白处(交叉点被擦掉却没有还原,WHY,按理是应该会还原的啊),而WINDOWS自带画图程序画直线时就不是这样,交叉的时候也是完全覆盖,绝对不会擦掉的,那是用的什么方法呢?我的方法有何问题?请SDK高手指点,不胜感激!#include <windows.h>LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);int CALLBACK WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd)
{
MSG msg;
TCHAR szAppName[] = "My Program";
HWND hWnd;
WNDCLASSEX wcex;
wcex.cbSize = sizeof (wcex);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor (NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szAppName;
wcex.hIconSm = NULL;
RegisterClassEx (&wcex); hWnd = CreateWindow (szAppName,
"Hello",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
hInstance,
NULL); ShowWindow (hWnd, nShowCmd);
UpdateWindow (hWnd); while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
} LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
static POINT ptOrg, ptOld;
static BOOL bLButDown = FALSE; //判断鼠标左键是否按下
int nOldRop;
int xPos, yPos;
switch (message)
{
case WM_LBUTTONDOWN:
bLButDown = TRUE;
ptOld.x = ptOrg.x = LOWORD (lParam);
ptOld.y = ptOrg.y = HIWORD (lParam);
break; case WM_LBUTTONUP:
bLButDown = FALSE;
break; case WM_MOUSEMOVE:
if (bLButDown == FALSE)
break;
xPos = LOWORD (lParam);
yPos = HIWORD (lParam);
hdc = GetDC (hWnd);
nOldRop = SetROP2 (hdc, R2_NOT); //颜色混合模式 非模式
MoveToEx (hdc, ptOrg.x, ptOrg.y, NULL); //擦掉上次的线
LineTo (hdc, ptOld.x, ptOld.y);
MoveToEx (hdc, ptOrg.x, ptOrg.y, NULL); //画新线
LineTo (hdc, xPos, yPos);
SetROP2 (hdc, nOldRop); //颜色混合模式 还原
ReleaseDC (hWnd, hdc);
ptOld.x = xPos;
ptOld.y = yPos;
break; case WM_DESTROY:
PostQuitMessage (0);
break; default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
return 0;
}
LPSTR lpCmdLine, int nShowCmd)
{
MSG msg;
TCHAR szAppName[] = "My Program";
HWND hWnd;
WNDCLASSEX wcex;
wcex.cbSize = sizeof (wcex);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor (NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szAppName;
wcex.hIconSm = NULL;
RegisterClassEx (&wcex); hWnd = CreateWindow (szAppName,
"Hello",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
hInstance,
NULL); ShowWindow (hWnd, nShowCmd);
UpdateWindow (hWnd); while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
} LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
static POINT ptOrg, ptOld;
static BOOL bLButDown = FALSE; //判断鼠标左键是否按下
int nOldRop;
int xPos, yPos;
switch (message)
{
case WM_LBUTTONDOWN:
bLButDown = TRUE;
ptOld.x = ptOrg.x = LOWORD (lParam);
ptOld.y = ptOrg.y = HIWORD (lParam);
break; case WM_LBUTTONUP:
bLButDown = FALSE;
break; case WM_MOUSEMOVE:
if (bLButDown == FALSE)
break;
xPos = LOWORD (lParam);
yPos = HIWORD (lParam);
hdc = GetDC (hWnd);
nOldRop = SetROP2 (hdc, R2_NOT); //颜色混合模式 非模式
MoveToEx (hdc, ptOrg.x, ptOrg.y, NULL); //擦掉上次的线
LineTo (hdc, ptOld.x, ptOld.y);
MoveToEx (hdc, ptOrg.x, ptOrg.y, NULL); //画新线
LineTo (hdc, xPos, yPos);
SetROP2 (hdc, nOldRop); //颜色混合模式 还原
ReleaseDC (hWnd, hdc);
ptOld.x = xPos;
ptOld.y = yPos;
break; case WM_DESTROY:
PostQuitMessage (0);
break; default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
return 0;
}
拖动的时候,交叉点是白的,没问题.等松开左键时,再单写一个函数.画一条直线.不要用SetROP2
用这个试试:R2_XORPEN
以前在WIN32环境下写的,画FREEHAND,1PIX还勉强过得去,如果画宽线。惨不忍睹。画直线也会象你说的这种情况发生。在MFC下就不会有这样的问题了。