Visual C 2010 MFC Programming 7 CFile n

  • Slides: 49
Download presentation
윈도우 프로그래밍 Visual C++ 2010 MFC Programming 7장. 파일 입출력

윈도우 프로그래밍 Visual C++ 2010 MFC Programming 7장. 파일 입출력

CFile 클래스 n 열기와 생성 try { CFile file(_T("mytest. txt"), CFile: : mode. Read.

CFile 클래스 n 열기와 생성 try { CFile file(_T("mytest. txt"), CFile: : mode. Read. Write); } catch (CFile. Exception* e) { e->Report. Error(); e->Delete(); } CFile file; CFile. Exception e; if(!file. Open(_T("mytest. txt"), CFile: : mode. Read. Write, &e)) e. Report. Error();

CFile 클래스 n 닫기 : 방법 1 void CEx. File. View: : On. LButton.

CFile 클래스 n 닫기 : 방법 1 void CEx. File. View: : On. LButton. Down(UINT n. Flags, CPoint point) { CFile file; CFile. Exception e; if(!file. Open(_T("mytest. txt“), CFile: : mode. Read. Write, &e)){ e. Report. Error(); return; }. . . } // CFile: : ~CFile() 소멸자가 호출된다. 7

CFile 클래스 n 닫기 : 방법 2 void CChild. View: : On. LButton. Down(UINT

CFile 클래스 n 닫기 : 방법 2 void CChild. View: : On. LButton. Down(UINT n. Flags, CPoint point) { CFile file; CFile. Exception e; if(!file. Open(_T("mytest 1. txt"), CFile: : mode. Read. Write ㅣCFile: : mode. CreateㅣCFile: : mode. No. Truncate, &e)) { e. Report. Error(); return; }. . . file. Close(); 8

CFile 클래스 n 읽기와 쓰기 UINT CFile: : Read(void* lp. Buf, UINT n. Count);

CFile 클래스 n 읽기와 쓰기 UINT CFile: : Read(void* lp. Buf, UINT n. Count); void CFile: : Write(const void* lp. Buf, UINT n. Count); n 입출력 위치 변경하기 ULONG CFile: : Seek(LONG l. Off, UINT n. From); // MFC 7. 0 ~ LONG CFile: : Seek(LONG l. Off, UINT n. From); // ~ MFC 6. 0 n. From 의미 CFile: : begin 파일의 처음 위치에서 l. Off만큼 파일 포인터 이동 CFile: : current 현재 파일 포인터 위치에서 l. Off만큼 파일 포인터 이동 CFile: : end 파일의 끝 위치에서 l. Off만큼 파일 포인터 이동

CFile 클래스 CFile cfile; cfile. Open(_T("Write_File. dat"), CFile: : mode. Create | CFile: :

CFile 클래스 CFile cfile; cfile. Open(_T("Write_File. dat"), CFile: : mode. Create | CFile: : mode. Read. Write); char pbuf. Write[100]; memset(pbuf. Write, 'a', sizeof(pbuf. Write)); cfile. Write(pbuf. Write, 100); cfile. Flush(); cfile. Seek. To. Begin(); char pbuf. Read[100]; cfile. Read(pbuf. Read, sizeof(pbuf. Read)); ASSERT(0 == memcmp(pbuf. Write, pbuf. Read, sizeof(pbuf. Write)));

도큐먼트/뷰 구조 n SDI와 MDI 다룰 수 있는 문서의 개수에 따라 구분 SDI :

도큐먼트/뷰 구조 n SDI와 MDI 다룰 수 있는 문서의 개수에 따라 구분 SDI : Single Document Interface MDI : Multiple Document Interface 18

도큐먼트/뷰 구조 n Init. Instance() 함수 BOOL CFile. IOTest. App: : Init. Instance() {.

도큐먼트/뷰 구조 n Init. Instance() 함수 BOOL CFile. IOTest. App: : Init. Instance() {. . . CSingle. Doc. Template* p. Doc. Template; p. Doc. Template = new CSingle. Doc. Template( IDR_MAINFRAME, // 리소스 ID RUNTIME_CLASS(CFile. IOTest. Doc), // 도큐먼트 클래스 정보 RUNTIME_CLASS(CMain. Frame), // 프레임 윈도우 클래스 정보 RUNTIME_CLASS(CFile. IOTest. View)); // 뷰 클래스 정보 if(!p. Doc. Template) return FALSE; Add. Doc. Template(p. Doc. Template); // 응용 프로그램 객체에 도큐먼트 템플릿 등록. . . } 20

void CFile. IOTest. View: : On. Draw(CDC* p. DC) { CFile. IOTest. Doc* p.

void CFile. IOTest. View: : On. Draw(CDC* p. DC) { CFile. IOTest. Doc* p. Doc = Get. Document(); ASSERT_VALID(p. Doc); if (!p. Doc) return; // TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다. p. DC->Set. Map. Mode(MM_LOMETRIC); p. DC->Rectangle(50, -50, 550, -550); p. DC->Ellipse(600, -50, 1100, -550); }

도큐먼트/뷰 구조 분석 n 응용 프로그램 클래스 (1/3) File. IOTest. App. cpp . .

도큐먼트/뷰 구조 분석 n 응용 프로그램 클래스 (1/3) File. IOTest. App. cpp . . . BEGIN_MESSAGE_MAP(CFile. IOTest. App, CWin. App) ON_COMMAND(ID_APP_ABOUT, &CFile. IOTest. App: : On. App. About) ➊ ON_COMMAND(ID_FILE_NEW, &CWin. App: : On. File. New) ON_COMMAND(ID_FILE_OPEN, &CWin. App: : On. File. Open) ON_COMMAND(ID_FILE_PRINT_SETUP, &CWin. App: : On. File. Print. Setup) END_MESSAGE_MAP(). . . BOOL CFile. IOTest. App: : Init. Instance() {. . . ➋ Load. Std. Profile. Settings(4); ① [파일]-[새 파일]/[열기]/[인쇄설정] 메뉴 핸들러를 CWin. App 의 기본 핸들러로 지정 ② 가장 최근 사용한 (MRU: Most Recently Used) 파일 목록 로드 (4개) 25

도큐먼트/뷰 구조 분석 n 응용 프로그램 클래스 (2/3) ➌ CSingle. Doc. Template* p. Doc.

도큐먼트/뷰 구조 분석 n 응용 프로그램 클래스 (2/3) ➌ CSingle. Doc. Template* p. Doc. Template; p. Doc. Template = new CSingle. Doc. Template( IDR_MAINFRAME, RUNTIME_CLASS(CFile. IOTest. Doc), RUNTIME_CLASS(CMain. Frame), RUNTIME_CLASS(CFile. IOTest. View)); if(!p. Doc. Template) return FALSE; Add. Doc. Template(p. Doc. Template); ➍ CCommand. Line. Info cmd. Info; Parse. Command. Line(cmd. Info); ③ 도큐먼드 탬플릿 객체 동적 생성 후 응용 프로그램 객체에 등록 ④ 명령행 인자 (cmd. Info) 전달 26

도큐먼트/뷰 구조 분석 n 응용 프로그램 클래스 (3/3) ➎ if(!Process. Shell. Command(cmd. Info)) return

도큐먼트/뷰 구조 분석 n 응용 프로그램 클래스 (3/3) ➎ if(!Process. Shell. Command(cmd. Info)) return FALSE; ➏ m_p. Main. Wnd->Show. Window(SW_SHOW); m_p. Main. Wnd->Update. Window(); return TRUE; } ⑤ 도큐먼드, 프레임 윈도우, 뷰 객체 생성 ⑥ 프레임 윈도우 화면 표시하고 (Show. Window()), WM_PAINT 메시지 핸들러 실행 (CWnd: : Update. Window) 27

도큐먼트/뷰 구조 분석 n 프레임 윈도우 클래스 Main. Frm. h class CMain. Frame :

도큐먼트/뷰 구조 분석 n 프레임 윈도우 클래스 Main. Frm. h class CMain. Frame : public CFrame. Wnd { protected: . . . ➊ DECLARE_DYNCREATE(CMain. Frame). . . }; Main. Frm. cpp . . . ➋ IMPLEMENT_DYNCREATE(CMain. Frame, CFrame. Wnd). . . ① ② : 프레임 윈도우 객체의 동적 생성을 지원하는 마크로 CWin. App: : Process. Shell. Command() 실행 중 생성됨 28

도큐먼트/뷰 구조 분석 n 뷰 클래스 (1/2) class CFile. IOTest. View : public CView

도큐먼트/뷰 구조 분석 n 뷰 클래스 (1/2) class CFile. IOTest. View : public CView File. IOTest. View. h { protected: . . . ➊ DECLARE_DYNCREATE(CFile. IOTest. View) public: ➋ CFile. IOTest. Doc* Get. Document() const; // 도큐먼트 객체 주소 리턴 … Public: ➌ virtual void On. Draw(CDC* p. DC); // On. Paint 기능 수행, CDC 객체 생성 불필요 … // 인쇄/인쇄 미리보기 에도 사용 protected: ➍ virtual BOOL On. Prepare. Printing(CPrint. Info* p. Info); //[파일]-[인쇄. . ] 시 호출 virtual void On. Begin. Printing(CDC* p. DC, CPrint. Info* p. Info); virtual void On. End. Printing(CDC* p. DC, CPrint. Info* p. Info); . . . }; #ifndef _DEBUG ➎ inline CFile. IOTest. Doc* CFile. IOTest. View: : Get. Document() const {return reinterpret_cast<CFile. IOTest. Doc*>(m_p. Document); } #endif 29

도큐먼트/뷰 구조 분석 n 뷰 클래스 (2/2) File. IOTest. View. cpp . . .

도큐먼트/뷰 구조 분석 n 뷰 클래스 (2/2) File. IOTest. View. cpp . . . ➏ IMPLEMENT_DYNCREATE(CFile. IOTest. View, CView) BEGIN_MESSAGE_MAP(CFile. IOTest. View, CView) ➐ ON_COMMAND(ID_FILE_PRINT, &CView: : On. File. Print) //[파일]-[인쇄] 메뉴 핸들러 지정 ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView: : On. File. Print) ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView: : On. File. Print. Preview) END_MESSAGE_MAP(). . . ➑ void CFile. IOTest. View: : On. Draw(CDC* p. DC) // On. Paint 기능 수행, CDC 객체 생성 불필요 { CFile. IOTest. Doc* p. Doc = Get. Document(); ASSERT_VALID(p. Doc); if(!p. Doc) return; p. DC->Set. Map. Mode(MM_LOMETRIC); p. DC->Rectangle(50, -50, 550, -550); p. DC->Ellipse(600, -50, 1100, -550); }. . . ➒ BOOL CFile. IOTest. View: : On. Prepare. Printing(CPrint. Info* p. Info) { return Do. Prepare. Printing(p. Info); } void CFile. IOTest. View: : On. Begin. Printing(CDC* /*p. DC*/, CPrint. Info* /*p. Info*/) { } 30

도큐먼트/뷰 구조 분석 n 도큐먼트 클래스 (1/2) class CFile. IOTest. Doc : public CDocument

도큐먼트/뷰 구조 분석 n 도큐먼트 클래스 (1/2) class CFile. IOTest. Doc : public CDocument { protected: CFile. IOTest. Doc(); ➊ DECLARE_DYNCREATE(CFile. IOTest. Doc) Flie. IOTest. Doc. h public: ➋ virtual BOOL On. New. Document(); ➌ virtual void Serialize(CArchive& ar); #ifdef SHARED_HANDLERS. . . #endif ② : [파일]-[새로 만들기] 시 자동 호출 , CDocument: : On. New. Document() 재 정의 ② : CObject: : Serialize() 재 정의, 직렬화 기능 구현 31

직렬화 기초 n 직렬화 영속적인 저장 매체에 객체의 내용을 저장하거나 읽어오 는 기법 n

직렬화 기초 n 직렬화 영속적인 저장 매체에 객체의 내용을 저장하거나 읽어오 는 기법 n 데이터 쓰기 - 일반 파일 입출력 void CFile. IOTest. View: : On. LButton. Down(UINT n. Flags, CPoint point) { CFile file; CFile. Exception e; if(!file. Open(_T("mytest. dat"), CFile: : mode. WriteㅣCFile: : mode. Create, &e)) { e. Report. Error(); return; } double a = 1. 23; double b = 4. 56; file. Write(&a, sizeof(a)); file. Write(&b, sizeof(b)); }

직렬화 기초 n 데이터 읽기 - 일반 파일 입출력 void CFile. IOTest. View: :

직렬화 기초 n 데이터 읽기 - 일반 파일 입출력 void CFile. IOTest. View: : On. RButton. Down(UINT n. Flags, CPoint point) { CFile file; CFile. Exception e; if(!file. Open(_T("mytest. dat"), CFile: : mode. Read, &e)){ e. Report. Error(); return; } double a, b; file. Read(&a, sizeof(a)); file. Read(&b, sizeof(b)); TRACE(_T("a = %f, b = %f₩n"), a, b); } 34

직렬화 기초 n 데이터 쓰기 - 직렬화 void CFile. IOTest. View: : On. LButton.

직렬화 기초 n 데이터 쓰기 - 직렬화 void CFile. IOTest. View: : On. LButton. Down(UINT n. Flags, CPoint point) { CFile file; CFile. Exception e; if(!file. Open(_T("mytest. dat"), CFile: : mode. WriteㅣCFile: : mode. Create, &e)) { e. Report. Error(); return; } double a = 1. 23; double b = 4. 56; CArchive ar(&file, CArchive: : store); ar << a << b; } 35

직렬화 기초 n 데이터 읽기 - 직렬화 void CFile. IOTest. View: : On. RButton.

직렬화 기초 n 데이터 읽기 - 직렬화 void CFile. IOTest. View: : On. RButton. Down(UINT n. Flags, CPoint point) { CFile file; CFile. Exception e; if(!file. Open(_T("mytest. dat"), CFile: : mode. Read, &e)){ e. Report. Error(); return; } double a, b; CArchive ar(&file, CArchive: : load); ar >> a >> b; TRACE(_T("a = %f, b = %f₩n"), a, b); } 36

직렬화 기초 n CArchive 클래스 생성자 CArchive: : CArchive(CFile* p. File, UINT n. Mode,

직렬화 기초 n CArchive 클래스 생성자 CArchive: : CArchive(CFile* p. File, UINT n. Mode, void*lp. Buf=NULL); int n. Buf. Size=4096, p. File – CFile 객체 n. Mode – CArchive: : load 또는 CArchive: : store n. Buf. Size – CArchive 클래스 내부에서 사용할 버퍼 크기 lp. Buf – 사용자 정의 버퍼의 주소 37

직렬화 기초 n 직렬화 가능한 데이터 타입 구분 데이터 타입 기본형 BYTE, WORD, LONG,

직렬화 기초 n 직렬화 가능한 데이터 타입 구분 데이터 타입 기본형 BYTE, WORD, LONG, DWORD, float, double, int, short, char, wchar_t, unsigned 비기본형 RECT, POINT, SIZE, CRect, CPoint, CSize, CString, CTime. Span, COle. Variant, COle. Currency, COle. Date. Time, COle. Data. Time. Span 38

도큐먼트/뷰 구조와 직렬화 n [파일]->[열기. . . ] 메뉴를 선택한 경우 ON_COMMAND(ID_FILE_OPEN, &CWin. App:

도큐먼트/뷰 구조와 직렬화 n [파일]->[열기. . . ] 메뉴를 선택한 경우 ON_COMMAND(ID_FILE_OPEN, &CWin. App: : On. File. Open) BOOL CDocument: : On. Open. Document(LPCTSTR lpsz. Path. Name) { …(CFile 객체를 생성한다; p. File은 CFile 객체의 주소값을 담고 있다. ) … CArchive ar(p. File, CArchive: : loadㅣCArchive: : b. No. Flush. On. Delete); … Serialize(ar) … } 40

도큐먼트/뷰 구조와 직렬화 n [파일]->[저장] 또는 [다른 이름으로 저장. . . ] 메 뉴를

도큐먼트/뷰 구조와 직렬화 n [파일]->[저장] 또는 [다른 이름으로 저장. . . ] 메 뉴를 선택한 경우 ON_COMMAND(ID_FILE_SAVE, On. File. Save) ON_COMMAND(ID_FILE_SAVE_AS, On. File. Save. As) BOOL CDocument: : On. Save. Document(LPCTSTR lpsz. Path. Name) { …(CFile 객체를 생성한다; p. File은 CFile 객체의 주소값을 담고 있다. ) … CArchive ar(p. File, CArchive: : storeㅣCArchive: : b. No. Flush. On. Delete); … Serialize(ar) … } 41

Document ① #include <afxtempl. h> BOOL CInput. Save. Load. Doc: : On. New. Document()

Document ① #include <afxtempl. h> BOOL CInput. Save. Load. Doc: : On. New. Document() { if (!CDocument: : On. New. Document()) return FALSE; class CInput. Save. Load. Doc : public CDocument { public: CArray<TCHAR, TCHAR> m_str; BOOL m_b. Italic, m_b. Underline; ② m_str. Remove. All(); m_b. Italic = m_b. Underline = FALSE; // 글자 저장 // 스타일 저장 return TRUE; } ③ void CInput. Save. Load. View: : On. Char(UINT n. Char, UINT n. Rep. Cnt, UINT n. Flags) { CInput. Save. Load. Doc* p. Doc = Get. Document(); View // Backspace 입력 시 맨 마지막 글자를 삭제한다. if(n. Char == _T('b')){ if(p. Doc->m_str. Get. Size() > 0) p. Doc->m_str. Remove. At(p. Doc->m_str. Get. Size()-1); } // 그 밖의 경우에는 동적 배열에 글자를 추가한다. else{ p. Doc->m_str. Add(n. Char); } ④ void CInput. Save. Load. View: : On. Draw(CDC* p. DC) { CInput. Save. Load. Doc* p. Doc = Get. Document(); ASSERT_VALID(p. Doc); if (!p. Doc) return; // 화면 출력용 폰트를 선택한다. CFont font; font. Create. Font(30, 0, 0, p. Doc->m_b. Italic, p. Doc->m_b. Underline, 0, 0, 0, _T("궁서")); p. DC->Select. Object(&font); // 현재까지 입력된 글자를 화면에 출력한다. CRect rect; Get. Client. Rect(&rect); p. DC->Draw. Text(p. Doc->m_str. Get. Data(), p. Doc->m_str. Get. Size(), &rect, DT_LEFT); // 데이터가 수정되었음을 도큐먼트 객체에 알린다. p. Doc->Set. Modified. Flag(); // 뷰의 화면을 갱신한다. Invalidate(); } }

Document void CInput. Save. Load. Doc: : On. Style. Italic() { m_b. Italic =

Document void CInput. Save. Load. Doc: : On. Style. Italic() { m_b. Italic = !m_b. Italic; Set. Modified. Flag(); Update. All. Views(NULL); // 뷰의 화면을 갱신한다. CWnd: : Invalidate 대신 } void CInput. Save. Load. Doc: : On. Style. Underline() { m_b. Underline = !m_b. Underline; Set. Modified. Flag(); Update. All. Views(NULL); // 뷰의 화면을 갱신한다. } void CInput. Save. Load. Doc: : On. Update. Style. Italic(CCmd. UI *p. Cmd. UI) { p. Cmd. UI->Set. Check(m_b. Italic == TRUE); } void CInput. Save. Load. Doc: : On. Update. Style. Underline(CCmd. UI *p. Cmd. UI) { p. Cmd. UI->Set. Check(m_b. Underline == TRUE); }

Document void CInput. Save. Load. Doc: : Serialize(CArchive& ar) { if (ar. Is. Storing())

Document void CInput. Save. Load. Doc: : Serialize(CArchive& ar) { if (ar. Is. Storing()) { ar << m_b. Italic << m_b. Underline; m_str. Serialize(ar); // 직렬화 클래스 } else { ar >> m_b. Italic >> m_b. Underline; m_str. Serialize(ar); } }

직렬화 클래스 구현 n 사용자 정의 클래스 class CMy. Data { public: CString m_str;

직렬화 클래스 구현 n 사용자 정의 클래스 class CMy. Data { public: CString m_str; COLORREF m_color; public: CMy. Data(CString &str, COLORREF &color) { m_str = str; m_color = color; } virtual ~CMy. Data(); }; Ø 직렬화 X 지원 안됨 void Ø CFile. IOTest. Doc: : Serialize(CArchive& ar) { if (ar. Is. Storing()) { ar << m_data; // Error } else { ar >> m_data; // Error } } 46

직렬화 클래스 구현 n 사용자 정의 클래스 변경 (1/2) /* 클래스 선언부 */ ➊

직렬화 클래스 구현 n 사용자 정의 클래스 변경 (1/2) /* 클래스 선언부 */ ➊ class CMy. Data : public CObject { ➋ DECLARE_SERIAL(CMy. Data) public: CString m_str; COLORREF m_color; public: ➌ CMy. Data() { } CMy. Data(CString &str, COLORREF &color) { m_str = str; m_color = color; } virtual ~CMy. Data(); ➍ void Serialize(CArchive& ar); }; 47

직렬화 클래스 구현 n 사용자 정의 클래스 변경 (2/2) /* 클래스 구현부 */ CMy.

직렬화 클래스 구현 n 사용자 정의 클래스 변경 (2/2) /* 클래스 구현부 */ CMy. Data: : ~CMy. Data() { } ➎ IMPLEMENT_SERIAL(CMy. Data, CObject, 1) ➏ void CMy. Data: : Serialize (CArchive& ar) { CObject: : Serialize(ar); if(ar. Is. Storing()) ar << m_str << m_color; else ar >> m_str >> m_color; } 48

직렬화 클래스 구현 n 직렬화 O void CFile. IOTest. Doc: : Serialize(CArchive& ar) {

직렬화 클래스 구현 n 직렬화 O void CFile. IOTest. Doc: : Serialize(CArchive& ar) { if(ar. Is. Storing()) { m_data. Serialize(ar); } else { m_data. Serialize(ar); } } 49