프로그래밍/VC++

마우스 움직이는대로 그리기

panpro 2008. 3. 6. 00:06

시작.
타블렛을 위해 마우스가 움직이는대로 그리는 프로그램을 만들려고 했다.
다 잘만들었다고 생각했다. 타블렛이 움직이는대로 글씨나 그림이 잘 그려졌다.

그런데 조그맣게 글씨를 쓰다보면 빠지는 획이 발생했다.
예를 들면 "잉어"라고 손으로 썼는데 "이어" 라고 쓰여진다거나 아주 조그만 ㅁ 을 그렸는데 맨 처음 그린 한 획만 그려지고 나머지 획들은 그려지지 않는 문제가 발생했다.

이거 원래 이래. 어쩔 수 없을거야.

MS One Note에서 타블렛을 테스트해 봤다.
아 놔. 겁나 잘 그려진다.
빠지는 획이 하나도 없을 뿐만 아니라, 너무 마음먹은 대로 잘 그려져서 마치 내가 그을려고 하는 곳을 미리 알고 점들이 미리 움직이는 듯한 느낌마저 들었다.

충격이었다. 뭘까.

처음엔 STL을 의심했다. list<> 에 push_back 할 때 겁나 시간이 많이 걸리거나 list<> 에 넣을 자료구조(32byte, 허걱. 줄여야지) 를 메모리에서 생성하는 시간이 겁나 오래 걸리는 게 아닌가 싶었다.

얘네들 아니다. 프로파일링해보면 0초로 표시된다.

그 다음엔 moveto, lineto를 의심했다. 어떤 사람이 저거 열라 느리니까 pdc->polyline을 쓰란다.
이거다 싶었다.

결과는 이전과 아주 약간 나아진 느낌(!)일 뿐 아무것도 나아진 게 없었다. 전과 비슷한 빈도로 획들이 빠졌다.

그 다음 의심한 게 GetDC(). 할때 마다 GetDC한다는 게 얼마나 느린 연산일까,
그 다음 의심한 게 CPen 생성.

전부 다 아니다.

그러다 이게 ActiveX로 만들어서 그런걸까 하고 의심했다.
ActiveX로 만들면 마우스 이벤트 받고 하는 부분에 조금 손해를 보는 게 아닐까 싶었다.
(아직 이건 테스트해보지 못했다.)


계속 테스트해본 결과 LButtonDown 이벤트가 발생하지 않는 경우가 발생한다는 것을 알았다.
이전 내 코드는

void CViewSpeedTestDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
 m_bMouseDown = true;
...
}

void CViewSpeedTestDlg::OnMouseMove(UINT nFlags, CPoint point)
{
if (false == m_bMouseDown)
  return;
...
//그림그리기 혹은 그와 관련된 코드들
}


void CViewSpeedTestDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
 m_bMouseDown = false;
...
}

이런 식이었다. 결국 OnLButtonDown 이벤트 핸들러로 들어가지 않으면 그림을 그리지를 못했던 거다.
그런데 실제로 분명히 마우스 버튼을 눌렀음에도 저 이벤트가 발생하지 않는 경우가 꽤 되었다.
특히 조밀조밀 움직일 때는 꽤 자주 (서너번에 1번꼴) 이런 현상이 발생했다.

이걸 해결하는 방법은 의외로 매우 단순했다.

void CViewSpeedTestDlg::OnMouseMove(UINT nFlags, CPoint point)
{
 if (false == (nFlags & MK_LBUTTON))
  return;

...

이런 식이다.

그리고 m_bMouseDown 관련 내용은 싸그리 지워버렸다. 내 경우엔 버튼을 눌렀을 때 그림을 그린다는 목적외에는 사용하지 않았으니까.

아 너무 뿌듯하다.