티스토리 뷰

프로그래밍/MFC

MFC 직렬화, CArchive

에어버스 2016. 6. 25. 15:27

MFC 직렬화

MFC에서 직렬화는 CArchive 클래스를 이용한 I/O 기법을 말한다.

Doc/View 구조에서는 직렬화 기능을 사용할 수 있도록 기본 코드를 생성해주므로 이를 이용하면 데이터를 저장하거나 읽어오는 코드를 편하게 작성할 수 있다.

마우스 왼쪽 버튼을 더블 클릭해서 변수값을 파일로 저장하고 우측버튼을 더블클릭하면 파일에서 변수로 읽어와 출력창에 표시하는 코드로 만들어진 파일 내용은 일반 텍스트가 아님을 알 수 있다.

- CArchive 생성자

1
CArchive(CFile* pFile, UINT nMode, int nBufSize = 4096void* 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,
 ULONGLONG, LONGLONG

 비 기본형

 RECT, POINT, SIZE, CRect, CPoint, CSize, CString, CTime, CTimeSpan, COleVariant,
 COleCurrency, COleDateTime, COleDataTimeSpan

<직렬화 적용 전 코드>

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(00255);
    pDoc->SetModifiedFlag();
    Invalidate();
}
cs

입력한 내용을 파일로 저장하고 읽어 올 수 있다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
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