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

Posted

技术标签:

【中文标题】在哪里初始化另一个对话框上的富编辑控件?【英文标题】:Where to initialize a rich edit control on another dialog? 【发布时间】:2018-11-11 21:45:16 【问题描述】:

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

在主对话框上,我添加了一个按钮“转到对话框 2”。所以我为按钮添加了一个处理程序,以便在单击它时弹出第二个对话框。一切正常但在第二个对话框中,我从工具箱中添加了丰富的编辑控件。我为它添加了一个变量。我还为第二个对话框添加了一个类。

现在,如果我运行应用程序,我会得到对话框一,如果我按下“转到对话框 2”,我就会得到我想要的。但我有时需要更改富编辑控件的字体,但我的程序崩溃了。

所以我覆盖了OnInitDialog,并在其中对控件进行了一些更改,但程序崩溃了。调试后发现富编辑的句柄为空?!

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

(我在OnInitInstance()中调用了AfxInitRichEdit2()

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?

【问题讨论】:

m_richEdit 不会是 NULL,但它的窗口句柄将是 NULL,因为它还没有被创建为窗口。您必须先调用默认方法。改为:BOOL CMyDlg2::OnInitDialog()__super::OnInitDialog();m_richEdit.SetWindowText("Hello there!");return TRUE; 准确地说,richedit 窗口已经在CMyDlg2::OnInitDialog() 中创建,但它不会与m_richEdit 变量关联,除非基类的@ 987654336@方法被调用。 基本上就像 Barmak 写的那样,但 __super 是微软特有的,我会写 CDialog::OnInitDialog() 代替,这是标准 C++。 看起来您现在正在调用基类方法 CMyDlg2::OnInitDialog()CDialog::OnInitDialog(); ... 应该可以工作。 好的,不客气。 【参考方案1】:

您可能已经被向导插入了以下代码:

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() int 放在第一行,以确保初始化完成。

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

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

不需要额外的初始化。

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

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

【讨论】:

您介意解释一下为什么GetDlgItem(IDC_RICHEDIT22)-&gt;SetWindowText("Hello"); 有效吗? 我在编辑中添加了更多说明。 现在明白了!感谢您的帮助、努力和时间。

以上是关于在哪里初始化另一个对话框上的富编辑控件?的主要内容,如果未能解决你的问题,请参考以下文章

从另一个更改编辑 mfc 控件文本

Qt中获取控件所在界面的位置,该怎么解决

vc++ 关于对话框上标签(TAB)控件的使用问题

MFC如何获取控件在对话框上的位置坐标

当我按下对话框窗口中的按钮时,如何在该对话框中更改/附加编辑控件框的文本

C#中如何在一个窗体中调用另一个窗体控件中的数据?