单文档程序 文档保存的问题:文档莫名其妙被清空了。

善良超锅锅 2014-05-26 03:55:05
写了一个矢量图形绘制程序。基于SDI。我需要保存数据,而且要保存为特定的格式。不想用mfc本身提供的序列化。

为了自定义文件的格式。我重载了文档类的OnOpenDocument函数和OnSaveDocument(LPCTSTR lpszPathName)函数。代码如下

BOOL CToyDrawDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;

// TODO: 在此添加您专用的创建代码
m_GraphList.Load(Unicode2ANSI(lpszPathName));
return TRUE;
}


BOOL CToyDrawDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
// TODO: 在此添加专用代码和/或调用基类
m_GraphList.Save(Unicode2ANSI(lpszPathName));

return CDocument::OnSaveDocument(lpszPathName);
}

在OnSaveDocument函数中根据传入的文件名创建文件,写入格式化数据,关闭文件。再调用基类的OnSaveDocument函数。
在OnOpenDocument函数中根据传入的文件名打开文件,载入数据,然后调用基类的OnOpenDocument函数。


下面是我测试的:3个用例,其中用例3出现了问题:
用例1:打开软件-->在默认创建视图中绘图,写入数据--.>保存文件。(会弹出文件对话框)
结果:文件是正确的,我用浏览器和notepad++打开看,很完美。

用例2:打开软件-->绘图--->保存文件-->接着绘图---->再按ctrl+S保存文件。
结果:文件还是正确的,后面绘制的数据也看到了。第一次保存会弹出一个文件对话框。后面就没有了。

用例3:打开软件-->打开前面保存的文件-->文件中的数据正常显示在视图上--->在这个基础上绘图、或修改。-->ctrl+s保存文件。
结果:打开文件,发现文件被清空了。大小为0KB,里面任何数据都没有。这是为什么呢?

上面3个用例都用到了保存文件的功能,为什么3的文件不能正常保存呢?我调试时发现它们都会执行OnSaveDocument函数。难道它们的执行逻辑不同吗?
要自定义文件格式,正确的步骤不是这样的吗?
...全文
150 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
u010540481 2014-08-10
  • 打赏
  • 举报
回复
楼主问题怎么解决的? 我也遇到文件被清空的问题。
善良超锅锅 2014-05-27
  • 打赏
  • 举报
回复
引用 6 楼 cvbtvbwu 的回复:
我也做过类似的东西。在单文档里保存数据,读取数据。我的方法是:在界面上给两个按钮,一个打开按钮,一个保存按钮,点击打开按钮的时候,打开文件对话框选择文件路径,然后自己
	CFile mFile; 

	if (mFile.Open(szPath, CFile::modeRead))
	{
		CArchive arch(&mFile,CArchive::load);

		//////////////////////////////////////////////////
		int nDataVersion;
		arch>>nDataVersion;

		......

		//////////////////////////////////////////////////
		arch.Close();

		mFile.Close();

		return TRUE;
	}
	else
	{
		return FALSE;
	}
这样去读取文件,然后调用视图去更新界面,视图就会用新的数据去绘图界面。点击打开按钮的时候,打开文件对话框选择文件保存路径,然后自己

CFile mFile; 

	if (mFile.Open(szPath, CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite))
	{
		CArchive arch(&mFile,CArchive::store);

		//////////////////////////////////////////////////

		arch<<DEF_DATA_VERSION;

		......

		//////////////////////////////////////////////////
		arch.Close();

		mFile.Close();

		return TRUE;
	}
	else
	{
		return FALSE;
	}
,去保存数据文件,这过程,没有涉及到什么重载了文档类的OnOpenDocument函数和OnSaveDocument(LPCTSTR lpszPathName)函数,我也不知道它们有什么用,反正我一直就这样过来的,也一直能完成这事情
这样好蹩脚。我这个是毕设,不能让老师看扁了。我想表现的自然些。我的问题解决了。你可以根据我的问题和这里的几个答案学习一下,用框架自带保存打开接口挺好的。
躺着睡的蜗牛 2014-05-26
  • 打赏
  • 举报
回复
改成下面的试试

BOOL CToyDrawDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
    // TODO: 在此添加专用代码和/或调用基类
    m_GraphList.Save(Unicode2ANSI(lpszPathName));
     
    return TRUE;
}
caewow 2014-05-26
  • 打赏
  • 举报
回复
对的,你这样直接自己写好了,没必要再去调用基类的函数了
叶恭介叶恭介 2014-05-26
  • 打赏
  • 举报
回复
我也做过类似的东西。在单文档里保存数据,读取数据。我的方法是:在界面上给两个按钮,一个打开按钮,一个保存按钮,点击打开按钮的时候,打开文件对话框选择文件路径,然后自己
	CFile mFile; 

	if (mFile.Open(szPath, CFile::modeRead))
	{
		CArchive arch(&mFile,CArchive::load);

		//////////////////////////////////////////////////
		int nDataVersion;
		arch>>nDataVersion;

		......

		//////////////////////////////////////////////////
		arch.Close();

		mFile.Close();

		return TRUE;
	}
	else
	{
		return FALSE;
	}
这样去读取文件,然后调用视图去更新界面,视图就会用新的数据去绘图界面。点击打开按钮的时候,打开文件对话框选择文件保存路径,然后自己

CFile mFile; 

	if (mFile.Open(szPath, CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite))
	{
		CArchive arch(&mFile,CArchive::store);

		//////////////////////////////////////////////////

		arch<<DEF_DATA_VERSION;

		......

		//////////////////////////////////////////////////
		arch.Close();

		mFile.Close();

		return TRUE;
	}
	else
	{
		return FALSE;
	}
,去保存数据文件,这过程,没有涉及到什么重载了文档类的OnOpenDocument函数和OnSaveDocument(LPCTSTR lpszPathName)函数,我也不知道它们有什么用,反正我一直就这样过来的,也一直能完成这事情
lis2012 2014-05-26
  • 打赏
  • 举报
回复
引用 楼主 shimachao 的回复:
写了一个矢量图形绘制程序。基于SDI。我需要保存数据,而且要保存为特定的格式。不想用mfc本身提供的序列化。 为了自定义文件的格式。我重载了文档类的OnOpenDocument函数和OnSaveDocument(LPCTSTR lpszPathName)函数。代码如下
BOOL CToyDrawDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
	if (!CDocument::OnOpenDocument(lpszPathName))
		return FALSE;

	// TODO:  在此添加您专用的创建代码
	m_GraphList.Load(Unicode2ANSI(lpszPathName));
	return TRUE;
}


BOOL CToyDrawDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
	// TODO: 在此添加专用代码和/或调用基类
	m_GraphList.Save(Unicode2ANSI(lpszPathName));
	
	return CDocument::OnSaveDocument(lpszPathName);
}
在OnSaveDocument函数中根据传入的文件名创建文件,写入格式化数据,关闭文件。再调用基类的OnSaveDocument函数。 在OnOpenDocument函数中根据传入的文件名打开文件,载入数据,然后调用基类的OnOpenDocument函数。 下面是我测试的:3个用例,其中用例3出现了问题: 用例1:打开软件-->在默认创建视图中绘图,写入数据--.>保存文件。(会弹出文件对话框) 结果:文件是正确的,我用浏览器和notepad++打开看,很完美。 用例2:打开软件-->绘图--->保存文件-->接着绘图---->再按ctrl+S保存文件。 结果:文件还是正确的,后面绘制的数据也看到了。第一次保存会弹出一个文件对话框。后面就没有了。 用例3:打开软件-->打开前面保存的文件-->文件中的数据正常显示在视图上--->在这个基础上绘图、或修改。-->ctrl+s保存文件。 结果:打开文件,发现文件被清空了。大小为0KB,里面任何数据都没有。这是为什么呢? 上面3个用例都用到了保存文件的功能,为什么3的文件不能正常保存呢?我调试时发现它们都会执行OnSaveDocument函数。难道它们的执行逻辑不同吗? 要自定义文件格式,正确的步骤不是这样的吗?
可以看出 3中m_GraphList里面的数据不正确或者为空,导致了后边数据没能存入
善良超锅锅 2014-05-26
  • 打赏
  • 举报
回复
引用 3 楼 schlafenhamster 的回复:
“很多都要调用基类的函数” 是, 那是因为 基类 还有事 要干, 你 都 干 完了 , 就 不必 调 基类了。
果然是这样。可是上次我删掉后出了问题。可能是其他地方的问题吧。我好二。
schlafenhamster 2014-05-26
  • 打赏
  • 举报
回复
“很多都要调用基类的函数” 是, 那是因为 基类 还有事 要干, 你 都 干 完了 , 就 不必 调 基类了。
善良超锅锅 2014-05-26
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
都自己 读写了, 为什么 要调用 基类 函数 ?
之前我把基类的函数调用删除了。发现不调用的话,有些功能用不了。有异常。我再看看去行不行。 MFC里重载函数,不是很多都要调用基类的函数吗?
schlafenhamster 2014-05-26
  • 打赏
  • 举报
回复
都自己 读写了, 为什么 要调用 基类 函数 ?

16,547

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧