본문 바로가기

Library/Windows Programming

WTL::CFileDialog, WTL::CMultiFileDialog

MFC에서 복수 파일을 선택하여 열기 / 저장을 하기 위해서는, CFileDialog 개체를 생성한 뒤, OFN_ALLOWMULTISELECT 플래그를 지정해야 한다. 그리고, OPENFILENAME 구조체의 lpstrFile에 선택한 파일들이 들어갈만한 충분한 버퍼를 할당해야 한다. OFN_ALLOWMULTISELECT 플래그를 지정했다고 하더라도, 할당한 버퍼의 크기가 충분하지 않으면 기대한 파일 목록을 얻지 못한다.

또, 이 파일들의 경로 따위를 얻어내기 위해서는 POSITION 구조체에 대해서 반복자를 적용하여 값을 얻어내야 하는데, 사실 Win32 API를 직접 사용하는 것보다 크게 나을 것이 없다. 무엇보다, POSITION 구조체에 반복자를 적용하는 것은 그렇다고 하더라도, 직접 버퍼를 할당하는 방식은 개체 지향 라이브러리라고 하기에는 뭔가 번지수가 맞지 않아 보인다.

이에 비해, WTL은 같은 작업을 훨씬 깔끔하게 처리할 수 있다. WTL은 여러 파일을 선택할 수 있는 파일 다이얼로그를 지원하기 위해 WTL::CFileDialog에서 OFN 관련 플래그를 지정하는 것이 아니라, CMultiFileDialog 개체를 생성하도록 한다. WTL::CMultiFileDialog는 MFC의 CFileDialog에 비해 선택한 파일들의 이름을 얻어내는 과정이 무척 단순하다. 특히, OFN 구조체가 필요로 하는 버퍼를 사용자가 직접 관리하지 않아도 내부에서 자동으로 관리해준다. 또, POSITION 구조체를 순회하면서 값을 얻어낼 필요없이, GetNextPathName()과 같은 멤버 함수를 사용하여 간단히 원하는 값을 얻어낼 수 있으며, 목록의 끝인지를 확인하기 위해서는 GetNextPathName()의 BOOL 값만 확인해보면 된다. 간단히 코드를 작성해본다면 다음과 같다.


WTL::CMultiFileDialog dlg; // 파라미터는 생략
if(dlg.DoModal() == IDOK)
{
    WTL::CString file;
    while(dlg.GetNextPathName(file))
    {
        // do something..
    }
}


MFC의 CFileDialog, 또는 Win32 API를 직접 사용하는 것보다 훨씬 깔끔하다.