각각 대략적으로 설명하면 Sandcastle은 도움말 파일을 만들기 위한 라이브러리, SHFB(Sandcastle Help File Builder)은 도움말 파일을 만드는 툴 정도로 생각하시면 됩니다.
(이외에 chm 파일을 만들기 위해서 "HTML Help Workshop"가 필요하지만 vs 등을 설치하면 기본적으로 설치되니 별도의 설치는 필요 없을 듯 합니다. 혹시 설치가 안되있다면 인터넷에서 그냥 받아서 설치하면 됩니다.)
설치 후에 생성된 시작메뉴에서 "Sandcastle Help File Builder GUI"를 실행합니다.
프로그램 실행 후에 File -> New Project나 툴바메뉴에서 가장 왼쪽 아이콘을 눌러서 새프로젝트를 생성합니다.
(도움말 파일을 만들기 위한 정보, 결과물이 저장될 수 있도록 작업 경로를 만드는 작업으로 적당한 폴더를 정해주고파일명을 적어준 후 저장 버튼을 누릅니다.)
프로젝트를 만들고 나면 아래 화면의 오른쪽에 보이는 것처럼 Project Explorer에서 Documentation Sources 항목이 있는데 여기서 마우스 오른쪽 버튼을 눌러서 Add Documentation Sources를 눌러서 위에서 설명했던 xml 파일과 dll 등의 프로젝트 결과물을 추가해줍니다.
(이외에 Visual Studio의 솔루션, 프로젝트 파일 등 다른 방법으로도 추가가 가능합니다.)
파일 추가가 끝나면 아래 화면의 왼쪽에 있는 Project Properties에서 적당히 설정을 해주고 Visual Studio에서 볼 수 있는 빌드 아이콘을 클릭해서 빌드를 합니다.
(설정은 기본적으로 Language 정도만 해주면 될 것 같고 때에 따라서 포맷, 스타일 정도를 지정해 주면 될 것 같네요...그리고 빌드 버튼은 Documentation -> Build Project 메뉴로도 가능합니다.)
빌드가 성공하면 아래처럼 빌드가 성공했다는 메시지가 나옵니다.
(빌드 시간은 좀 걸립니다.)
빌드가 성공적으로 끝나면 처음에 프로젝트 만들었던 폴더를 보면 Documentation.chm 파일로 도움말 파일이 완성되고 열어보면 아래처럼 결과가 나옵니다.
참고로 위 샘플에 쓰인 코드는 아래와 같습니다. XML 주석 부분이랑 결과를 비교해보세요.
프로젝트 클리너 - v0.2에 사용했던 MultipleSearchPattern을 라이브러리화 시켰습니다.
사용법은 dll, xml 파일을 같은 경로에 두고 프로젝트에서 참조시키면 되고, 모두 정적메소드로 만들었기 때문에 객체 생성없이 바로 사용하면 됩니다.
닷넷의 기본 DirectoryInfo.GetFiles(), DirectoryInfo.GetDirectories() 메소드의 searchPattern은 단일 조건밖에 되지 않는데 이것을 개선해서 여러 조건을 사용가능하게 해줍니다.
기본적인 사용법은 MS의 GetFiles(), GetDirectories() 메소드에 매개변수를 약간 변형시켰습니다.
일단 두 메소드 모두 첫번째 매개변수는 결과를 받을 배열로서 out 키워드를 이용해서 넘겨주면 메소드 실행 후 결과를 받을 수 있습니다. 기본적으로 string배열로 결과를 받을 수 있고, 각 메소드에 맞게 DirectoryInfo, FileInfo 배열로 결과를 받을 수 있습니다.
두번째 매개변수는 검색을 할 경로를 지정합니다. 단순히 하나의 경로에 대해서 처리할 때는 string형에 경로를 저장해서 넘겨주면 되고 복수의 경로에 대해서는 string배열로 넘겨주면 됩니다.
세번째, 네번째 매개변수는 searchPattern과 관련된 것으로 기본 문법은 MS의 메소드와 같지만 복수개의 조건을 지정하고 싶으면 char형의 구분자를 통해서 여러개의 조건을 지정할 수 있고 이떄 사용된 구분자는 네번째 매개변수로 넘겨줍니다.
(searchPattern의 자세한 내용은 http://msdn.microsoft.com/ko-kr/library/8he88b63.aspx 를 참고하세요.)
마지막으로 SearchOption은 검색경로에 대해서 하위 경로 포함여부를 정하는 것으로 MS 메소드에 사용하는 SearchOption을 그대로 사용합니다.
뭔가 플래그연산을 통해서 얻을 수 있을 것 같은데 못 찾겠고 일단 아래의 코드를 사용하면 작동합니다.
// 상태를 알고 싶은 커서 모양(예:IDC_IBEAM)으로 임시 커서 생성
HCURSOR loadCursor = LoadCursor(NULL, IDC_IBEAM);
// 현재 커서를 얻어 옴
CURSORINFO ci;
ci.cbSize = sizeof(CURSORINFO);
GetCursorInfo(&ci);
if( loadCursor == ci.hCursor )
{
// 조건이 True이면 현재 커서는 IDC_IBEAM
}
참고자료는 아래 사이트에 있는 내용인데 이상하게 전 아래 사이트에 있는 코드로는 작동이 안되더군요.