C ++ / MFC访问控件变量时出错

时间:2012-01-17 22:08:19

标签: c++ mfc

我为CEdit创建了一个控件变量:

class CGateDlg : public CDialog
{
    ...
    public:
        // here is my control's variable
        CEdit m_edit_a;
        // here I map variable to control
        virtual void DoDataExchange(CDataExchange* pDX);
}

这就是我将变量映射到控件的方式:

void CGateDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_EDIT_A, m_edit_a);
}

这是它的工作原理:用户在编辑框中键入一些文本。然后他按下“重置”按钮,清除编辑框。这是一段代码,负责在单击“重置”按钮后清除编辑框:

void CGateDlg::OnBnClickedReset()
{
    // clear edit box 
    m_edit_a.SetWindowTextW(L"");
}

应用程序启动时没有任何错误。我在EditBox中键入一些文本并点击“重置”按钮。然后我得到一个错误,导致我winocc.cpp,第245行(ENSURE(this)):

void CWnd::SetWindowText(LPCTSTR lpszString)
{
    ENSURE(this);
    ENSURE(::IsWindow(m_hWnd) || (m_pCtrlSite != NULL));

    if (m_pCtrlSite == NULL)
            ::SetWindowText(m_hWnd, lpszString);
    else
            m_pCtrlSite->SetWindowText(lpszString);
}

我认为问题出在hWnd:

this    0x0030fa54 {CEdit hWnd=0x00000000}  CWnd * const

但如何解决?

当我使用以下方法访问控件的值时,一切正常:

CEdit *m_edit_a;
m_edit_a = reinterpret_cast<CEdit *>(GetDlgItem(IDC_EDIT_A));
m_edit_a->SetWindowTextW(L"");

我做错了什么?

4 个答案:

答案 0 :(得分:8)

我可以看到两种可能性:

  1. 对话框启动时控件不存在。 CDialog :: OnInitDialog将要做的第一件事是调用DoDataExchange,所以如果你在初始化过程中稍后创建控件那就太晚了。

  2. 您自己的OnInitDialog未调用CDialog :: OnInitDialog,因此未调用DoDataExchange。

答案 1 :(得分:1)

我认为你不应该直接使用你的控制(在这种情况下m_edit_a)。相反,你应该使用一个memeber变量,比方说CStrimg m_edit_data,你应该将它链接到控件:

DDX_Text(pDX, IDC_EDIT_A, m_edit_data); // as you did it in DDC_Cotrol

现在您可以使用directy变量,但为了更新控件,您应该在使用之前使用以下代码:

UpdateData(true); // unlocks the control in a sense
m_edit_data = "this is my test";
UpdateData(false); // locks the control again (in a sense)

这是MFC中的正常程序:),希望我帮忙...

哦......你还应该把控件添加到String Table ...(如果你不知道,请告诉我)

答案 2 :(得分:0)

我找不到你的错。我使用VC6.0创建一个新项目,并将变量与Edit相关联,只需链接即可。 exe正常运作。

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

// Dialog Data
//{{AFX_DATA(CEditTestDlg)
enum { IDD = IDD_EDITTEST_DIALOG };
CEdit   m_Edit;
//}}AFX_DATA

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

...

.cpp

void CEditTestDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CEditTestDlg)
    DDX_Control(pDX, IDC_EDIT1, m_Edit);
    //}}AFX_DATA_MAP
}
void CEditTestDlg::OnBnClickedReset() 
{
    // TODO: Add your control notification handler code here
    m_Edit.SetWindowText("tttt");
}

所以,我认为这不是代码问题。你最好再试一次。

答案 3 :(得分:0)

如果您的对话框开始调用CDialog :: OnInitDialog()并且您的DoDataExchange开始调用CDialog :: DoDataExchange,但仍然有空的hWnd指针并获得CNotSupportedException,请确保您的资源(rc)文件的对话框模板包括DoDataExchange中的所有控件(IDC_)。

如果使用也提供资源的DLL,请检查覆盖定义。