【问题标题】:Assertion Error in Dialog manipulation对话框操作中的断言错误
【发布时间】:2011-09-06 10:41:20
【问题描述】:

标题很弱,但我会在这里解释一下。我正在开发 MFC 应用程序。单击按钮时,将创建一个新对话框,将一些字符串添加到第二个对话框中的ComboBox,然后显示该对话框。代码如下所示。 Combo1 是在 Class1.h 文件中定义的 CComboBox 变量。问题是当我尝试调用dlg.Foo() 方法时,程序给了我一个Debug Assertion Error。错误出现在AddString 行,此外还出现在afxwin2.inl 文件中,在这行代码中:

{ ASSERT(::IsWindow(m_hWnd)); return (int)::SendMessage(m_hWnd, CB_ADDSTRING, 0, (LPARAM)lpszString); }

CClass1 dlg = new CClass1(this);
dlg.Foo();
dlg.DoModal();

void CClass1::Foo()
{
    Combo1.AddString(TEXT("text"));
}

【问题讨论】:

  • 好的,我重新阅读了这个问题,它真的不是很清楚。您在示例代码中只显示了一个对话框,但您在问题中讨论了两个对话框。
  • 我有主对话框和第二个对话框。第二个对话框在 CClass1 中定义。抱歉我的问题含糊不清。

标签: c++ mfc dialog modal-dialog


【解决方案1】:

在您调用 foo() 时尚未创建组合框窗口。您可能希望将 CStringArray 成员添加到 CClass1,然后将其设置为使用 DDX 加载组合框。 DDX 步骤将在组合框窗口创建后发生。

这里有一个自定义 DDX 函数可以完成这项任务:

void AFXAPI 
DDX_CBStringArray (CDataExchange* pDX, int nIDC, CStringArray& strings)
{
    HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
    bool bMine = false;
    CComboBox* pCB = dynamic_cast<CComboBox*>(CWnd::FromHandlePermanent(hWndCtrl));
    if (!pCB)
    {
        pCB = new CComboBox;
        pCB->Attach(hWndCtrl);
        bMine = true;
    }
    if (pDX->m_bSaveAndValidate)
    {
        strings.RemoveAll();
        int nNumStrings = pCB->GetCount();
        CString strVal("");
        for (int x = 0; x < nNumStrings; ++x)
        {
            pCB->GetLBText(x, strVal);
            strings.Add(strVal);
        }
    }
    else
    {
        pCB->ResetContent();
        INT_PTR nSize = strings.GetSize();
        for (INT_PTR x = 0; x < nSize; ++x)
        {
            pCB->AddString(strings.GetAt(x));
        }
    }
    if (bMine)
    {
        pCB->Detach();
        delete pCB;
    }
}

您将向 CClass1 添加一个 CStringArray 成员,并在您的 DDX 块中添加对此函数的引用。在构造类实例之后,但在调用 DoModal() 之前,将 ComboBox 中所需的字符串添加到 StringArray 变量中。此函数将为您填充组合框。

CClass1 改变如下:

CClass1 : public CDialogEx
{
...
public:
    CStringArray myStringEntries;

...
protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
...
};

您的 DoDataExchange 覆盖将如下所示:

void CClass1::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CClass1)
    DDX_CBStringArray(pDX, IDC_COMBO1, myStringEntries);
    ...
    //}}AFX_DATA_MAP
}

您的调用类更改为:

CClass1 dlg(this);
dlg.myStringEntries.Add("Some text");
dlg.myStringEntries.Add("More text");
dlg.DoModal();

或者,或者,可以更改 CClass1::foo() 以填充 CStringArray:

void CClass1::Foo()
{
    myStringEntries.Add(TEXT("text"));
    myStringEntries.Add(TEXT("more text"));
}

【讨论】:

  • 问题是 ComboBox 会有多个字符串,我希望在 DoModal() 第二个对话框时加载它们。
  • 那么 CStringList 会更有意义。让我编辑和详细说明。
  • @AdrianMar 您需要将对话框构造函数的添加字符串移出。
  • @johnathon 它不在对话框的构造函数中。它在一个单独的方法中。
  • @jwismar 感谢您的努力,但选择的答案有点简单。再次,我很感激!
【解决方案2】:

您可以将字符串添加到 OnInitDialog() 内的组合框中,在 DoModal() 期间会自动调用该组合框:

在标题中:

class CClass1 : public CDialog
{
    protected:
        virtual BOOL OnInitDialog();
}

在cpp文件中:

BOOL CClass1::OnInitDialog()
{
    __super::OnInitDialog();
    Combo1.AddString(TEXT("text"));  // or just call Foo() here if that's preferred

    return TRUE;
}

【讨论】:

  • 一开始看起来很明显所以我尝试了一下,但是Visual Studio为第二个对话框(.cpp文件)创建的类没有这样的功能。手动添加时,它给我一个错误,说“不允许继承的成员”。
  • 不,它继承自 CDialogEX。
  • 你在header中是不是这样声明的:protected: virtual BOOL OnInitDialog();
  • @17 of 26 此函数如何用于从第二个对话框创建的第三个对话框?
  • 应该是一样的。 MFC 对话框的问题是在调用 OnInitDialog() 之前控件不存在,因此您需要在那里进行初始化工作。
【解决方案3】:

嘿!我有一个建议,有一种更简单的方法可以将字符串从第一个对话框传递到第二个对话框。您已经在第一个对话框中创建了第二个对话框类的实例,现在您需要做的就是在第二个对话框的类中添加一个字符串成员变量,并在调用 DoModal() 之前使用组合框字符串初始化该变量。

【讨论】:

    【解决方案4】:

    当您在OnInitDialog 函数中引用m_comboBox 时,即使m_comboBox 存在于DoDataExchange 定义中,您也会收到错误消息。

    你可以用两种方法解决这个问题:

    1. 在您的OnInitDialog 中,您可以参考您的组合框

      CComboBox *cmb = (CComboBox *)GetDlgItem(IDC_YOURCOMBOBOX);

    2. 或在访问m_comboBox之前调用UpdateData,这将调用DoDataExchange函数,如MSDN documentation关于DoDataExchange函数的备注中所述。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-08
      • 1970-01-01
      相关资源
      最近更新 更多