.파일 저장

다음은 편집하던 문서를 파일로 저장해 보자. ApiDraw 문서는 도형의 집합인 arObj 배열이므로 배열만 파일로 그대로 저장하면 된다. 어떤 방식을 사용하던 저장된 파일로부터 원래의 배열만 만들 있다면 제대로 저장한 것이다. 배열 앞에는 매직 넘버, 버전, 도형의 개수 등에 대한 간략한 정보를 가지는 헤더가 삽입되는데 헤더 구조체를 다음과 같이 선언한다. 가장 기본적인 파일 헤더 모양이다.

 

struct FileHeader

{

   TCHAR szHeader[32];

   int version;

   int arNum;

};

 

ApiDraw 문서 선두에 헤더를 작성하여 과연 ApiDraw 문서 파일이 맞는지, 읽을 있는 버전인지, 도형의 개수는 개인지 등에 대한 기본적인 정보를 저장할 것이다. 저장 동작은 파일의 이름을 어떻게 취급할 것인가에 따라 개의 함수로 나누어져 있다.

SaveToFile 함수는 지정한 이름의 파일로 저장하며 SaveAs 사용자에게 파일명을 물어 보도록 하며 Save 편집 문서가 이름을 가지는가 아닌가에 따라 적절한 함수를 호출한다. 사용자는 파일의 이름이 있건 없건 Save 함수만 호출하면 된다. 필요한 판단과 함수 호출은 Save 담당한다.

 

BOOL Save()

{

   if (lstrcmp(NowFile,"이름없음")==0) {

      return SaveAs();

   } else {

      return SaveToFile(NowFile);

   }

}

 

BOOL SaveAs()

{

   OPENFILENAME OFN;

   TCHAR lpstrFile[MAX_PATH]="";

 

   memset(&OFN, 0, sizeof(OPENFILENAME));

   OFN.lStructSize = sizeof(OPENFILENAME);

   OFN.hwndOwner=hWndMain;

   OFN.lpstrFilter="ApiDrawFile(*.adr)\0*.adr\0Every File(*.*)\0*.*\0";

   OFN.lpstrFile=lpstrFile;

   OFN.nMaxFile=256;

   OFN.lpstrDefExt="adr";

   if (GetSaveFileName(&OFN)==FALSE) {

      return FALSE;

   }

   ChangeCaption(OFN.lpstrFile);

   return SaveToFile(NowFile);

}

 

BOOL SaveToFile(TCHAR *Path)

{

   FileHeader Header;

   HANDLE hFile;

   DWORD dwWritten;

   int idx;

 

   hFile=CreateFile(Path,GENERIC_WRITE,0,NULL,

      CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);

   if (hFile==INVALID_HANDLE_VALUE) {

      return FALSE;

   }

 

   strcpy(Header.szHeader,"ApiDraw File");

   Header.version=100;

   Header.arNum=arNum;

   WriteFile(hFile,&Header,sizeof(Header),&dwWritten,NULL);

 

   for (idx=0;idx<arNum;idx++) {

      WriteFile(hFile,arObj[idx],sizeof(DObject),&dwWritten,NULL);

      if (arObj[idx]->Type >= DT_TEXT && arObj[idx]->Type <= DT_META) {

          WriteFile(hFile,arObj[idx]->Text,arObj[idx]->Len,&dwWritten,NULL);

      }

   }

 

   CloseHandle(hFile);

   bModified=FALSE;

   return TRUE;

}

 

실제로 ApiDraw 문서를 저장하는 함수는 SaveToFile 함수이다. 인수로 전달된 경로에 파일을 생성하고 헤더를 먼저 출력한 arObj 배열을 순서대로 파일로 출력한다. 단순 도형의 경우는 DObject 구조체만 저장하면 되지만 텍스트, 비트맵, 메타 객체는 Text 포인터가 가리키는 곳의 내용도 같이 출력해야 한다. 그렇지 않으면 텍스트에 어떤 문자열이 있었는지, 비트맵 파일의 그림은 어떤 것인지를 없을 것이다. 파일을 저장했으면 bModified FALSE 되어 편집되지 않은 상태가 된다.

SaveAs 파일 저장 공통 대화상자를 열어 사용자에게 저장할 파일명을 물어 보고 사용자가 선택한 이름으로 SaveToFile 호출한다. 디폴트 확장자를 adr 지정하여 사용자가 별도의 확장자를 입력하지 않으면 adr 확장자를 사용하도록 했다. Save 함수는 현재 편집하고 있는 문서가 이름이 있으면 SaveToFile 바로 호출하고 그렇지 않다면 SaveAs 호출하여 이름부터 입력받도록 한다. 파일을 저장하는 모든 함수들은 성공 여부를 리턴하여 ConfirmSave에서 파일이 제대로 저장되었는지 있도록 해야 한다.