在哪里初始化另一个对话框上的丰富编辑控件?

时间:2018-11-11 21:45:17

标签: c++ mfc

我有一个基于MFC对话框的应用程序,其中包含2个对话框:主对话框CMyDlg和第二个对话框CMyDlg2

在主对话框上,添加一个按钮“转到对话框2”。因此,我为按钮添加了一个处理程序,以便在单击该按钮时会弹出第二个对话框。一切正常,但是在第二个对话框中,我从工具箱添加了Rich Edit Control。我为它添加了一个变量。我还为第二个对话框添加了一个类。

现在,如果我运行该应用程序,则会显示一个对话框,如果按“转到对话框2”,则会显示我想要的内容。但是我有时需要更改丰富的编辑控件的字体,但是我的程序崩溃了。

因此,我重写了OnInitDialog,并在其中进行了一些控件更改,但程序崩溃了。调试后,我发现丰富编辑的句柄为空?!

那我该如何以及在哪里更改颜色或对控件进行一些初始化?

(我在AfxInitRichEdit2()中叫OnInitInstance()

BOOL CMyDlg2::OnInitDialog() {
    m_richEdit.SetWindowText("Hello there!"); // program crashes because the handle m_richEdit is null.

    return TRUE;
}

这是创建Dialog2并包含丰富编辑控件的按钮处理程序:

void CMyDlg::OnBnClickedButton1(){
    CMyDlg2 theDlg;
    theDlg.DoModal();
// TODO: Add your control notification handler code here
}
  • 如果我以编程方式创建丰富的编辑控件,那么一切正常,因为我在OnInitDialog上创建了它,然后一切正常,但是我需要使用向导工具箱添加的控件。

***问题是,如果我写:

    m_richEdit.SetWindowText(""); // program crashes but if I wirte:
    GetDlgItem(IDC_RICHEDIT221).SetWindowText(""); it works fine?

1 个答案:

答案 0 :(得分:2)

向导可能会插入以下代码:

void DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_RICHEDIT22, m_richEdit);
}

这告诉对话框将m_richEdit与对话框控件IDC_RICHEDIT22关联。但是,直到调用基类方法CDialog::OnInitDialog();时,才执行此关联。

BOOL CMyDlg2::OnInitDialog() 
{
    //this line should work:
    GetDlgItem(IDC_RICHEDIT22)->SetWindowText("Hello");

    //this line won't work:
    //m_richEdit.SetWindowText("Hello there!"); <- richedit's handle is NULL

    //this line will subclass m_richEdit
    //plus run other initialization
    CDialog::OnInitDialog(); 

    //m_richEdit is ready
    m_richEdit.SetWindowText("Hello there!"); 
    return TRUE;
}

建议将CDialog::OnInitDialog()放在第一行,以确保初始化完成。

GetDlgItem之所以有效,是因为对话框模板中存在控件IDC_RICHEDIT22,并且您具有有效的对话框句柄。您基本上是在基于WinAPI的GetDlgItem进行简单的调用:

HWND hedit = ::GetDlgItem(m_hWnd, IDC_RICHEDIT22);
::SetWindowText(hedit, "Hello world");

不需要其他初始化。

但是m_richEdit只是一个C ++对象,声明为CRichEditCtrl m_richEdit;除了将m_hWnd设置为NULL之外,此C ++类的构造函数并没有做什么用。

一旦将其与有效的窗口句柄相关联,我们就可以开始使用其窗口方法,例如CRichEdit::SetWindowText