在 VC++ 6 中将数据从 CDateTimeCtrl 移动到 CTime 对象
Posted
技术标签:
【中文标题】在 VC++ 6 中将数据从 CDateTimeCtrl 移动到 CTime 对象【英文标题】:Moving data from a CDateTimeCtrl to a CTime object in VC++ 6 【发布时间】:2015-10-19 19:30:33 【问题描述】:在使用 VS6 时,我注意到在 CDateTimeCtrl 对象中更改日期时,我的某些对话框会崩溃。调查发现,对 DDX_DateTimeCtrl 的调用将 12 个字节的数据移动到一个 4 个字节宽的 CTime 对象上。谁能解释为什么会发生这种情况?有人知道怎么改吗?
标题:
#if !defined(AFX_DATEDIALOG_H__B9373304_D774_4447_A4D1_BB4E1FB3404F__INCLUDED_)
#define AFX_DATEDIALOG_H__B9373304_D774_4447_A4D1_BB4E1FB3404F__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DateDialog.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CDateDialog dialog
class CDateDialog : public CDialog
// Construction
public:
CDateDialog(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//AFX_DATA(CDateDialog)
enum IDD = IDD_DIALOG_DATE ;
CDateTimeCtrl m_StartDate;
CDateTimeCtrl m_EndDate;
CTime m_tmEndDate;
CTime m_tmStartDate;
//AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//AFX_VIRTUAL(CDateDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//AFX_MSG(CDateDialog)
afx_msg void OnButtonBack();
afx_msg void OnDatetimechangeEndDate(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnDatetimechangeStartDate(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnCloseupStartDate(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnCloseupEndDate(NMHDR* pNMHDR, LRESULT* pResult);
//AFX_MSG
DECLARE_MESSAGE_MAP()
private:
// the range limits for the dates; these are set to the values found
// in m_tmStartDate and m_tmEndDate in OnInitDialog
CTime m_tmStart; // beginning of the range
CTime m_tmEnd; // end of the range
;
//AFX_INSERT_LOCATION
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DATEDIALOG_H__B9373304_D774_4447_A4D1_BB4E1FB3404F__INCLUDED_)
Code:
// DateDialog.cpp : implementation file
//
#include "stdafx.h"
#include "CustomerSales.h"
#include "DateDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDateDialog dialog
CDateDialog::CDateDialog(CWnd* pParent /*=NULL*/)
: CDialog(CDateDialog::IDD, pParent)
//AFX_DATA_INIT(CDateDialog)
m_tmEndDate = 0;
m_tmStartDate = 0;
//AFX_DATA_INIT
void CDateDialog::DoDataExchange(CDataExchange* pDX)
CDialog::DoDataExchange(pDX);
//AFX_DATA_MAP(CDateDialog)
DDX_Control(pDX, IDC_START_DATE, m_StartDate);
DDX_Control(pDX, IDC_END_DATE, m_EndDate);
DDX_DateTimeCtrl(pDX, IDC_END_DATE, m_tmEndDate);
DDX_DateTimeCtrl(pDX, IDC_START_DATE, m_tmStartDate);
//AFX_DATA_MAP
BEGIN_MESSAGE_MAP(CDateDialog, CDialog)
//AFX_MSG_MAP(CDateDialog)
ON_BN_CLICKED(IDC_BUTTON_BACK, OnButtonBack)
ON_NOTIFY(DTN_DATETIMECHANGE, IDC_END_DATE, OnDatetimechangeEndDate)
ON_NOTIFY(DTN_DATETIMECHANGE, IDC_START_DATE, OnDatetimechangeStartDate)
ON_NOTIFY(DTN_CLOSEUP, IDC_START_DATE, OnCloseupStartDate)
ON_NOTIFY(DTN_CLOSEUP, IDC_END_DATE, OnCloseupEndDate)
//AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDateDialog message handlers
void CDateDialog::OnButtonBack()
// exit with our buton ID
EndDialog(IDC_BUTTON_BACK);
void CDateDialog::OnDatetimechangeEndDate(NMHDR* pNMHDR, LRESULT* pResult)
if(m_EndDate.GetMonthCalCtrl() == NULL)
UpdateData();
if(m_tmStartDate > m_tmEndDate)
m_tmStartDate = m_tmEndDate;
UpdateData(FALSE);
*pResult = 0;
void CDateDialog::OnDatetimechangeStartDate(NMHDR* pNMHDR, LRESULT* pResult)
if(m_StartDate.GetMonthCalCtrl() == NULL)
UpdateData();
if(m_tmEndDate < m_tmStartDate)
m_tmEndDate = m_tmStartDate;
UpdateData(FALSE);
*pResult = 0;
void CDateDialog::OnCloseupStartDate(NMHDR* pNMHDR, LRESULT* pResult)
UpdateData();
if(m_tmEndDate < m_tmStartDate)
m_tmEndDate = m_tmStartDate;
UpdateData(FALSE);
*pResult = 0;
void CDateDialog::OnCloseupEndDate(NMHDR* pNMHDR, LRESULT* pResult)
UpdateData();
if(m_tmStartDate > m_tmEndDate)
m_tmStartDate = m_tmEndDate;
UpdateData(FALSE);
*pResult = 0;
【问题讨论】:
您能否在此处发布您的代码,包括头文件中的声明。所以我们可以帮助你。 【参考方案1】:我很久以前就观察到 CDateTimeCtrl 的错误。如果与 CTime 变量一起使用,该类的 GetTime 方法会崩溃。我记得当时我在网上找到了与这个问题相关的参考资料。我现在找不到了。建议的解决方案是使用 COleDateTime。
好像DDE/DDX交换也有类似的问题,最新的MFC还没有修复。
当时对我来说最简单的解决方法是使用 COleDateTime 变量。
DDX_DateTimeCtrl 与 CTime 和 COleDateTime 一起使用,因此您的解决方案是将 COleDateTime 用于您的 m_tmEndDate
和 m_tmStartDate
变量。
【讨论】:
以上是关于在 VC++ 6 中将数据从 CDateTimeCtrl 移动到 CTime 对象的主要内容,如果未能解决你的问题,请参考以下文章
如何在 vc 6.0 中将对象转换或分配为 Variant 类型
在 devenv.exe 中将 microsoft 编译器从 vc14 更改为 vc12