文章目录
- 小工具 - 浮点计算器
- 概述
- 笔记
- FloatCalcDlg.cpp
- FloatCalcDlg.h
- rc
- END
小工具 - 浮点计算器
概述
在学习CE, 在调试过程中, 经常要看内存中浮点对应的4字节内存到底对应的是啥具体的浮点值. e.g. 0x42860000 => 67.00
转换逻辑挺简单的
float CFloatCalcDlg::uint32_to_float(uint32_t u)
{
return (*(float*)&u);
}
开始写了一个测试程序, 直接改4字节的值, 编译运行一下, 看打印出的结果.
但是要经常看内存中的4字节数据对应的浮点值, 不胜其烦.
花了半天, 写了一个小工具, 方便多了.
笔记
编程环境 : vs2019 mfc dlg
FloatCalcDlg.cpp
// FloatCalcDlg.cpp: 实现文件
//
#include "pch.h"
#include "framework.h"
#include "FloatCalc.h"
#include "FloatCalcDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CFloatCalcDlg 对话框
CFloatCalcDlg::CFloatCalcDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_FLOATCALC_DIALOG, pParent)
, m_cs4ByteIn(_T(""))
, m_cs4ByteOut(_T(""))
, m_csFloatIn(_T(""))
, m_csFloatOut(_T(""))
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CFloatCalcDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT_TIP, m_ctrlTip);
DDX_Text(pDX, IDC_EDIT_4BYTES_IN, m_cs4ByteIn);
DDX_Text(pDX, IDC_EDIT_4BYTES_OUT, m_cs4ByteOut);
DDX_Text(pDX, IDC_EDIT_FLOAT_IN, m_csFloatIn);
DDX_Text(pDX, IDC_EDIT_FLOAT_OUT, m_csFloatOut);
}
BEGIN_MESSAGE_MAP(CFloatCalcDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, &CFloatCalcDlg::OnBnClickedOk)
ON_BN_CLICKED(IDCANCEL, &CFloatCalcDlg::OnBnClickedCancel)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_BUTTON_FLOAT_TO_4BYTES, &CFloatCalcDlg::OnBnClickedButtonFloatTo4bytes)
ON_BN_CLICKED(IDC_BUTTON_4BYTES_TO_FLOAT, &CFloatCalcDlg::OnBnClickedButton4bytesToFloat)
END_MESSAGE_MAP()
// CFloatCalcDlg 消息处理程序
BOOL CFloatCalcDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
this->SetWindowTextW(TEXT("浮点计算器"));
addMsg(TEXT("功能:\r\n"));
addMsg(TEXT("1. 输入浮点数, 转换成4字节\r\n"));
addMsg(TEXT("2. 输入4字节, 转换成浮点数\r\n"));
// for test
this->m_csFloatIn = TEXT("121");
this->m_cs4ByteIn = TEXT("0x42F20000");
this->UpdateData(FALSE);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CFloatCalcDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CFloatCalcDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
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;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CFloatCalcDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CFloatCalcDlg::OnBnClickedOk()
{
CWnd* pWnd = GetFocus();
if (GetDlgItem(IDOK) == pWnd)
{
// 取消默认的回车处理
CDialogEx::OnOK();
return;
}
}
void CFloatCalcDlg::OnBnClickedCancel()
{
CWnd* pWnd = GetFocus();
if (GetDlgItem(IDCANCEL) == pWnd)
{
// 取消摩恩的ESC键处理
CDialogEx::OnCancel();
return;
}
}
void CFloatCalcDlg::OnClose()
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CDialog::OnOK();
CDialogEx::OnClose();
}
void CFloatCalcDlg::addMsg(const TCHAR* pcMsg)
{
do {
if (NULL == pcMsg)
{
break;
}
if (_tcslen(pcMsg) > 0)
{
m_ctrlTip.SetSel(-1, -1, TRUE);
m_ctrlTip.ReplaceSel(pcMsg);
}
else {
// 如果给的文本为空字符串, 就说明要清空消息
m_ctrlTip.SetSel(0, -1, TRUE);
m_ctrlTip.ReplaceSel(TEXT(""));
}
// 加一个回车
m_ctrlTip.SetSel(-1, -1, TRUE);
m_ctrlTip.ReplaceSel(TEXT("\r\n"));
} while (false);
}
void CFloatCalcDlg::OnBnClickedButtonFloatTo4bytes()
{
byte ary[4];
CString cs;
CString csTmp;
this->UpdateData(TRUE);
addMsg(TEXT(""));
addMsg(TEXT("浮点数转4字节"));
float f = (float)_ttof(m_csFloatIn);
uint32_t u = *(uint32_t*)&f;
uint32_to_4byte(u, ary, 4);
cs.Format(TEXT("0x%.2X%.2X%.2X%.2X"), ary[0], ary[1], ary[2], ary[3]);
this->m_cs4ByteOut = cs;
csTmp.Format(TEXT("%.2f to %s\r\n"), f, cs);
addMsg(csTmp);
this->UpdateData(FALSE);
}
void CFloatCalcDlg::uint32_to_4byte(uint32_t u, byte* ary, int aryLen)
{
_ASSERT(NULL != ary);
_ASSERT(aryLen >= 4);
ary[0] = (byte)((u >> (8 * 3)) & 0xff);
ary[1] = (byte)((u >> (8 * 2)) & 0xff);
ary[2] = (byte)((u >> (8 * 1)) & 0xff);
ary[3] = (byte)((u >> (8 * 0)) & 0xff);
}
void CFloatCalcDlg::OnBnClickedButton4bytesToFloat()
{
CString cs;
CString csTmp;
uint32_t u;
this->UpdateData(TRUE);
addMsg(TEXT(""));
addMsg(TEXT("4字节转浮点数"));
cs = this->m_cs4ByteIn;
cs.MakeUpper();
if (cs.GetLength() >= 2)
{
if ((TEXT('0') == cs[0]) && ((TEXT('X') == cs[1])))
{
cs = cs.Right(cs.GetLength() - 2);
}
}
do {
// 12345678
if (cs.GetLength() > 8)
{
addMsg(TEXT("err : 4字节最多8个16进制字符"));
break;
}
if (!IsHexPsz((LPCTSTR)cs))
{
addMsg(TEXT("err : 请输入16进制字符串"));
break;
}
while (cs.GetLength() < 8)
{
cs = _T("0") + cs;
}
Hex8CharToUint32((LPCTSTR)cs, u);
this->m_csFloatOut.Format(TEXT("%.2f"), uint32_to_float(u));
csTmp.Format(TEXT("%s to %s\r\n"), m_cs4ByteIn, this->m_csFloatOut);
addMsg(csTmp);
} while (false);
this->UpdateData(FALSE);
}
float CFloatCalcDlg::uint32_to_float(uint32_t u)
{
return (*(float*)&u);
}
void CFloatCalcDlg::Hex8CharToUint32(const TCHAR* pszHex8, uint32_t& u)
{
unsigned char uc1;
unsigned char uc2;
_ASSERT(NULL != pszHex8);
_ASSERT(8 == _tcslen(pszHex8));
_ASSERT(NULL != pszHex8);
_ASSERT(8 == _tcslen(pszHex8));
uc1 = OneHexChar2UChar(pszHex8[0]);
uc2 = OneHexChar2UChar(pszHex8[1]);
u = uc1;
u <<= 4;
u += uc2;
u <<= 4;
uc1 = OneHexChar2UChar(pszHex8[2]);
uc2 = OneHexChar2UChar(pszHex8[3]);
u += uc1;
u <<= 4;
u += uc2;
u <<= 4;
uc1 = OneHexChar2UChar(pszHex8[4]);
uc2 = OneHexChar2UChar(pszHex8[5]);
u += uc1;
u <<= 4;
u += uc2;
u <<= 4;
uc1 = OneHexChar2UChar(pszHex8[6]);
uc2 = OneHexChar2UChar(pszHex8[7]);
u += uc1;
u <<= 4;
u += uc2;
}
unsigned char CFloatCalcDlg::OneHexChar2UChar(TCHAR c)
{
unsigned char uc = 0;
_ASSERT(((c >= TEXT('0')) && (c <= TEXT('9'))) || ((c >= TEXT('A')) && (c <= TEXT('F'))));
if ((c >= TEXT('0')) && (c <= TEXT('9')))
{
uc = (unsigned char)(c - TEXT('0'));
}
else if ((c >= TEXT('A')) && (c <= TEXT('F')))
{
uc = (unsigned char)(c - TEXT('A') + 10);
}
return uc;
}
bool CFloatCalcDlg::IsHexPsz(const TCHAR* psz)
{
int i = 0;
TCHAR c = 0;
bool b_ok = true;
_ASSERT(NULL != psz);
for (i = 0; i < (int)_tcslen(psz); i++)
{
c = psz[i];
if (((c >= TEXT('0')) && (c <= TEXT('9'))) || (c >= TEXT('A')) && (c <= TEXT('F')))
{
}
else {
b_ok = false;
break;
}
}
return b_ok;
}
FloatCalcDlg.h
// FloatCalcDlg.h: 头文件
//
#pragma once
// CFloatCalcDlg 对话框
class CFloatCalcDlg : public CDialogEx
{
// 构造
public:
CFloatCalcDlg(CWnd* pParent = nullptr); // 标准构造函数
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_FLOATCALC_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedOk();
afx_msg void OnBnClickedCancel();
afx_msg void OnClose();
private:
void addMsg(const TCHAR* pcMsg);
void uint32_to_4byte(uint32_t u, byte* ary, int aryLen);
void Hex8CharToUint32(const TCHAR* pszHex8, uint32_t& u);
bool IsHexPsz(const TCHAR* psz);
unsigned char OneHexChar2UChar(TCHAR c);
float uint32_to_float(uint32_t u);
public:
CEdit m_ctrlTip;
afx_msg void OnBnClickedButtonFloatTo4bytes();
afx_msg void OnBnClickedButton4bytesToFloat();
CString m_cs4ByteIn;
CString m_cs4ByteOut;
CString m_csFloatIn;
CString m_csFloatOut;
};
rc
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/
//
// Generated from the TEXTINCLUDE 2 resource.
//
#ifndef APSTUDIO_INVOKED
#include "targetver.h"
#endif
#include "afxres.h"
#include "verrsrc.h"
/
#undef APSTUDIO_READONLY_SYMBOLS
/
// 中文(简体,中国) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#ifdef APSTUDIO_INVOKED
/
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#ifndef APSTUDIO_INVOKED\r\n"
"#include ""targetver.h""\r\n"
"#endif\r\n"
"#include ""afxres.h""\r\n"
"#include ""verrsrc.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n"
"LANGUAGE 4, 2\r\n"
"#include ""res\\FloatCalc.rc2"" // 非 Microsoft Visual C++ 编辑的资源\r\n"
"#include ""l.CHS\\afxres.rc"" // 标准组件\r\n"
"#if !defined(_AFXDLL)\r\n"
"#include ""l.CHS\\afxribbon.rc"" // MFC 功能区和控制条资源\r\n"
"#endif\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON "res\\FloatCalc.ico"
/
//
// Dialog
//
IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "关于 FloatCalc"
FONT 9, "MS Shell Dlg", 0, 0, 0x1
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,14,14,21,20
LTEXT "FloatCalc,版本 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX
LTEXT "版权所有 (C) 2024",IDC_STATIC,42,26,114,8
DEFPUSHBUTTON "确定",IDOK,113,41,50,14,WS_GROUP
END
IDD_FLOATCALC_DIALOG DIALOGEX 0, 0, 295, 131
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
FONT 9, "MS Shell Dlg", 0, 0, 0x1
BEGIN
CTEXT "转换之前",IDC_STATIC,78,7,65,14,SS_CENTERIMAGE
CTEXT "转换之后",IDC_STATIC,149,7,65,14,SS_CENTERIMAGE
CTEXT "输入为浮点数",IDC_STATIC,7,29,65,14,SS_CENTERIMAGE
EDITTEXT IDC_EDIT_FLOAT_IN,78,29,65,14,ES_AUTOHSCROLL
EDITTEXT IDC_EDIT_4BYTES_OUT,149,29,65,14,ES_AUTOHSCROLL | ES_READONLY
PUSHBUTTON "浮点数转4字节",IDC_BUTTON_FLOAT_TO_4BYTES,222,29,65,14,BS_CENTER | BS_VCENTER
CTEXT "输入为4字节",IDC_STATIC,7,49,65,14,SS_CENTERIMAGE
EDITTEXT IDC_EDIT_4BYTES_IN,78,49,65,14,ES_AUTOHSCROLL
EDITTEXT IDC_EDIT_FLOAT_OUT,149,49,65,14,ES_AUTOHSCROLL | ES_READONLY
PUSHBUTTON "4字节转浮点数",IDC_BUTTON_4BYTES_TO_FLOAT,222,49,65,14,BS_CENTER | BS_VCENTER
EDITTEXT IDC_EDIT_TIP,7,69,281,55,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | ES_WANTRETURN
END
/
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080404B0"
BEGIN
VALUE "CompanyName", "TODO: <公司名>"
VALUE "FileDescription", "FloatCalc"
VALUE "FileVersion", "1.0.0.1"
VALUE "InternalName", "FloatCalc.exe"
VALUE "LegalCopyright", "TODO: (C) <公司名>。 保留所有权利。"
VALUE "OriginalFilename", "FloatCalc.exe"
VALUE "ProductName", "TODO: <产品名>"
VALUE "ProductVersion", "1.0.0.1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x804, 1200
END
END
/
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_ABOUTBOX, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 163
TOPMARGIN, 7
BOTTOMMARGIN, 55
END
IDD_FLOATCALC_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 288
VERTGUIDE, 78
VERTGUIDE, 149
VERTGUIDE, 222
TOPMARGIN, 7
BOTTOMMARGIN, 124
HORZGUIDE, 29
HORZGUIDE, 49
HORZGUIDE, 69
END
END
#endif // APSTUDIO_INVOKED
/
//
// AFX_DIALOG_LAYOUT
//
IDD_FLOATCALC_DIALOG AFX_DIALOG_LAYOUT
BEGIN
0
END
/
//
// String Table
//
STRINGTABLE
BEGIN
IDS_ABOUTBOX "关于 FloatCalc(&A)..."
END
#endif // 中文(简体,中国) resources
/
#ifndef APSTUDIO_INVOKED
/
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE 4, 2
#include "res\FloatCalc.rc2" // 非 Microsoft Visual C++ 编辑的资源
#include "l.CHS\afxres.rc" // 标准组件
#if !defined(_AFXDLL)
#include "l.CHS\afxribbon.rc" // MFC 功能区和控制条资源
#endif
#endif
/
#endif // not APSTUDIO_INVOKED