Где инициализировать элемент управления rich edit в другом диалоге? - PullRequest
0 голосов
/ 12 ноября 2018

У меня есть приложение на основе диалогового окна MFC, которое имеет 2 диалоговых окна: главный диалог CMyDlg и второе диалоговое окно CMyDlg2.

В главном диалоге я добавляю кнопку «Перейти в диалог 2». Поэтому я добавил обработчик для кнопки, чтобы при нажатии на нее всплыло второе диалоговое окно. Все работает отлично Но во втором диалоге я добавил Rich Edit Control из панели инструментов. Я добавил для этого переменную. Я также добавил класс для второго диалога.

Теперь, если я запускаю приложение, я получаю диалоговое окно, и если я нажимаю «Перейти к диалогу 2», я получаю то, что хочу. Но мне нужно в какой-то момент изменить шрифт элемента управления rich edit, но моя программа падает.

Итак, я переопределил OnInitDialog и внутри него внесены некоторые изменения в элемент управления, но программа вылетает. После отладки я обнаружил, что дескриптор расширенного редактирования равен нулю?!

Так как и где я могу изменить цвет или выполнить некоторые инициализации для элемента управления?

(я звонил AfxInitRichEdit2() в OnInitInstance())

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

    return TRUE;
}

И это обработчик кнопки, которая создает Dialog2 и содержит элемент управления rich edit:

void CMyDlg::OnBnClickedButton1(){
    CMyDlg2 theDlg;
    theDlg.DoModal();
// TODO: Add your control notification handler code here
}
  • Если я создаю элемент управления rich edit программно, то все работает нормально, потому что я создаю его в OnInitDialog, а затем он работает нормально, но мне нужен тот, который я добавил с помощью панели инструментов мастера.

*** Дело в том, что если я напишу:

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

1 Ответ

0 голосов
/ 12 ноября 2018

Вероятно, у вас есть следующий код, вставленный мастером:

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; Конструктор для этого класса C ++ мало что делает, кроме установки m_hWnd в NULL.

Как только он будет связан с действительным дескриптором окна, мы можем начать использовать его методы Windows, такие как CRichEdit::SetWindowText

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...