.키보드 지원

다음은 키보드로도 도형의 크기 변경 이동을 있도록 보자. 드로잉 프로그램의 작업은 대부분 마우스로 있지만 섬세한 이동 처리나 크기 변경에는 키보드가 적합한 경우도 있다. 커서 이동키만 누르면 이동 처리를 하고 Shift키와 함께 누르면 크기를 변경한다. Ctrl키는 1픽셀 단위로 미세하게 이동 크기 변경을 한다. OnKeyDown 다음 코드를 작성하자.

 

LRESULT OnKeyDown(HWND hWnd,WPARAM wParam,LPARAM lParam)

{

   BOOL bShift, bControl;

   int dx,dy;

   RECT drt,crt,irt;

   BOOL bAction=TRUE;

 

   if (NowSel == -1) {

      return 0;

   }

  

   bShift=((GetKeyState(VK_SHIFT) & 0x8000) != 0);

   bControl=((GetKeyState(VK_CONTROL) & 0x8000) != 0);

   if (bControl) {

      dx=1;

      dy=1;

   } else {

      dx=8;

      dy=8;

   }

   drt=arObj[NowSel]->rt;

 

   if (bShift == FALSE) {

      switch(wParam) {

      case VK_LEFT:

          OffsetRect(&drt,-dx,0);

          break;

      case VK_RIGHT:

          OffsetRect(&drt,dx,0);

          break;

      case VK_UP:

          OffsetRect(&drt,0,-dy);

          break;

      case VK_DOWN:

          OffsetRect(&drt,0,dy);

          break;

      default:

          bAction=FALSE;

          break;

      }

   } else {

      switch(wParam) {

      case VK_LEFT:

          if (drt.right > drt.left + 10) {

             drt.right -= dx;

          }

          break;

      case VK_RIGHT:

          drt.right += dx;

          break;

      case VK_UP:

          if (drt.bottom > drt.top + 10) {

             drt.bottom -=dy;

          }

          break;

      case VK_DOWN:

          drt.bottom += dy;

          break;

      default:

          bAction=FALSE;

          break;

      }

   }

 

   if (bAction) {

      GetClientRect(hWnd,&crt);

      InflateRect(&crt,-10,-10);

      IntersectRect(&irt,&crt,&drt);

      if (!IsRectEmpty(&irt)) {

          arObj[NowSel]->rt=drt;

          InvalidateRect(hWnd,NULL,TRUE);

      }

   }

   return 0;

}

 

키보드로 이동 크기 변경을 하는 대상은 물론 선택된 도형이며 선택이 없다면 이동이나 크기 변경도 없다. , 키보드는 마우스와 달리 선택 툴이 아닐 때도 사용할 있다는 점이 다르다. NowTool 마우스를 누를 때의 동작에 영향을 주지만 키보드에는 영향을 주지 않는데 왜냐하면 어차피 키보드로는 새로운 도형을 만드는 방법이 제공되지 않기 때문이다. 키보드 입력은 무조건 선택 도형의 이동 또는 크기 변경으로 해석할 있다.

쉬프트키와 컨트롤키의 현재 상태는 GetKeyState 함수로 쉽게 구할 있으며 bControl값에 따라 이동 크기 변경의 단위인 dx, dy 달라진다. bShift FALSE이면 이동 처리를 하는데 도형의 영역을 dx, dy만큼 이동시키면 된다. bShift TRUE이면 크기 변경 처리를 하는데 도형의 좌상단은 고정해 놓고 우하단의 좌표만 조정하되 정규화 원칙을 항상 만족할 있도록 해야 한다.

키보드로 도형을 움직일 때도 캔버스 바깥으로 도형이 나갈 없도록 예외 처리를 필요가 있다. 키를 누를 때마다 도형의 위치와 크기가 바뀌며 매번 전체 화면을 다시 그리도록 했다. 캔버스가 입력을 받으려면 메인 윈도우가 포커스를 캔버스에게 양보해야 한다. 다음 코드를 추가한다.

 

LRESULT Main_OnSetFocus(HWND hWnd,WPARAM wParam,LPARAM lParam)

{

   SetFocus(hCanvas);

   return 0;

}

 

WM_KEYDOWN 포커스를 가진 윈도우에게만 전달되기 때문에 부모가 자식에게 포커스를 양보하지 않으면 캔버스가 입력을 받을 없다. ApiDraw 메인 윈도우는 어차피 껍데기에 불과하기 때문에 포커스를 가질 필요가 전혀 없다. 여기까지가 ApiDraw05이다.