大家也许都经常进行着如下操作,假如你在某个地方保存了一个文件,您使用某个软件想打开它,通常的做法是点击该软件的File菜单,选择其中的Open,这时系统将会弹出一个对话框提示您所要打开文件的类型及文件路径,您可以改变文件路径,使之选择您所需要的文件的地方;同理,您要保存文件时,也是同样的做法,大家对这种做法可能司空见惯了,可是如果有一天,您要自己写一个程序用来打开与保存文件,这时可能您会有疑惑,文件到底是如何打开的呢?
本人近日也遇到了这种情况,公司了有一个B&R伺服驱动器坏了,检查下来之后发现是其中一块GAL16V8坏了,据了解该PLD内部的程序可以用类似单片机编程的方法进行读写,所以自己准备着手去做一个GAL编程器,要使用以下方面的知识:GAL读写时序图,GAL与上位机通讯软件,GAL编程器图。在做上位机软件时遇到了麻烦,如何编写用户界面,如何读入数据并加以保存?如何打开数据?面对这些问题,在一开始毫无头绪的情况下,首先就是上网查资料,查看别人是如何编程的,然后自己照着做,一句一句地去理解,终于花了两个晚上搞定了读写的使用方法以及注意事项,特此将编写方法列出来,希望对大家有所帮助,当然限于本人能力有限,错误之处恳请大家指出。
好了,言归正传,下面我就介绍一下HEX文件的读写方法:
1.要出现打开文档对话框,则就需要使用CFileDialog对象,先简要的介绍一下CFileDialog的构造函数各个参数的意义:CFileDialog(BOOL bOpenFileDialog, //表示所出现的文档对话框的功能,TRUE表示打开,FALSE表示保 存, LPCTSTR lpszDefExt=NULL,//默认的扩展名,如果没有在文件框中输入扩展名,则自动加上lpszDefExt所示的扩展名,如果此参数为空,则不会再文件名后加扩展名,这个参数主要用于保存文档时,在打开文档过程中使用NULL
LPCTSTR lpszFileName=NULL,//弹出文档对话框时默认的文件,如果为空,则没有默认文件
DWORD dwFlags=OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,//这是个标志组合,用于初始化对话框
LPCTSTR lpszFilter=NULL,//这是一个关键的参数,用于文件过滤,哪些后缀的文件可以显示,完全由这个参数决定
CWnd* pParent=NULL);//指向父类的指针,一般不需使用
好了,CFileDialog的构造函数已经介绍好了,下面将使用它了,语句如下:
CFileDialog fileOpenDialog(TRUE,"","",OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,"Binary Files(*.bin)|*.bin|Hex Files(*.hex)|*.hex||");
2.当对象构造好了之后,将要使用DoModal使其以模态的方式显示,并且要判断用户点击了OK还是CANCEL,语句如下:
if(fileOpenDialog.DoModal()==IDOK)
{ .............................}
3.当完成了上述工作之后,接下来就要利用已经打开的文档获取路径,文件名,扩展名等有效信息:
CString strGetPathName; //保存路径信息
CString strGetOpenFileExtName; //保存文件扩展名信息
CString strGetOpenFileName; //保存文件名信息
strGetPathName=fileOpenDialog.GetPathName();
strGetOpenFileExtName=fileOpenDialog.GetFileExt();
strGetOpenFileName=fileOpenDialog.GetFileName();
strGetOpenFileExtName.MakeUpper();//将扩展名转为大写,主要用于以后比较,普通应用无需进行这样的转换
4.在获得了文件的扩展名及路径之后,就可以使用CFile进行操作了:
CFile fileUse;//将要被使用的文件,先别带参数构造,以便使用Open函数打开,若使用带参数的对象,则如果再使用Open函数时将会出现访问违例报警
if(!fileUse.Open(strGetPathName,//这就是费尽了千辛万苦所获的文档路径
CFile::modeReadWrite|CFile::modeNoTruncate|CFile::shareExclusive,//文档的打开属性
NULL))
{
AfxMessageBox("File Open Error!"); //如果文档不能正常打开则报警以提示用户
}
5.好了,至此文档已经打开了,剩下的就是如何使用了,因为我做的是GAL读写软件,所以我需要对其进行进一步的处理:
if(strGetOpenFileName!="") //我要用文档,当然不能使用空的文档了
{
UINT nFileUseSize; //所打开的文档中的字节个数
nFileUseSize=fileUse.GetLength(); //获取有效字节个数
if(strGetFileExtName=="HEX") //假如打开的HEX文档,对于GAL需要进行转换
{
char* pFileUseBuffer=(char*)GlobalAlloc(GMEM_FIXED,nFileUseSize+1); //分配堆内存,加1表示要给最后一个,也就是NULL分配一个空间
memset(pFileUseBuffer,0,nFileUseSize+1); //初始化堆内存
HexToBin(pFileUseBuffer,pEditHex);//HexToBin是一个自己编写的用于HEX转BIN的函数,pEditHex是一个缓冲区,在本软件初始化时已经分配了堆内存
GlobalFree(pFileUseBuffer);//释放分配的堆内存空间,注意不能使用delete[]
}
else //若是BIN,则正好满足要求,可以直接进行使用
{
fileUse.Read(pEditHex,0x10000);//直接读取内容到缓冲区
}
m_XTHexEdit.SetData(pEditHex,0x10000);//m_XTHexEdit是XTHexEdit编辑控件的对象,而XTHexEdit则是Xtreme Toolkit的一个子控件
fileUse.Close(); //文件用好了之后别忘记关闭了。
}
else //如果打开了空文件则设置相应的警告标志
{
AfxMessageBox("Please Open File!");
}
哦,写到这儿,可以稍微舒了一口气。
6.好了,再接再厉,继续谈如何保存文档的问题,我这里只示范如何把文档保存为BIN格式,其它格式的大家可以在本文的基础上进行修改,保存同打开其实大同小异,部分函数用法上有所区别,先创建一个CFileDialog对象,它的作用依然是弹出对话框:
CFileDialog fileSaveDialog(FALSE, //表示此次是进行保存活动的
"bin",//表示默认后缀为bin文件
NULL,//无初始文件存在
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
"Binary Files(*.bin)|*.bin||");
7.完成构造之后要调用模态显示,同时还需要判断是否点了OK或CANCEL按钮:
if(fileSaveDialog.DoModal()==IDOK) //只有点击OK按钮才表示保存
{
.......................
}
8.现在来具体处理省略号的内容了,主要就是获取文档保存的路径,以便以后使用:
CString strGetSavePath; //文档路径
strGetSavePath=fileSaveDialog.GetPathName(); //获取路径
9.既然已经取得的保存文档的路径了,那么现在就可以利用CFile进行内容的保存工作了:
CFile fileSave; //别带参数,以便使用Open函数打开
if(!fileSave.Open(strGetSavePath,//这就是千辛万苦获得的路径,
CFile::shareCompat|CFile::modeCreate|CFile::modeWrite,
NULL))
{
AfxMessageBox("Save File Error!"); //如果保存有问题,则加以报警指示
}
m_XTHexEdit.GetData(pEditHex,0x10000); //获取XTHexEdit控件中的内容
fileSave.Write(pEditHex,0x10000); //向打开的文档中写入数据,这就实现了数据保存
好了,写了这么久,希望能够对大家有所帮助