打开文件类之间关联
在向导创建的应用程序中,程序的默认菜单有“文件”、“编辑”、“视图”和“帮助”。当运行程序后,打开“文件”菜单中的“打开”命令时,应用程序会自动打开相应的“打开”文件通用对话框。之所以有这功能,是因为向导创建的应用程序框架中,自动将“打开”菜单命令与CWinApp的OnFileOpen成员函数相关联。
当用户在通用“打开”文件对话框中指定一个文件后,应用程序将调用文档对象的CDocument::OnOpenDocument虚成员函数。该函数将打开文件,并调用DeleteContents清除文档对象的内容,然后创建一个CArchive(归档类)对象用于数据的读取,接着又自动调用Serialize函数。之后便调用视图对象的CView::OnInitialUpdate虚成员函数。
上述的Serialize函数是一个很特别的函数,它既可以从中读取文档数据,也可以保存文档数据,称为“序列化”函数。它被添加用户的文档类中,用来根据CArchive内部的一个标志来决定文档数据的流向(读或写),
打开机制:可以看到消息映射ON_COMMAND(ID_FILE_OPEN,CWinApp::OnFileOpen),如果你没有映射ID_FILE_OPEN消息,就会调用CWinApp::OnFileOpen,否则调用你的消息映射函数。在CWinApp::OnFileOpen中调用CDocManager::OnFileOpen(),这样函数完成以下任务:1。弹出对话框让用户选择待打开的文件,返回该文件的全路径名称, 供下面函数调用时使用2。调用应用程序的OpenDocumentFile(LPCTSTR lpszFileName)。至此,这个对话框的出处就真相大白了。
文档数据的读操作
对于上述过程,我们所做的仅仅是在文档类的Serialize函数中添加文档数据读取(加载)和存储的代码。需要说明的是,Serialize函数的参数ar是一个CArchive类的引用对象。CArchive类提供了“<<”和“>>”运算符,分别可以向文档对象写入数据或从文档对象中读取数据。它们的含义与C++中的“<<”和“>>”运算符相同,只不过CArchive支持更多的数据类型,如:CObject、CString等。除此之外CArchive类还提供ReadString和WriteString成员函数来读写文档中的一行文本。
文档数据的显示方法和技巧
用户的视图类是负责显示文档数据的,目前常用的显示方法有二个:一是在视图的客户区中使用编辑控件,二是直接调用CDC类的文本输出函数绘制所有的文本内容。
1. 使用编辑控件
“编辑控件”是一个可以让用户从键盘输入和编辑文本的控件,通过它可以输入各种文本、数字或者口令,也可使用它来编辑和修改简单的文本内容。MFC类CEdit封装了编辑控件的全部操作。
使用编辑控件实现文档数据的显示的思路是,先在视图中创建一个与视图客户区大小相同的编辑控件,然后把文档的文本内容转送到编辑控件中。
2. 直接控制文本的输出(详细)
(1)重写OnOpenDocument函数,读取文本文件到字符串变量
BOOL CMFCDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
// TODO: 在此添加您专用的创建代码
if(lpszPathName!=NULL)
{
CFile pCFile;
int hResult=pCFile.Open(lpszPathName, CFile::modeReadWrite); //以读写方式打开文件
if(hResult != 0)
{
// AfxMessageBox("打开文件成功");
}
//将文件读到str字符串
pCFile.Read(str.GetBuffer(pCFile.GetLength()), pCFile.GetLength());
pCFile.Close();
}
return TRUE;
}
(2)ondraw函数中将文件显示出来
CDC为我们提供了四个输出文本的函数:TextOut、ExtTextOut、TabbedTextOut和DrawText,分别用于不同的场合。如果想要绘制的文本需要支持Tab符,那么采用TabbedTextOut函数,可以使绘制出来的文本效果更佳;如果要在一个矩形区域内绘制多行文本,那么采用DrawText函数,会更富于效率;如果文本和图形结合紧密,字符间隔不等,并要求有背景颜色或矩形裁剪特性,那么ExtTextOut函数就将是最好的选择。如果没有什么特殊要求,那使用TextOut函数就显得简练了。
pDC->DrawText(pDoc->str,pDoc->str.GetAllocLength(),CRect(0,0,1000,1000),DT_WORDBREAK);