|
对于编程器软件来说支持hex,bin文件的加载是必须的,也是必不可少的。具体怎么解码hex文件请参考hex文件格式说明之类的资料,这里不做详细解说,我们采用现成的hex文件读写模块。bin文件就简单多了,直接以二进制读取到内存即可。
通过调用系统默认的打开文件对话框实现:
手动配置好过滤条件hex和bin。实现代码如下:
- void CUUProgDlg::OnFileOpen()
- {
- // TODO: Add your command handler code here
- CFile ldfile;
- CString m_sFileExt;
-
- SetAppLog("加载文件开始...");
- CFileDialog mDlg(TRUE,".HEX",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"HEX文件(*.HEX)|*.HEX|BIN文件(*.bin)|*.bin||",this);
- if(mDlg.DoModal() == IDOK)
- {
- m_sFilename = mDlg.GetPathName();
- m_sFileExt = mDlg.GetFileExt();
- m_sFileExt.MakeUpper();
- //加载文件
- if(!m_sFilename.IsEmpty())
- {
- SetAppLog("加载文件:"+m_sFilename);
- if(ldfile.Open(m_sFilename,CFile::shareCompat|CFile::modeRead,NULL))
- {
- int nFileSize;
- nFileSize=ldfile.GetLength();
- if(m_sFileExt=="HEX")
- {
- char* pFileBuf=(char*)GlobalAlloc(GMEM_FIXED,nFileSize+1);
- memset(pFileBuf,0,nFileSize+1);
- ldfile.Read(pFileBuf,nFileSize);
- nFileSize = HexToBin(pFileBuf,pProgBuff);
- GlobalFree(pFileBuf);
- }
- else
- {
- if(nFileSize>0x10000) nFileSize=0x10000;
- memset(pProgBuff,0xff,0x10000);
- ldfile.Read(pProgBuff,nFileSize);
- }
- ldfile.Close();
- SetLoadFileName(m_sFilename);
- SetAppLog("加载完成:"+Int2Str(nFileSize)+"字节");
- }
- else
- {
- SetAppLog("加载文件失败");
- AfxMessageBox("加载指定的文件出错");
- }
- }
- }
-
- else
- {
- SetAppLog("取消加载文件");
- }
- }
复制代码 首先通过定一个字符型指针变量,然后在内存中开辟块文件大小+1的区块,再用hextobin函数转换成字节型数据流。为什么要先把文件加载到内存在转换呢?自己想一下就明白了。
下面就是hextobin(),有两个参数,前面是char*,后面是byte*
- int HexToBin(char* pHex,BYTE* pBin)//pBin指向的缓存必须不小于64k
- { //pHex指向的缓存必须以0结尾
- CString strHex;
- CArray<BYTE,BYTE>* pByteArray=NULL;
- CArray<CArray<BYTE,BYTE>*,CArray<BYTE,BYTE>*> arByteRec;
- strHex=pHex;
- int nEnd;
- BYTE byteTmp;
- int n=0,m=0;
- nEnd=strHex.Find(":00000001");
- if(nEnd<0)//先判断文件结尾处
- {
- AfxMessageBox("*.Hex文件转换失败(未找到\":00000001\"记录)!");
- return -1;
- }
-
- while(n<nEnd)//先把所有字符转换成字节
- {
- if(pHex[n]==':')//发现':'就新增一条记录
- {
- pByteArray=new CArray<BYTE,BYTE>;
- arByteRec.Add(pByteArray);//增加一条记录
- n++;
- }
- else if(pHex[n]==0x0d)//检查是不是换行
- {
- n++;
- }
- else if(pHex[n]==0x0a)
- {
- n++;
- }
- else//字符转换成字节
- {
- if(CharToByte(&pHex[n],&byteTmp))
- {
- if(pByteArray==NULL)
- return -1;
- pByteArray->Add(byteTmp);//增加一个字节
- n++;
- n++;
- }
- else
- {
- AfxMessageBox("*.Hex文件转换失败(错误的字符)!");
- return -1;
- }
- }
- }
- int nRec=arByteRec.GetSize();
- int nAddr=0;//buf中的偏移地址
- BYTE* pBuf;
- int nLength=0;//数据块长度
- int nByte=0;
- memset(pBin,0xff,0xffff);//先把每个单元置成FFH
- for(n=0;n<nRec;n++)//分析每条记录
- {
- pByteArray=arByteRec.GetAt(n);
- if(pByteArray->GetSize()<5)
- {
- AfxMessageBox("*.Hex文件转换失败(错误的记录)!");
- return -1;
- }
- if(pByteArray->GetAt(3)==0)//判断是不是数据记录
- {
- nByte=(int)pByteArray->GetAt(0);
- if(nByte>(pByteArray->GetSize()-4))//记录中数据长度不符合
- {
- AfxMessageBox("*.Hex文件转换失败(错误的记录)!");
- return -1;
- }
- ((BYTE*)&nAddr)[0]=pByteArray->GetAt(2);//装入地址
- ((BYTE*)&nAddr)[1]=pByteArray->GetAt(1);
-
- pBuf=&pBin[nAddr];
- for(m=0;m<nByte;m++)//把数据都拷贝到pBin
- {
- pBuf[m]=pByteArray->GetAt(4+m);
- nLength++;
- }
- }
- else if(pByteArray->GetAt(3)==2)
- {
- AfxMessageBox("*.Hex文件转换失败(不支持大于64k)!");
- return -1;
- }
- else if(pByteArray->GetAt(3)==4)
- {
- AfxMessageBox("*.Hex文件转换失败(不支持大于64k)!");
- return -1;
- }
- else
- {
- AfxMessageBox("*.Hex文件转换失败(错误的记录)!");
- return -1;
- }
-
- }
- return nLength;
- }
复制代码 这里采用的是全局型函数,方便其他窗口调用
文件保存就是打开的逆过程,下面就是保存部分:
- void CUUProgDlg::OnFileSaveAs()
- {
- // TODO: Add your command handler code here
- CString filename;
- CFile savefile;
- CString m_sFileExt;
- int filesize;
- SetAppLog("保存开始...");
- filesize = GetMinLength(pProgBuff,m_dDeviceSize);
- if (filesize ==0)
- {
- SetAppLog("缓冲区无数据,取消保存");
- AfxMessageBox("缓冲区无数据,不需保存");
- return;
- }
- CFileDialog mDlg(FALSE,".HEX",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"HEX文件(*.hex)|*.hex|BIN文件(*.bin)|*.bin||",this);
- if(mDlg.DoModal() == IDOK)
- {
- filename = mDlg.GetPathName();
- m_sFileExt = mDlg.GetFileExt();
- m_sFileExt.MakeUpper();
- SetAppLog("保存为:"+filename);
- //保存文件代码
- if (m_sFileExt=="HEX")
- {
- }
- else
- {
- if(savefile.Open(filename,CFile::shareCompat|CFile::modeCreate|CFile::modeWrite,NULL))
- {
- //m_editBuf2.GetData(m_Pro.m_pReadBuf,0x10000);
- savefile.Write(pProgBuff,filesize);
- savefile.Close();
- }
- }
- SetAppLog("保存完成:"+Int2Str(filesize)+"字节");
- }
- else
- {
- SetAppLog("取消保存");
- }
-
- }
复制代码 我们这里只实现了bin文件的保存,hex处理部分没有代码,暂时无法实现。
实现hex,bin的识别主要通过文件后缀名实现的,通过if语句实现不同的处理。
|
|