⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elfs2bindlg.cpp

📁 16进制Motorola S-records 文件说明 及转换为Bin/Binary S3格式程序
💻 CPP
字号:
// Elfs2BinDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Elfs2Bin.h"
#include "Elfs2BinDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CElfs2BinDlg dialog

CElfs2BinDlg::CElfs2BinDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CElfs2BinDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CElfs2BinDlg)
	m_Filename = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CElfs2BinDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CElfs2BinDlg)
	DDX_Text(pDX, IDC_EDIT_FILE_NAME, m_Filename);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CElfs2BinDlg, CDialog)
	//{{AFX_MSG_MAP(CElfs2BinDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_FILE_SELECT, OnButtonFileSelect)
	ON_BN_CLICKED(ID_START, OnStart)
	ON_EN_CHANGE(IDC_EDIT_FILE_NAME, OnChangeEditFileName)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CElfs2BinDlg message handlers

BOOL CElfs2BinDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CElfs2BinDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CElfs2BinDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CElfs2BinDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CElfs2BinDlg::OnButtonFileSelect() 
{
	// TODO: Add your control notification handler code here
    UpdateData(TRUE);
	CFileDialog dlg	(TRUE,   // Save
		NULL,    // No default extension
		NULL,    // No initial file name
		OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY,
		"S-RECORD Files (*.S)|*.S||");
    if (dlg.DoModal() == IDOK)
	{
		m_Filename = dlg.GetPathName();
		UpdateData(FALSE);
		OnChangeEditFileName() ;
    }
}

// 字母转换为HEX, c应在'0'-'9'或'A'-'F'之间
unsigned char ctoh(unsigned char c)
{
	return c>'9'?(c-'A'+10):(c-'0');
}

// 检查c是否为十六进制字符
BOOL isch(TCHAR c)
{
	return  ((('0' <= c)  && (c <='9'))
		|| (('A' <=c)  && (c <='F')))?	TRUE:FALSE;
}

void CElfs2BinDlg::OnStart() 
{
	// TODO: Add your control notification handler code here
	CString szFBin;
	CStdioFile fSrecord, fBin;
	CFileException fe;
	CString szMsg;
	TCHAR   szCause[255];

	if (!fSrecord.Open(m_Filename, CFile::modeRead|CFile::typeText|CFile::shareDenyWrite, &fe)) 
	{
		GetDlgItem(ID_START)->EnableWindow(FALSE);
		fe.GetErrorMessage(szCause, 255);
		szMsg = "未能正确打开指定的S-RECORD文件! \n原因是:\n";
		szMsg += szCause;
		AfxMessageBox(szMsg);
		return ;
	}

	szFBin = m_Filename + ".Bin";
	if (!fBin.Open(szFBin, CFile::modeCreate|CFile::modeWrite|CFile::typeBinary, &fe))
	{
		fe.GetErrorMessage(szCause, 255);
		szMsg = "创建BIN文件时发生错误! \n原因是:\n";
		szMsg += szCause;
		AfxMessageBox(szMsg);
		return ;
	}

	CString stag;
	// 记录所在行数
	int iLine =0;
	// 记录长度
	int rlen;
	// 记录偏移量
	int offset;
	// 转换后的字节数
	int iBytes =0;
	// 地址
	int addr, newAddr;
	//地址有效
	char cha =0;
	unsigned char err =0;
	unsigned char binTemp[256];
	CString szLine;
	CWaitCursor wcsr;
	while(fSrecord.ReadString(szLine))
	{
		iLine++;
		rlen = szLine.GetLength();
		if (!rlen)	continue;
		if((rlen < 10)		// 记录长度不符
			|| (rlen & 1))	// 奇数字节
		{
			err=1;
			szMsg.Format ("第%d行 的记录长度有误!", iLine);
			break ;
		}

		stag = szLine.Left (2);
		if(("S0" != stag)
			&& ("S3" != stag)
			&& ("S7" != stag))
		{
			err=2;
			szMsg.Format ("第%d行 不能识别的记录类型!", iLine);
			break ;
		}

		szLine.MakeUpper();
		int ipos;
		for (ipos =2; ipos <rlen; ipos++)
		{
			if (FALSE == isch(szLine.GetAt(ipos)))
				{	err = 5;	break;	}
		}
		if (5 == err)
		{
			szMsg.Format ("第%d行 中的第%d个字符不是十六进制字符!", iLine, ++ipos);
			break ;
		}

		offset = 2;
		while(offset < rlen)
		{
			binTemp[offset/2] = (ctoh(szLine.GetAt(offset)) <<4) + ctoh(szLine.GetAt(offset+1));
			offset +=2;
		}
		binTemp[0] = 0;
		for (int i=1; i <=binTemp[1]+1; i++)
			binTemp[0] += binTemp[i];
		if (0xff != binTemp[0])
		{
			err=3;
			szMsg.Format ("第%d行 记录校验有误!", iLine);
			break ;
		}

		if("S0" == stag)
			continue;

		if("S3" == stag)
		{
			addr = binTemp[2] *0x1000000 + binTemp[3] * 0x10000
				+ binTemp[4] *0x100 + binTemp[5];
			if (cha)
			{
				if (newAddr != addr)
				{
					err=4;
					szMsg.Format("第%d行 与上一行的地址不连续!",iLine);
					break ;
				}
			}
			newAddr = addr +binTemp[1]-5;
			cha = 1;
			iBytes += (binTemp[1]-5);
			fBin.Write(binTemp+6, binTemp[1]-5);
		}
	}

	fSrecord.Close();
	fBin.Close();
	if (err)
		GetDlgItem(ID_START)->EnableWindow(FALSE);
	else
		szMsg.Format ("转换完成,共%d(0x%x)字节!", iBytes, iBytes);

	AfxMessageBox(szMsg);
}

void CElfs2BinDlg::OnChangeEditFileName() 
{
	// TODO: If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.
	
	// TODO: Add your control notification handler code here
	UpdateData();
	GetDlgItem(ID_START)->EnableWindow(m_Filename.GetLength()?TRUE:FALSE);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -