简体   繁体   中英

Where to initialize a rich edit control on another dialog?

I have an MFC dialog based application that has 2 Dialogs: Main Dialog CMyDlg and Second dialog CMyDlg2 .

On the main Dialog I add a Button "Go dialog 2". So I added a handler for the button so that when clicked it pops up the second dialog. Everything works fine But on the second Dialog I have added a Rich Edit Control from toolbox. I Added for it a variable. I also added a class for the second dialog.

Now If I run the Application I get the dialog one and if I pressed "Go to dialog 2" I got what I want. But I need at some point to change the font of the rich edit control but my program crashes.

So I overrided OnInitDialog and inside it do some changes to the control but program crashes. After debugging I found that the handle of rich edit is null?!

So how and where can I change the color or do some initializations to the control?

(I called AfxInitRichEdit2() in OnInitInstance() )

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

    return TRUE;
}

And this is the handler of button that creates the Dialog2 and that contains the rich edit control:

void CMyDlg::OnBnClickedButton1(){
    CMyDlg2 theDlg;
    theDlg.DoModal();
// TODO: Add your control notification handler code here
}
  • If I create the rich edit control programmatically then everything works fine because I create it at OnInitDialog and then it works fine but I need the one that is I added using the wizard toolbox.

*** The thing is that if I write:

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

You probably have the following code inserted by wizard:

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

This tells the dialog to associate m_richEdit with the dialog control IDC_RICHEDIT22 . But this association is not performed until the base class method CDialog::OnInitDialog(); is called.

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;
}

It's recommended to put CDialog::OnInitDialog() int the first line, to make sure the initialization is done.

GetDlgItem works because the control IDC_RICHEDIT22 exists in the dialog template and you have a valid dialog handle. You are basically making a simple call based on WinAPI's GetDlgItem :

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

There is no additional initialization needed.

But m_richEdit is just a C++ object, declared as CRichEditCtrl m_richEdit; The constructor for this C++ class doesn't do much besides setting m_hWnd to NULL .

Once it's associated with a valid window handle, we can begin using its windows methods such as CRichEdit::SetWindowText

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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