. 커서 리소스 작성

선택영역에서 드래그할 때나 마진에 있을 때 커서모양을 바꾸는 코드는 작성했는데 실제로 보여주는 커서는 스톡 커서 중 비슷한 모양을 가진 것을 대신 사용하였다. 대충 비슷하기는 하지만 정확한 모양은 아니기 때문에 별로 마음에는 안 들 것이다. 커서 리소스를 작성하고 이 커서를 사용하도록 해보자.

파일/새로 만들기/파일 메뉴항목을 선택한 후 커서 파일을 선택하여 세 개의 커서 리소스를 만든 후 이 리소스를 각각 ApiEditMargin.cur, ApiEditMove.cur, ApiEditCopy.cur 이름으로 저장한다. CD-ROM에 있는 파일을 바로 복사해 와도 상관없다. 프로젝트에 커서를 직접 포함시키지 않고 순수하게 커서 파일만 만들어 놓은 것이다. 각 커서의 핫 스팟은 화살표의 끝 부분으로 지정하였다.

  

이렇게 만들어진 커서 리소스를 사용하려면 리소스 스크립트를 작성해야 한다. 프로젝트/새 항목 추가 메뉴를 선택한 후 ApiEdit.rc 리소스 스크립트를 추가해보자.

빈 리소스 스크립트가 프로젝트에 추가될 것이다. 이 스크립트에 앞에서 만들어 두었던 커서를 포함시킨다. 리소스 추가 대화상자의 가져오기 버튼을 클릭하여 커서 파일을 선택하면 된다.

 

추가된 커서는 디폴트로 IDC_CURSOR1,2,3이라는 정수 ID가 부여되는데 모두 파일 이름과 같은 이름의 문자열 ID로 변경한다. 리소스 속성창의 ID란에서 ID를 반드시 따옴표로 묶어야 한다.

리소스의 ID를 문자열로 주는 이유는 정수 ID는 호스트의 리소스와 충돌할 위험이 있기 때문이다. 문자열 이름은 우연히 충돌할 가능성이 극히 희박하여 안정적이다. OnCreate의 커서 초기화 코드를 다음과 같이 수정한다.

 

BOOL OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)

{

     ....

     hCCopy=LoadCursor(GetModuleHandle(NULL),"ApiEditCopy");

     if (hCCopy==NULL)

          hCCopy=LoadCursor(NULL,IDC_APPSTARTING);

     hCMove=LoadCursor(GetModuleHandle(NULL),"ApiEditMove");

     if (hCMove==NULL)

          hCMove=LoadCursor(NULL,IDC_ARROW);

     hCMargin=LoadCursor(GetModuleHandle(NULL),"ApiEditMargin");

     if (hCMargin==NULL)

          hCMargin=LoadCursor(NULL,IDC_SIZENESW);

 

     return TRUE;

}

 

문자열 ID를 주었으므로 MAKEINTRESOURCE 매크로를 쓸 필요없이 문자열로 커서 ID를 지정하며 정수 ID를 쓰지 않았으므로 resource.h를 인클루드할 필요도 없다. 혹시 리소스가 없다면 스톡 커서라도 사용하도록 하였다. 컴파일한 후 실행해보면 예쁜 모양의 커서를 볼 수 있을 것이다.

커서 리소스를 추가하는데 왜 이렇게 복잡한 과정을 거쳐야 하는가 하면 ApiEdit는 다른 프로젝트의 컨트롤로 사용될 모듈이기 때문이다. 컨트롤을 DLL로 배포한다면 리소스를 ApiEdit가 가져도 상관없지만 그렇지 않을 경우 컨트롤은 호스트가 제공하는 리소스를 사용해야 한다. 그래서 커서만 만들어 놓고 리소스는 호스트 프로젝트의 리소스에 추가해야 하는 것이다.

호스트에 커서 리소스를 추가하려면 세 개의 커서 파일을 호스트의 리소스 스크립트로 임포트하기만 하면 된다. 그래서 커서 파일을 분리된 파일로 따로 제작했으며 호스트의 다른 리소스와 ID가 충돌하지 않도록 하기 위해 문자열로 된 ID를 주었다. 리소스를 임포트하는 과정이 귀찮다면 커서 파일을 호스트 프로젝트 폴더로 복사한 후 RC 파일을 직접 열어 다음 문장을 추가하면 된다.

 

ApiEditMove             CURSOR  DISCARDABLE     "ApiEditMove.cur"

ApiEditCopy             CURSOR  DISCARDABLE     "ApiEditCopy.cur"

ApiEditMargin           CURSOR  DISCARDABLE     "ApiEditMargin.cur"

 

차후에 ApiEdit가 완전한 컨트롤이 되고 실제 사용된다면 이 작업을 다시 하기로 하자.