MFC中加入DataTimePicker控件后,编译通过但运行出错。

问题描述

我使用MFC AppWizard创建了一个SDI应用‘test’,未勾选ActiveX控件,其它为默认设置。然后为CTestView类添加成员变量CString m_strName,创建对话框类CTestDialog,并使用向导为其添加成员变量CTime m_dataTime(自动添加DDX函数)。

之后,在CTestView::OnDraw(CDC* pDC)中创建CTestDialog对象dlg,使用DoModal生成窗口后,对m_strName重新赋值。编译通过,但运行出错。
在Debug的时候发现,调用了DoModal之后, 对话框出现之后,点击OK按钮后,原本保存m_strName地址的那部分内存(4字节)内容会被修改,导致找不到m_strName的值(新地址越界了,原地址指向的内容没变)。

而在我单独使用EditBox控件的时候则不会出现这样的问题,所以我想知道这中间发生了什么,有什么区别以及该如何正确使用DataTimePicker控件。

代码部分

testView.h图片说明

// testView.h : interface of the CTestView class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_TESTVIEW_H__85D7C03F_39A6_4535_80A5_5E109333D12B__INCLUDED_)
#define AFX_TESTVIEW_H__85D7C03F_39A6_4535_80A5_5E109333D12B__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


class CTestView : public CView
{
protected: // create from serialization only
    CTestView();
    DECLARE_DYNCREATE(CTestView)

// Attributes
public:
    CTestDoc* GetDocument();
    CString m_strName;

// Operations
public:

// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CTestView)
    public:
    virtual void OnDraw(CDC* pDC);  // overridden to draw this view
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    protected:
    virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
    virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
    virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
    //}}AFX_VIRTUAL

// Implementation
public:
    virtual ~CTestView();
#ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// Generated message map functions
protected:
    //{{AFX_MSG(CTestView)
        // NOTE - the ClassWizard will add and remove member functions here.
        //    DO NOT EDIT what you see in these blocks of generated code !
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

#ifndef _DEBUG  // debug version in testView.cpp
inline CTestDoc* CTestView::GetDocument()
   { return (CTestDoc*)m_pDocument; }
#endif

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_TESTVIEW_H__85D7C03F_39A6_4535_80A5_5E109333D12B__INCLUDED_)

testView.cpp

// testView.cpp : implementation of the CTestView class
//

#include "stdafx.h"
#include "test.h"

#include "testDoc.h"
#include "testView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CTestView

IMPLEMENT_DYNCREATE(CTestView, CView)

BEGIN_MESSAGE_MAP(CTestView, CView)
    //{{AFX_MSG_MAP(CTestView)
        // NOTE - the ClassWizard will add and remove mapping macros here.
        //    DO NOT EDIT what you see in these blocks of generated code!
    //}}AFX_MSG_MAP
    // Standard printing commands
    ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTestView construction/destruction

CTestView::CTestView()
{
    // TODO: add construction code here
    m_strName="0000";
}

CTestView::~CTestView()
{
}

BOOL CTestView::PreCreateWindow(CREATESTRUCT& cs)
{
    // TODO: Modify the Window class or styles here by modifying
    //  the CREATESTRUCT cs

    return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CTestView drawing

void CTestView::OnDraw(CDC* pDC)
{
    CTestDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here
    CTestDialog dlg;
    dlg.DoModal();
    m_strName="11111";
}

/////////////////////////////////////////////////////////////////////////////
// CTestView printing

BOOL CTestView::OnPreparePrinting(CPrintInfo* pInfo)
{
    // default preparation
    return DoPreparePrinting(pInfo);
}

void CTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    // TODO: add extra initialization before printing
}

void CTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    // TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CTestView diagnostics

#ifdef _DEBUG
void CTestView::AssertValid() const
{
    CView::AssertValid();
}

void CTestView::Dump(CDumpContext& dc) const
{
    CView::Dump(dc);
}

CTestDoc* CTestView::GetDocument() // non-debug version is inline
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTestDoc)));
    return (CTestDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CTestView message handlers

Dialogs.h

#if !defined(AFX_DIALOGS_H__32ACF32B_B56E_4CFB_A5AE_E6F2F343DF92__INCLUDED_)
#define AFX_DIALOGS_H__32ACF32B_B56E_4CFB_A5AE_E6F2F343DF92__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Dialogs.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CTestDialog dialog

class CTestDialog : public CDialog
{
// Construction
public:
    CTestDialog(CWnd* pParent = NULL);   // standard constructor

// Dialog Data
    //{{AFX_DATA(CTestDialog)
    enum { IDD = IDD_DIALOG1 };
    CTime   m_dateTime;
    //}}AFX_DATA


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

// Implementation
protected:

    // Generated message map functions
    //{{AFX_MSG(CTestDialog)
        // NOTE: the ClassWizard will add member functions here
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DIALOGS_H__32ACF32B_B56E_4CFB_A5AE_E6F2F343DF92__INCLUDED_)

Dialogs.cpp

// Dialogs.cpp : implementation file
//

#include "stdafx.h"
#include "test.h"
#include "Dialogs.h"

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

/////////////////////////////////////////////////////////////////////////////
// CTestDialog dialog


CTestDialog::CTestDialog(CWnd* pParent /*=NULL*/)
    : CDialog(CTestDialog::IDD, pParent)
{
    //{{AFX_DATA_INIT(CTestDialog)
    m_dateTime = 0;
    //}}AFX_DATA_INIT
}


void CTestDialog::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CTestDialog)
    DDX_DateTimeCtrl(pDX, IDC_DATETIMEPICKER1, m_dateTime);
    //}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CTestDialog, CDialog)
    //{{AFX_MSG_MAP(CTestDialog)
        // NOTE: the ClassWizard will add message map macros here
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTestDialog message handlers

3个回答

按照你说的写了下, 没问题啊, 上传个按照你说明的写的demo你试试图片说明
把图片下载下来改成zip格式就可以了

qq_33407933
爱偷懒的 回复二滩王小虎:我刚才又发现release版本也不会报bug,/wulian
接近 3 年之前 回复
qq_33407933
爱偷懒的 回复一步一光年: 我的天,心好累。我刚才自己用vs再做一遍也没问题,应该是我的库有问题没跑了。谢谢你
接近 3 年之前 回复
u014457656
一步一光年 回复二滩王小虎:编译了你的代码, 运行是没有问题的, 可能vc6安装的有问题
接近 3 年之前 回复
qq_33407933
爱偷懒的 回复一步一光年: 重新编辑了问题,代码附在“代码部分”标题后面了。不会真的是我的库有问题吧?
接近 3 年之前 回复
u014457656
一步一光年 回复二滩王小虎: 可以上传下你的代码看下
接近 3 年之前 回复
u014457656
一步一光年 回复二滩王小虎: 一样啊, 点击ok键就是回车, 没问题啊
接近 3 年之前 回复
qq_33407933
爱偷懒的 谢谢。不好意思,前面有一点忘了讲了(现在重新编辑了问题),问题的出现是在我点击了OK按钮,对话框消失之后才出现的。
接近 3 年之前 回复

可以加悬赏吗?
真的是被这个bug卡到了,不知道该怎么解决啊。
本来是想要用两个datetimepicker控件来获取起止日期,然后求时间跨度的,结果第一关就没过去,给datetimepicker控件加一个变量就会出现问题。

 void CTestView::OnDraw(CDC* pDC)
{
    CTestDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here
    CTestDialog dlg;
    dlg.DoModal();
    m_strName="11111";
}

对话框你放到这里,View每次刷新都会打开对话框。。你确定要这样使用???

如果需要打开对话框,还是推荐使用菜单栏的菜单来实现。。。

qq_33407933
爱偷懒的 一开始是放在菜单里,这里只是单纯的想测试那三句引发的问题才这样放的
接近 3 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!