. 마우스로 선택하기

선택영역을 표시하는 기능을 다 작성했다. 이제 마우스의 움직임에 따라 SelStart SelEnd만 잘 조정하고 작업영역을 무효화시키면 나머지 작업은 OnPaint와 그 일당들이 알아서 할 것이다. 마우스 메시지를 프로그래밍해보도록 하자. 마우스 왼쪽 버튼을 클릭하면 블록선택을 시작한다.

 

void OnLButtonDown(HWND hWnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)

{

     if (SelStart != SelEnd) {

          SelStart=SelEnd=0;

          InvalidateRect(hWnd,NULL,TRUE);

     }

 

     off=GetOffFromXY(x+xPos,y+yPos);

     SelStart=SelEnd=off;

     SetCapture(hWnd);

     bCapture=TRUE;

     SetCaret();

}

 

앞쪽 조건문은 선택영역이 있으면 해제하는 문장이다. 이미 선택되어 있는 상태에서 클릭하면 새로운 선택영역을 지정해야 하므로 기존의 선택영역은 제거해야 한다. 선택영역을 제거하려면 SelStart SelEnd를 모두 0으로 만들어 주고 화면을 무효화하면 된다.

버튼을 클릭한 위치가 곧 현재 캐럿 위치가 되는데 이 위치는 선택의 시작점이 되며 동시에 선택의 끝점이 되기도 한다. 그래서 버튼을 클릭한 상태에서는 캐럿만 이동하고 선택영역은 아직 없다. 이 상태로 마우스를 움직이면 SelStart는 그대로 두고 SelEnd가 마우스를 쫓아 감으로써 선택영역이 확장될 것이다. 블록선택이 시작되면 커서가 작업영역을 벗어나도 계속 마우스 메시지를 받아야 하므로 커서를 캡처하였다. 마우스가 이동할 때의 처리는 다음과 같다.

 

void OnMouseMove(HWND hWnd, int x, int y, UINT keyFlags)

{

     if (bCapture == FALSE) {

          return;

     }

 

     off=SelEnd=GetOffFromXY(x+xPos,y+yPos);

     SetCaret();

     InvalidateRect(hWnd,NULL,TRUE);

}

 

일단 캡처 상태가 아니면, 즉 선택을 하고 있는 중이 아니면 곧바로 리턴하여 아무 일도 하지 않는다. 그래서 이 루틴은 마우스 버튼을 클릭한 상태에서만 실행된다. 커서가 있는 위치가 새로운 현재 위치가 되며 선택의 끝점도 이 위치로 확장된다. 캐럿을 이동시키고 화면을 다시 그리면 마우스가 이동한 만큼 선택영역이 확장되어 있을 것이다. 마지막으로 버튼을 놓을 때는 마우스 캡처만 풀어주면 된다.

 

void OnLButtonUp(HWND hWnd, int x, int y, UINT keyFlags)

{

     bCapture=FALSE;

     ReleaseCapture();

}

 

캡처를 풀면 이제 선택이 끝나며 OnMouseMove에서는 더 이상 선택영역을 확장하지 않을 것이다. 마우스로 선택영역을 만드는 처리가 완료되었다. 실행해보면 잘 선택될 것이다.