|  | 
 
| 对于编程器软件来说支持hex,bin文件的加载是必须的,也是必不可少的。具体怎么解码hex文件请参考hex文件格式说明之类的资料,这里不做详细解说,我们采用现成的hex文件读写模块。bin文件就简单多了,直接以二进制读取到内存即可。 通过调用系统默认的打开文件对话框实现:
 
   手动配置好过滤条件hex和bin。实现代码如下:
 
 首先通过定一个字符型指针变量,然后在内存中开辟块文件大小+1的区块,再用hextobin函数转换成字节型数据流。为什么要先把文件加载到内存在转换呢?自己想一下就明白了。复制代码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("取消加载文件");
        }
}
下面就是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;        
}
文件保存就是打开的逆过程,下面就是保存部分:
 
 我们这里只实现了bin文件的保存,hex处理部分没有代码,暂时无法实现。复制代码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("取消保存");
        }
        
}
实现hex,bin的识别主要通过文件后缀名实现的,通过if语句实现不同的处理。
 
 
 | 
 |