티스토리 뷰
MFC 직렬화
MFC에서 직렬화는 CArchive 클래스를 이용한 I/O 기법을 말한다.
Doc/View 구조에서는 직렬화 기능을 사용할 수 있도록 기본 코드를 생성해주므로 이를 이용하면 데이터를 저장하거나 읽어오는 코드를 편하게 작성할 수 있다.
마우스 왼쪽 버튼을 더블 클릭해서 변수값을 파일로 저장하고 우측버튼을 더블클릭하면 파일에서 변수로 읽어와 출력창에 표시하는 코드로 만들어진 파일 내용은 일반 텍스트가 아님을 알 수 있다.
- CArchive 생성자
1 |
CArchive(CFile* pFile, UINT nMode, int nBufSize = 4096, void* lpBuf = NULL); |
cs |
pFile : CFile 객체의 주소
nMode : 저장/읽기, CArchive::store / CArchive::load
nBufSize : CFile과 달리 CArchive는 내부 버퍼를 사용하고, 기본값은 4,096 이다
lpBuf : 사용자 정의 (힙)주소, 기본값은 NULL, CArchive는 힙(Heap)에 버퍼를 위한 메모리 할당한다.
CArchive 객체가 만들어지면 <<, >> 연산자를 사용해서 직렬화할 수 있다.
<MFC에서 기본 제공하는 직렬화 가능한 데이타 타입>
구분 |
데이터 타입 |
기본형 |
BYTE, WORD, LONG, DWORD, float, double, int, short, char, wchar_t, unsigned, bool, |
비 기본형 |
RECT, POINT, SIZE, CRect, CPoint, CSize, CString, CTime, CTimeSpan, COleVariant, |
<직렬화 적용 전 코드>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 |
void CMFCApplication4View::OnLButtonDblClk(UINT nFlags, CPoint point)
{
CFile file;
CFileException e;
if (!file.Open(L"mytest.dat", CFile::modeReadWrite | CFile::modeCreate, &e))
{
e.ReportError();
return;
}
int a = 100;
int b = 200;
file.Write(&a, sizeof(a));
file.Write(&b, sizeof(b));
CView::OnLButtonDblClk(nFlags, point);
}
void CMFCApplication4View::OnRButtonDblClk(UINT nFlags, CPoint point)
{
CFile file;
CFileException e;
if (!file.Open(L"mytest.dat", CFile::modeRead, &e))
{
e.ReportError();
return;
}
int a, b;
file.Read(&a, sizeof(a));
file.Read(&b, sizeof(b));
TRACE(L"a = %d, b = %d\n", a, b);
CView::OnRButtonDblClk(nFlags, point);
} |
cs |
CArchive 객체를 이용하면 CFile::Write()/CFile::Read() 대신 <<, >> 연산자를 이용하여 파일 입출력이 가능해진다. 이때는 CArchive와 CFile 두 객체가 필요해진다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 |
void CMFCApplication4View::OnLButtonDblClk(UINT nFlags, CPoint point)
{
CFile file;
CFileException e;
if (!file.Open(L"mytest.dat", CFile::modeReadWrite | CFile::modeCreate, &e))
{
e.ReportError();
return;
}
int a = 100;
int b = 200;
// file.Write(&a, sizeof(a));
// file.Write(&b, sizeof(b));
CArchive ar(&file, CArchive::store);
ar << a << b;
CView::OnLButtonDblClk(nFlags, point);
}
void CMFCApplication4View::OnRButtonDblClk(UINT nFlags, CPoint point)
{
CFile file;
CFileException e;
if (!file.Open(L"mytest.dat", CFile::modeRead, &e))
{
e.ReportError();
return;
}
int a, b;
// file.Read(&a, sizeof(a));
// file.Read(&b, sizeof(b));
CArchive ar(&file, CArchive::load);
ar >> a >> b;
TRACE(L"a = %d, b = %d\n", a, b);
CView::OnRButtonDblClk(nFlags, point);
} |
cs |
Doc/View 구조의 응용 프로그램에서는 파일을 열거나 저장할때 CFile 객체와 CArchive 객체를 MFC에서 자동으로 만들어 주므로 사용자는 Serialize()를 재정의하여 어떤 데이터를 저장 혹은 읽어 올건지 지정해주면 된다.
<코드3>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 |
class CMFCApplication4Doc : public CDocument
{
...
public:
CString m_str;
COLORREF m_color;
};
void CMFCApplication4Doc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
ar << m_str << m_color;
}
else
{
ar >> m_str >> m_color;
}
}
void CMFCApplication4View::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CMFCApplication4Doc* pDoc = GetDocument();
pDoc->m_str += (char)nChar; // 한글 깨짐
pDoc->SetModifiedFlag(); // Doc 자신의 데이터가 변경되었음 표시
Invalidate();
CView::OnChar(nChar, nRepCnt, nFlags);
}
void CMFCApplication4View::OnDraw(CDC* pDC)
{
...
CFont font;
font.CreatePointFont(200, L"나눔고딕");
pDC->SelectObject(&font);
pDC->SetTextColor(pDoc->m_color);
CRect rect;
GetClientRect(&rect);
pDC->DrawText(pDoc->m_str, &rect, DT_LEFT);
}
void CMFCApplication4View::OnColorBlue()
{ // 메뉴 추가해서 이벤트 핸들러 추가
CMFCApplication4Doc* pDoc = GetDocument();
pDoc->m_color = RGB(0, 0, 255);
pDoc->SetModifiedFlag();
Invalidate();
} |
cs |
입력한 내용을 파일로 저장하고 읽어 올 수 있다.