SetROP2에서 R2_NOT이나 R2_XORPEN를 줘서 반전효과를 이용하면
이전의 선들을 지우면서 이동할 수 있다.
그런데 기존에 인터넷에 돌아다니는 소스에는 좀 문제가 있다.
마우스 왼쪽 버튼 다운 메시지가 오면 파라미터로 전달된 좌표와 old x, old y 좌표를 일치시켜서 처리하는 식인데
이 경우 마우스 무브 첫 메시지 발생하고 그리는 과정에서 문제가 생긴다.
선을 그리는 함수의 좌표가 같은 경우, 가령 (100, 100) ~ (100, 100) 까지 선을 그린다고 하면
100, 100 위치에 선 굵기만한 점이 그려진다.
그래서 첫 마우스무브 메시지에서 일단 선굵기 크기의 점을 그리고 그 다음에 시작지점부터 마우스무브 좌표까지의 선을 그린다.
이 결과 첫 점 부분이 다시 반전이 되어 원래의 배경색이 된다. 굵은 선으로 테스트해 보면 그 결함이 쉽게 드러난다.
이를 수정하기 위해서는 따로 BOOL 변수를 두어서 첫 무브시에는 2번 그리는 처리를 하지 않아야 된다.
< bad> <good>
왼쪽 그림에서 선의 시작부분에 원형점 모양으로 뻥 뚫린다.
// 소스 참조
~~~~~~~ WndProc~~~~~~~
static BOOL bLBtnDown = FALSE, bFirstMoveCheck = FALSE;
case WM_LBUTTONDOWN:
xStart = LOWORD(lParam);
yStart = HIWORD(lParam);
bLBtnDown = TRUE;
bFirstMoveCheck = TRUE;
break;
case WM_MOUSEMOVE:
if (bLBtnDown)
{
hdc = GetDC(hWnd);
hPen = CreatePen(PS_SOLID, 20, RGB(255, 255, 0));
hOldPen = (HPEN)SelectObject(hdc, hPen);
// SetROP2(hdc, R2_NOT);
SetROP2(hdc, R2_XORPEN);
// 첫 마우스 무브시는 이전에 그린 것에 대한 처리를 하면 안된다.
// 참고로 아래와 같이 처리하지 않고 WM_LBUTTONUP 메시지 처리부분에서 x = xStart, y = yStart 이렇게 대입하고
// 아래와 같은 조건문 없이 처리하는 방식이 있는데 이 방법은 문제가 있다.
// 왜냐하면 첫 마우스무브 메시지에서 일단 선굵기만한 점을 그리고
// (선그리기 함수의 시작좌표와 끝좌표가 같으면 선굵기의 점을 그린다.)
// 그 다음에 시작지점부터 마우스무브된 좌표까지의 선을 그린다.
// 그 결과 앞서 그려진 점 부분이 다시 반전이 되어 원래의 배경색이 된다.
// 굵은 선으로 테스트해 보면 그 결함이 쉽게 드러난다.
if (bFirstMoveCheck)
{
bFirstMoveCheck = FALSE;
}
else
{
MoveToEx(hdc, xStart, yStart, NULL); // 이전에 그린 선 다시 그려줌으로써 배경그림으로 다시 복귀함.
LineTo(hdc, x, y);
}
x = LOWORD(lParam);
y = HIWORD(lParam);
MoveToEx(hdc, xStart, yStart, NULL);
LineTo(hdc, x, y);
SelectObject(hdc, hOldPen);
DeleteObject(hPen);
ReleaseDC(hWnd, hdc);
}
break;
'API' 카테고리의 다른 글
뮤텍스와 세마포어,,, WAIT_ABANDONED 발생 여부 (0) | 2012.03.06 |
---|---|
프로세스, 스레드간의 상호 통신에 주의해야 될 점 (0) | 2011.07.21 |
SetCapture 특기할만한 사항 (0) | 2011.07.16 |
mfc 기본 구조 파악 자료 pdf (0) | 2011.07.09 |
GetAsyncKeyState 올바른 이해 (2) | 2011.07.07 |
펌) Change the Tab Order of the Controls in a Dialog Box (2) | 2010.08.12 |
멀티미디어 프로그래밍 참조 (1) | 2010.04.09 |