. 목록 조사

파일창의 코드 대부분은 하드디스크로부터 폴더와 파일의 목록을 읽어오고 목록을 정렬하는 코드이다. WM_CREATE에서는 파일 트리를 초기화하기 위해 InitTree 함수를 호출하는데 이 함수는 시스템에 장착된 모든 드라이브의 목록과 네트워크로 연결된 드라이브의 목록을 조사하여 파일 트리에 노드로 등록한다. CD-ROM 드라이브는 읽기는 가능하지만 쓰기는 불가능하므로 아예 목록에 표시하지 않았으며 램 디스크나 이동식 디스크도 목록에서 제외하였다. 이런 드라이브들은 탈착을 관리하는 것이 쉽지 않기 때문에 미니 탐색기에서 제대로 보여주기가 어렵다.

드라이브 노드를 파일 트리에 등록할 때 차일드의 개수를 1로 설정했는데 이렇게 하면 노드 앞에 <+> 버튼이 나타나며 <+> 버튼을 클릭하면 드라이브에 포함된 폴더 목록을 읽어온다. 드라이브에 포함된 모든 서브폴더를 시작할 때 다 읽어 놓으려면 엄청난 시간이 소요되기 때문에 미리 폴더 전체를 다 읽지 않으며 부모 노드가 펼쳐질 때 하위 노드를 읽으면 된다. 이런 기법은 API 정복 18장의 cChildren 예제에 잘 설명되어 있으므로 참고하기 바란다.

파일 트리는 <+> 버튼을 클릭하여 노드를 확장할 때 TVN_ITEMEXPANDING 통지 메시지를 보내며 이때 확장된 노드의 하위 항목을 읽어오면 된다. GetNodePath 함수는 특정 노드의 완전 경로를 조사한다. 검색을 시작한 노드로부터 계속 부모 노드를 찾아 올라가면서 노드의 텍스트를 붙여 나가면 이 노드의 완전 경로를 구할 수 있다.

부모 노드가 최상위 노드이면 드라이브이므로 드라이브 문자 :을 취하고 폴더일 경우 \를 중간에 넣어 주면 된다. 이렇게 노드의 완전 경로를 구했으면 앞장에서 검색을 위해 만들어 두었던 FindInFiles 함수를 호출하여 이 폴더 아래의 모든 파일과 폴더를 구한다. FindInFiles 함수는 파일검색 함수에서도 사용하므로 중간에 검색이 취소된 경우를 위해 bContFIF TRUE로 변경해야 한다.

FindInFiles 함수의 콜백 함수로 OnFindNode 함수를 지정했으므로 파일이나 폴더가 발견될 때마다 이 함수가 호출될 것이다. 사용자정의 데이터로는 확장된 노드의 ID를 전달하여 발견된 항목을 이 노드에 등록하도록 했다. 확장된 폴더 바로 아래의 항목들만 읽어오면 되므로 FIF_DEEP 플래그를 줄 필요가 없다. 대신 숨김 파일도 표시 옵션이 선택되어 있으면 FIF_INCHID 플래그를 줘야 한다.

OnFindNode에서는 발견된 파일이나 폴더를 사용자정의 데이터로 전달된 노드 아래에 추가한다. 발견된 순서대로 항목을 추가하는 것이 아니라 알파벳순으로 정렬하되 폴더를 우선적으로 추가하고 파일을 폴더 다음에 추가하도록 했다. FindInsAfter 함수는 삽입된 노드의 이미지 인덱스와 파일명을 인수로 전달하면 어디쯤에 삽입되어야 할 것인가를 계산하는 도우미 함수이다.

OnFindNode 함수는 FindInsAfter 함수가 계산하는 위치에 발견된 항목을 추가한다. 그래서 파일창은 항상 폴더를 우선으로 배치하고 난 다음에 파일이 폴더 뒤에 배치된다. 폴더 노드를 추가할 때는 이 폴더가 비어 있는지 아닌지를 조사한 후에 비어 있지 않으면 하위 항목을 읽어올 수 있도록 <+> 버튼을 표시했다. 필터에서 지정한 조건에 맞는 파일이 하나도 없을 때 비어 있는 폴더로 간주된다.