더북(TheBook)

클래스 마법사를 통해 CImageToolDoc 클래스에 OnOpenDocumentOnSaveDocument 함수를 각각 재정의하면 헤더 파일인 ImageToolDoc.h 파일에 아래와 같은 함수 선언이 추가된다.

virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);

그리고 ImageToolDoc.cpp 파일에는 함수의 기본 틀이 만들어진다. 예를 들어 OnOpenDocument 함수는 아래와 같이 정의된다.

BOOL CImageToolDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
    if (!CDocument::OnOpenDocument(lpszPathName))
        return FALSE;

    // TODO: 여기에 특수화된 작성 코드를 추가합니다.

    return TRUE;
}

OnOpenDocumentOnSaveDocument 함수는 파일 선택 대화 상자에서 선택된 파일의 전체 경로 문자열을 가리키는 lpszPathName을 인자로 받는다. 그리고 파일 불러오기가 성공하면 TRUE를 반환하고, 만약 실패하면 FALSE를 반환하도록 규정되어 있다. 그러므로 함수 본문 중 // TODO:가 쓰여 있는 부분에 IppDib 클래스의 멤버 함수인 Load 또는 Save 함수를 호출하는 코드를 추가하고, Load 또는 Save 함수의 반환 값을 그대로 OnOpenDocumentOnSaveDocument 함수의 반환 값으로 사용하면 된다.

다만 한 가지 신경을 써야 하는 사항이 있는데, 파일 경로 명으로 전달되는 lpszPathName이 유니코드 문자열이라는 점이다. 반면에 IppDib 클래스의 Load 또는 Save 함수는 ANSI 문자열로 구성된 파일 경로 명을 인자로 받기 때문에 유니코드 문자열을 ANSI 문자열 형태로 변환해야 한다. 다행히 Visual C++에서는 CT2A라는 클래스를 이용하여 유니코드 문자열을 간단하게 ANSI 문자열로 변환할 수 있다. 아래 코드를 살펴보자.

CT2A filename(lpszPathName);
m_Dib.Load(filename);

CT2A 클래스 타입의 변수 filename을 새로 선언하면서 생성자 인자로 유니코드 문자열 주소 lpszPathName을 넘겨주었다. 이렇게 생성된 filename은 마치 LPCSTR, 즉 const char* 형태로 사용할 수 있다. 그러므로 Load 함수의 인자로 filename을 넘겨줄 수 있다. 위 코드를 더욱 간단하게 바꿀 수도 있다. filename 변수를 선언하지 않고 임시 객체를 사용하는 방식으로 아래와 같이 바꿔 써도 동작한다.

m_Dib.Load(CT2A(lpszPathName));

지금까지 설명한 내용들이 포함된 OnOpenDocumentOnSaveDocument 함수의 구현을 소스 5-2에 나타내었다.

소스 5-2 BMP 파일 입출력 기능이 추가된 OnOpenDocument와 OnSaveDocument 함수 구현(ImageToolDoc.cpp)
BOOL CImageToolDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
    if (!CDocument::OnOpenDocument(lpszPathName))
        return FALSE;

    return m_Dib.Load(CT2A(lpszPathName));
}

  
BOOL CImageToolDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
    return m_Dib.Save(CT2A(lpszPathName));
}
신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.