我刚刚安装了Visual Studio 2017社区版。我使用应用程序向导创建了一个MFC项目,采用了所有默认值。然后我在about对话框中添加了两个编辑框。然后我将两个double类型的变量映射到这两个编辑框。然后我为OK按钮添加了一个处理程序。以下是相关代码:
class CAboutDlg : public CDialogEx
{
double m_f;
afx_msg void OnBnClickedOk();
double m_f2;
};
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_f);
DDX_Text(pDX, IDC_EDIT2, m_f2);
}
void CAboutDlg::OnBnClickedOk()
{
if (!UpdateData(TRUE))
{
return;
}
CString s;
s.Format(_T("m_f = %g"), m_f);
AfxMessageBox(s);
s.Format(_T("m_f2 = %g"), m_f2);
AfxMessageBox(s);
CDialogEx::OnOK();
}
我注意到在发布模式下,如果我在第一个编辑框中输入0.56,在第二个编辑框中输入0并单击确定按钮。 m_f和m_f2值显示为0.56和56(而不是0)。有人注意到这个bug吗?我无法相信存在这样的错误。
我还参与了项目常规设置,例如Windows SDK版本,Platform Toolset,MFC(静态或共享库)和字符集(Unicode或nonUnicode)的使用。我正确显示值的唯一设置是使用Windows SDK版本= 10.0.15063.0,平台工具集= Visual Studio 2017 v141,使用MFC静态库。
答案 0 :(得分:1)
我遇到了与this issue
相关的MFC类似问题为了避免这个问题,我重新实现了DDX_Text
函数调用它DDX_Text2
并使用此函数而不是DDX_Text
来实现双精度和浮点数。
从MFC来源复制AfxTextFloatFormat
的代码,唯一的区别是在调用szBuffer
之前GetWindowText
已填零。
//
// Reimpelementation of AfxTextFloatFormat because of buggy _sntscanf_s function
//
// See:
// - https://social.msdn.microsoft.com/Forums/vstudio/en-US/4a04b861-8b16-4bb3-8a0d-f4e78b1c2a5a/sntscanfs-doesnt-work-as-expected-in-vs2015?forum=vcgeneral
// - https://connect.microsoft.com/VisualStudio/feedback/details/1773279/bug-in-sntscanf-s
// - https://connect.microsoft.com/VisualStudio/feedback/details/1642606/mfc-cdialog-dodataexchange-cdataexchange-pdx-fails-when-value-is-zero
#include "stdafx.h"
#include "TextFloatFormatPatch.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// Copied from MFC source code
static void AFXAPI AfxTextFloatFormat(CDataExchange* pDX, int nIDC,
void* pData, double value, int nSizeGcvt)
{
ASSERT(pData != NULL);
pDX->PrepareEditCtrl(nIDC);
HWND hWndCtrl;
pDX->m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);
const int TEXT_BUFFER_SIZE = 400;
TCHAR szBuffer[TEXT_BUFFER_SIZE] = { 0 }; // added: initlialize whole buffer with 0
if (pDX->m_bSaveAndValidate)
{
::GetWindowText(hWndCtrl, szBuffer, _countof(szBuffer));
double d;
if (_sntscanf_s(szBuffer, _countof(szBuffer), _T("%lf"), &d) != 1)
{
AfxMessageBox(AFX_IDP_PARSE_REAL);
pDX->Fail(); // throws exception
}
if (nSizeGcvt == FLT_DIG)
*((float*)pData) = (float)d;
else
*((double*)pData) = d;
}
else
{
ATL_CRT_ERRORCHECK_SPRINTF(_sntprintf_s(szBuffer, _countof(szBuffer), _countof(szBuffer) - 1, _T("%.*g"), nSizeGcvt, value));
AfxSetWindowText(hWndCtrl, szBuffer);
}
}
void AFXAPI DDX_Text2(CDataExchange* pDX, int nIDC, float& value)
{
AfxTextFloatFormat(pDX, nIDC, &value, value, FLT_DIG);
}
void AFXAPI DDX_Text2(CDataExchange* pDX, int nIDC, double& value)
{
AfxTextFloatFormat(pDX, nIDC, &value, value, FLT_DIG);
}