简体   繁体   English

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

[英]C++/MFC Error accessing control's variable

I created a control's variable for CEdit: 我为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);
}

And this is how I map my variable to the control: 这就是我将变量映射到控件的方式:

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

This is how it works: user types some text into the edit box. 这是它的工作原理:用户在编辑框中键入一些文本。 Then he presses the "Reset" button which clears the edit box. 然后他按下“重置”按钮,清除编辑框。 This is a piece of code responsible for clearing edit box after clicking Reset button: 这是一段代码,负责在单击“重置”按钮后清除编辑框:

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

Application starts without any errors. 应用程序启动时没有任何错 I type some text into EditBox and hit "Reset" button. 我在EditBox中键入一些文本并点击“重置”按钮。 Then I get an error which leads me to winocc.cpp, line 245 (ENSURE(this)): 然后我得到一个错误,导致我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);
}

I think the problem is with the hWnd: 我认为问题在于hWnd:

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

but how to fix it ? 但是如何解决呢?

Everything works fine when I access my control's value using this: 当我使用以下方法访问控件的值时,一切正常:

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

What am I doing wrong ? 我究竟做错了什么 ?

I can see two possibilities: 我可以看到两种可能性:

  1. The control does not exist when the dialog starts. 对话框启动时控件不存在。 The first thing that CDialog::OnInitDialog will do is call DoDataExchange, so if you're creating the control later in the initialization process it's too late. CDialog :: OnInitDialog将要做的第一件事是调用DoDataExchange,所以如果你在初始化过程中稍后创建控件,那就太晚了。

  2. Your own OnInitDialog is not calling CDialog::OnInitDialog so DoDataExchange is not being called. 您自己的OnInitDialog未调用CDialog :: OnInitDialog,因此未调用DoDataExchange。

I think you should no use directly the meber of your control (in this case m_edit_a ). 我认为你不应该直接使用你的控制(在这种情况下是m_edit_a )。 Instead you should use a memeber variable, let's say CStrimg m_edit_data , and you should link it to the control: 相反,你应该使用一个CStrimg m_edit_data变量,比如CStrimg m_edit_data ,你应该将它链接到控件:

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

Now you can use directy the variable, but in order the control to be updated you should use the following code before using it: 现在您可以使用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)

This is normal procedure in MFC :), hope I helped... 这是MFC中的正常程序:),希望我帮忙...

ohh... you should also add the control to String Table ... (let me know if you do not know) 哦......你还应该把控件添加到String Table ...(如果你不知道,请告诉我)

If your dialog starts off calling CDialog::OnInitDialog() and your DoDataExchange starts off calling CDialog::DoDataExchange but still you have null hWnd pointers and get CNotSupportedException, make sure your resource (rc) file's dialog template includes all the controls (IDC_) and such you have in DoDataExchange. 如果您的对话框开始调用CDialog :: OnInitDialog()并且您的DoDataExchange开始调用CDialog :: DoDataExchange,但仍然有空的hWnd指针并获得CNotSupportedException,请确保您的资源(rc)文件的对话框模板包含所有控件(IDC_)而你在DoDataExchange中就是这样。

Check for overriding definitions if using a DLL that also provides resources. 如果使用也提供资源的DLL,请检查覆盖定义。

I can not find something wrong with you. 我找不到你的错。 I Create a new project using VC6.0,and associate a variable to the Edit,just link you do. 我使用VC6.0创建一个新项目,并将变量与Edit相关联,只需链接即可。 the exe operates normally. 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 的.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");
}

so,I think it is not a code problem.You had better try again. 所以,我认为这不是代码问题。你最好再试一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM