第九章 文件操作

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第九章文件操作(编程实例与技巧)

void CS9_1View::OnInitialUpdate()

{ CFormView::OnInitialUpdate();

ResizeParentToFit();

CS9_1Doc *pDoc=GetDocument(); //获取CS9_1Doc指针

m_nYear=pDoc->m_nYear; //获取文档中的年份

m_MonthList.SetCurSel(0); //选择一月

m_nCurrentMonth=0; //当前是一月

m_nMonthProduct=pDoc->m_Moth[0].nProduct; //一月产值

m_sNote=pDoc->m_Moth[0].sNote; //一月备注

m_sRiseRate="第一月无此值"; //一月的增值率

CString str;

str.Format("%d",pDoc->m_nTotalProduct);

m_YearProduct.SetCaption(str); //调用CLabelControl设置标题显示年总产值

UpdateData(FALSE); //更新显示

}

void CS9_1View::OnChangeMonthNote() 输入当月备注发生变化(EN_CHANGE)

{

// TODO: If this is a RICHEDIT control, the control will not send this notification unless you override the CFormView::OnInitDialog() function and call CRichEditCtrl().SetEventMask() with the ENM_CHANGE flag ORed into the mask.

CS9_1Doc *pDoc=GetDocument(); //获取CS9_1Doc指针

UpdateData(); //获取最新输入数据

//和文档中的数据比较是否有变化

if(strcmp(pDoc->m_Moth[m_nCurrentMonth].sNote,m_sNote))

{ //记录下新数据

strcpy(pDoc->m_Month[m_nCurrnentMonth].sNote,m_sNote);

pDoc->SetModifiedFlag(); //设置文档变化标志

}

}

void CS9_1View::OnChangeMonthProduct()

{ CS9_1Doc *pDoc=GetDocument(); //获取CS9_1Doc指针

UpdateData(); //获取最新输入数据

//判断数据是否改变

if(pDoc->m_Moth[m_nCurrentMoth].nProduct!=m_nMonthProduct)

{ //改变总产值

pDoc->m_nTotalProduct+=

m_nMonthProduct-pDoc->m_Moth[m_nCurrentMonth].nProduct;

CString str;

str.Format("%d",pDoc->m_nTotalProduct);

m_YearProduct.SetCaption(str); //调用CLabelControl设置标题函数显示年总产值

//记录当月产值到CS9_1Doc中

pDoc->m_Moth[m_nCurrentMonth].nProduct=m_nMonthProduct;

//计算增长率

if(m_nCurrentMonth==0) //是第一月

m_sRiseRate="第一月无此值";

else if(pDoc->m_Moth[m_nCurrentMonth-1].nProduct==0)//前一月产值0

m_sRieRate="上月无产值";

else

m_sRiseRate.Format("%.2f %%",(pDoc->m_Moth[m_nCurrentMonth].nProduct- pDoc->m_Moth[m_nCurrentMonth-1].nProduct)/

(float)(pDoc->m_Moth[m_nCurrentMonth-1].nProduct)*100);

pDoc->SetModifiedFlag(); //设置文档更改标志

UpdateData(FALSE); // 更新显示

}

}

void CS9_1View::OnChangeYear()

{ CS9_1Doc *pDoc=GetDocument(); //获取CS9_1Doc指针

UpdateData(); //获取最新输入

if(pDoc->m_nYear!=m_nYear) //判断数据是否变化

{ pDoc->m_nYear=m_nYear; //记录当月产值到CS9_1Doc中

pDoc->SetModifiedFlag(); //设置文档更改标志

}

}

void CS9_1View::OnDeltaposSpinYear(NMHDR* pNMHDR, LRESULT* pResult)

{ NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;

//用spin控件更改年份

UpdateData(); //调用它使m_nYear中是最新值

if(pNMUpDown->iDelta>0)&&(m_nYear>0) //减小年份,并且不能小于0

m_nYear--;

else if(pNMUpDown->iDelta<0) //增加年份

m_nYear++;

else //非法输入

{ AfxMessageBox("年份必须是非负整数");

*pResult=0;

return;

}

GetDocument()->m_nYear=m_nYear; //文档记录下新年份

GetDocument()->SetModifiedFlag(); //设置文档更改标志

UpdateData(FALSE);

*pResult = 0;

}

void CS9_1View::OnSelchangeMonth()

{ CS9_1Doc *pDoc=GetDocument(); //获取CS9_1Doc指针

//因每个数据改动,自己都响应了变动的消息,所以不用做保存数据的工作

//获得当前选择的月份并设置正确的显示

m_nCurrentMonth=m_MonthList.GetCurSel();

//计算这个月增长率

if(m_nCurrentMonth==0) //是第一月

m_sRiseRate="第一月无此值";

else if(pDoc->m_Moth[m_nCurrentMonth-1].nProduct==0) //前一月产值0 m_sRiseRate="上月无产值";

else //计算增长率

m_sRiseRate.Format("%.2f%%",(pDoc->m_Moth[m_nCurrentMonth].nProduct- pDoc->m_Moth[m_nCrrentMonth-1].nProduct)/

(float)(pDoc->m_Moth[m_nCurrentMonth-1].nProduct)*100);

m_nMonthProduct=pDoc->m_Moth[m_nCurrentMonth].nProduct; //获得当月产值和备注m_sNote=pDoc->m_Moth[m_nCurrentMonth].sNote;

UpdateData(FALSE);

}

void CS9_1Doc::Serialize(CArchive& ar)

{ if (ar.IsStoring())

{ //实现存储写的代码

ar<

ar<

for(int i=0;i<12;i++) //循环写入各月信息

{ ar<

ar.Write(m_Month[i].sNote,50); //这个月备注

}

}

else

{ //实现恢复读出的代码

ar>>m_nYear; //读出年份

ar>>m_nTotalProduct; //读出总产值

int nTemp=0;

for(int i=0;i<12;i++) //读出各月信息

{ ar>>m_Month[i].nProduct; //这个月的产值

if(m_Month[i].nProduct<0) //纠正负值

m_Month[i].nProduct=-m_Month[i].nProduct;

nTemp+=m_Month[i].nProduct; //临时统计各月累计总产值

ar.Read(m_Month[i].sNote,50); //读出这个月的备注信息

m_Month[i].sNote[49]=NULL; //确保字符串结束存在!

}

//进行检查工作

if(nTemp!=m_nTotalProduct) //各月累计和总产值不符

{ //提示

AfxMessageBox("该报表文件中总产值与各月总和不符,

\\n将总产值置为各月总和!");

m_nTotalProduct=nTemp; //将总产值置为各月总和

}

}

}

void CS9_1Doc::OnCreateText()

{

CString str;

CString filename=GetPathName(); //获取该文档当前的yrp文件名

if(filename.IsEmpty()) //如果空(新建的文件未存之前的情况)

filename=GetTitle()+".trp"; //从标题获得

else //改扩展名

filename=filename.Left(filename.GetLength()-3)+"trp";

CStdioFile file;

//用CStdioFile创建一个trp文件,注意使用的文件操作标志

if(file.Open(filename,CFile::modeCreate|CFile::modeWrite|CFile::typeText==0))

{ str="创建文件"+filename+"失败!";

AfxMessageBox(str); // 创建失败,报告并返回

return;

}

//实现起来很简单,这就开始写这些文本内容了!

str.Format ("%d年产值报告\n\n",m_nYear); //年份

file.WriteString(str); //用WriteString写入

str.Format("总产值:%d元\n\n",m_nTotalProduct);

file.WriteString(str); //写总产值文字信息

str.Format("月份: 产值: 单位(元) 备注: \n");

file.WriteString(str); //写各月报表头

for(int i=0;i<12;i++)

{ //写月产值和备注

str.Format ("%4d%13d %s\n", i+1,m_Month[i].nProduct,m_Month[i].sNote );

file.WriteString(str);

}

/*好了,文件这就写完了,再作一些辅助工作. 设置文件结尾,因为新创建文件写完后大小就是自己写的内容的大小,所以这条语句不是必须的,只是为演示函数的用法*/

file.SetLength(file.GetPosition());

file.Close(); //关闭文件

str="notepad"+filename;

WinExec(str,SW_SHOW);

}

void CMainFrame::OnFromText()

{ //选择文本报表文件

CFileDialog dlg(TRUE,"trp",NULL,

OFN_HIDEREADONL Y|OFN_OVERWRITEPROMPT,

"文本报表文件(*.trp)|*.trp|所有文件(*,*)|*.*||",this);

if(dlg.DoModal()==IDCANCEL)

return;

CString filename=dlg.GetPathName(); //获取选择的文本报表文件名CString str , strTemp;

CFile file;

//用CFile打开文本报表文件,注意打开的文件方式;

if(file.Open(filename,CFile::modeRead)==0)

{ str="打开文件"+filename+"失败!";

AfxMessageBox(str); //打开失败,报告并返回

return;

}

//创建CArchive对象,创建方式和文件打开方式要一致

CArchive ar(&file,CArchive::load);

//定义yrp文件内容结构(和CS9_1Doc::Serialize的读写顺序一样

struct YRP_STRUCT{

int nYear; //年份

int nTotalProduct; //年总产值

struct{

int nProduct; //月产值

char sNote[50]; //月备注

}Month[12]; //各个月信息

}*pYrpMap; //定义使用报表文件映射的指针

//定义句柄

HANDLE hNewFile=INV ALID_HANDLE_V ALUE;

HANDLE hMap=NULL;

//获取yrp文件名,这里就使用的是同名的

filename=filename.Left(filename.GetLength()-3)+"yrp";

try

{ //创建文件句柄,注意创建方式

hNewFile=CreateFile(filename,GENERIC_WRITE|GENERIC_READ, 0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL);

if(hNewFile==INV ALID_HANDLE_V ALUE)

throw"创建报表文件失败!";

//创建内存映射文件句柄,注意和文件的创建方式相一致

hMap=CreateFileMapping(hNewFile,NULL,PAGE_READWRITE,0,

sizeof(YRP_STRUCT),"yrp file");

if(hMap==NULL)

throw "创建内存映射文件失败!";

//将文件视图映射到内存中,获得指针

pYrpMap=(YRP_STRUCT*)MapViewOfFile(hMap,FILE_MAP_WRITE, 0,0,sizeof(YRP_STRUCT));

if(pYrpMap==NULL)

throw "文件视图映射时失败!";

}

catch(char *str)

{AfxMessageBox(str); //错误报告,并返回

if(hMap!=NULL)

CloseHandle(hMap);

if(hNewFile!=INV ALID_HANDLE_V ALUE)

CloseHandle(hNewFile);

return;

}

//创建工作成功,开始读数据

ar.ReadString(str);

sscanf(str,"%d%s",&(pYrpMap->nYear),(LPCTSTR)strTemp); //年份ar.ReadString(str);

ar.ReadString(str);

sscanf(str,"%s%d%s",(LPCTSTR)strTemp,

&(pYrpMap->nTotalProduct),(LPCTSTR)strTemp); //总产值ar.ReadString(str);

ar.ReadString(str);

for(int i=0;i<12;i++) //各个月的信息

{ int nTemp;

ar.ReadString(str);

sscanf(str,"%d%d%s",&nTemp,&(pYrpMap->Month[i].nProduct), pYrpMap->Month[i].sNote); //没有判断月份的合法性}

UnmapViewOfFile(pYrpMap); //解除映射

CloseHandle(hMap); //关闭映射句柄

CloseHandle(hNewFile); //关闭写的文件句柄

ar.Close(); //关闭CArchive

file.Close(); //关闭读的文件

//在程序中打开从文本报表中引入的报表文件

if(AfxGetApp()->OpenDocumentFile(filename)==NULL)

AfxMessageBox("打开与文本报表同名的报表文件失败!");

}

相关文档
最新文档