CArchive类



CArchive没有基类。
CArchive允许以一个永久二进制(通常为磁盘存储)的形式保存一个对象的复杂网络,它可以在对象被删除时,还能永久保存。可以从永久存储中装载对象,在内存中重新构造它们。使得数据永久保留的过程就叫作“串行化”。
可以把一个归档对象看作一种二进制流。象输入/输出流一样,归档与文件有关并允许写缓冲区以及从硬盘读出或读入数据。输入/输出流处理一系列ASCII字符,但是归档文件以一种有效率、精练的格式处理二进制对象。
必须在创建一个CArchive对象之前,创建一个CFile对象。另外,必须确信归档文件的装入/存储与文件的打开模式是兼容的。每一个文件只限于一个活动归档文件。
当构造一个CArchive对象时,要把它附加给表示一个打开文件的类CFile(或派生类)的对象上。还要指定归档文件将用于装载还是存储。
CArchive对象不仅可以处理首要类型,而且还能处理为串行化而设计的CObject派生类的对象。一个串行化类通常有一个Serialize成员函数并且使用DECLARE_SERIAL和IMPLEMENT_SERIAL宏。这些在CObject类中有所描述。
重载提取(>>)和插入(<<)是方便的归档编程接口。它支持主要类型和CObject派生类。
CArchive还支持使用MFC Windows套接字类CSocket和CSocketFile编程。IsBufferEmpty成员函数也支持这种使用。如果要了解有关CArchive的更多信息,请参阅联机文档“Visual C++ 程序员指南”中的“串行化(永久对象)” 和“Windows套接字:在归档文件中使用套接字”
#include <afx.h>

请参阅:CFileCObjectCSocketCSocketFile


CArchive类的成员

数据成员
m_pDocument指向被串行化的CDocument对象

构造函数
CArchive创建一个CArhcive对象
Abort在不异常的情况下,关闭归档文件
Close冲掉未写入数据并且释放与CFile的连接

基础输入/输出
Flush从归档文件缓冲区中冲掉未写入数据
operator >>装载对象和归档文件的主要类型
operator <<存储对象和归档文件的主要类型
Read读入原始类型
Write写入原始类型
WriteString写一行文本
ReadString读一行文本

状态
GetFile获得此归档文件的CFile对象指针
GetObjectSchema由Serialize函数调用来确定被非串行化的对象的版本
SetObjectSchema在归档文件中存储对象概要
IsLoading确定归档文件是否被装载
IsStoring确定归档文件是否被存储
IsBufferEmpty确定在一个Windows Socket接收过程中缓冲区是否被清空

对象输入/输出

ReadObject调用一个用于装载的Serialize函数
WriteObect调用一个用于装载的Serialize函数
MapObject在没有对文件串行化的映射中放置对象,但是此映射对参考的子对象有效
SetStoreParams设置哈希表的大小和映射的块的大小,在串行化的过程中识别唯一的对象
LoadParams设置装载数组扩展的大小。必须在被装载对象之前或调用MapObject或ReadObject之前
ReadClass读入一个原先存储在WriteClass中的类的参考
WriteClass把对CRuntime的参考写入CArchive
SerializeClass根据CArchive方向,读入或写入对CArchive对象的类的参考

CArchive类是使用了缓冲区,即一段内存空间作为临时数据存储地,对CArchive的读写都先依次排列到此缓冲区,当缓冲区满或用户要求时,将此段整理后的数据读写到指定的存储煤质。

一般来说,CArchive封装了对该缓冲区的操作,它的好处是可以少划动硬盘以及提高运行速度。不过对于使用MFC来说,是一个很好的封装。看看其对读写的操作,可见在实际编程上是非常容易出错的。对于这样的类,一定要封装好,作为一个公用函数或公用类调用,否则在实际中像c那样散在代码的各个地方的话,恐怕有时头会大。

有时我想,如果编程在这些地方磨洋工的话,恐怕一个大的工程软件写起来得好长时间。所以说尽量已组件的方式,类的思路来组合前人的算法,技巧也是一种编程的进步。

 

所下列看其对指针的娴熟操作(也是往往出错的啊),

例如双字的插入(写)

CArchive& CArchive::operator<<(DWORD dw)
{
   if (m_lpBufCur + sizeof(DWORD) > m_lpBufMax) //缓冲区空间不够
       Flush();                                  //缓冲区内容提交到实际存储煤质。
   if (!(m_nMode & bNoByteSwap))
     _AfxByteSwap(dw, m_lpBufCur);  //处理字节顺序
   else
     *(DWORD*)m_lpBufCur = dw;      //添入缓冲区
   m_lpBufCur += sizeof(DWORD);     //移动当前指针
   return *this;
}

双字的提取(读)

CArchive& CArchive::operator>>(DWORD& dw)
{
  if (m_lpBufCur + sizeof(DWORD) > m_lpBufMax) //缓冲区要读完了
      FillBuffer(sizeof(DWORD) - (UINT)(m_lpBufMax - m_lpBufCur));  //重新读入内容到缓冲区
   dw = *(DWORD*)m_lpBufCur;  //读取双字
   m_lpBufCur += sizeof(DWORD); //移动当前位置指针
   if (!(m_nMode & bNoByteSwap))
     _AfxByteSwap(dw, (BYTE*)&dw);  //处理字节顺序
   return *this;
}

 

内部指针

缓冲区指针 BYTE* m_lpBufStart,指向缓冲区,这个缓冲区有可能是底层CFile(如派生类CMemFile)对象提供的,但一般是CArchive自己建立的。

缓冲区尾部指针 BYTE* m_lpBufMax;

缓冲区当前位置指针 BYTE* m_lpBufCur;

初始化时,读模式,当前位置在尾部,是写模式,当前位置在头部:

m_lpBufCur = (IsLoading()) ? m_lpBufMax : m_lpBufStart;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图结构实现),并且可以打开已保存的图形文件进行编辑和保存修改后的图形文件。 这是一个相对复杂的问题,需要进行详细的解释和说明。我将尝试回答你的问题并提供一些指导。 首先,你需要创建一个 MFC 应用程序,并在其中创建一个文档/视图结构。然后,你需要在视图类中实现绘图功能。具体来说,你需要重写视图类的 OnDraw 函数,并在其中绘制所需的图形。你可以使用 CDC 类提供的函数来绘制线条、矩形、椭圆等基本图形。 接下来,你需要在视图类中实现鼠标事件处理函数,以响应鼠标的移动和点击事件。具体来说,你需要实现 OnLButtonDown、OnMouseMove 和 OnLButtonUp 函数。在这些函数中,你可以获取鼠标的位置信息,并根据需要更新所绘制的图形。 为了实现不同的线宽和颜色,你可以添加一些菜单项或对话框,用于选择线宽和颜色。当用户选择不同的线宽和颜色时,你需要相应地更新绘图属性,并在绘制图形时使用这些属性。 为了实现存储和加载图形文件,你需要使用 MFC 的 CArchive 类和文档/视图结构。具体来说,你需要重写文档类的 Serialize 函数,并在其中将绘图信息写入或读取自 CArchive 对象。同时,你需要添加一些菜单项或对话框,用于打开和保存图形文件。 综上所述,实现一个绘图板需要进行多方面的工作和调试。如果你是初学者,建议你先学习 MFC 的基本知识,并尝试实现一些简单的程序,然后再逐步深入学习和实现这个绘图板。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值