Взаимодействие между 2 классами

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
bigory
Сообщения: 3
Зарегистрирован: 13 сен 2010, 22:34

Всем доброе время суток!
Помогите разобраться как взаимодействовать с 2мя классами. У меня есть главный диалог класса CnotepadDlg и немодальный диалог класса Dialog. В классе Dialog пытаюсь воздействовать на элементы, которые принадлежат классу CnotepadDlg. Вот мой неработающий пример

Код: Выделить всё

void Dialog::OnBnClickedButton3()
{
    CnotepadDlg Dlg;
    int nSelStart, nSelEnd;
    Dlg.edit1.SetFocus();        //Пытаюсь установить фокус на элемент класса CnotepadDlg
    Dlg.edit1.GetSel(nSelStart,nSelEnd);
    UpdateData(TRUE);
    CString a=Dlg.edit, b, c;
    EditC1.GetWindowText(b);
...
}
Ошибка на 3й строчке:
Изображение
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Класс CnotepadDlg описывает работу с диалогом. Но для полноценной работы с диалогом не достаточно создать экземпляр класса. Необходимо ещё и создать физически диалоговое окно. Только после того, как окно будет создано, программист сможет обращаться к элементам управления этого окна. Создать окно можно либо модально (вызвав DoModal), либо не модально (вызывав CreateDialog). В первом случае код, стоящий после вызова DoModal вызовется только после того, как диалог будет закрыт, таким образом нам не подходит этот вариант. Остаётся CreateDialog.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Decoder
Сообщения: 308
Зарегистрирован: 19 фев 2008, 23:11
Откуда: Moscow

Не так это делается. В классе CNotepadDlg нужно создать внутреннюю переменную типа CString, например: CString m_text;
В методе OnInitDialog() предварительно инициализируются значениями все нужные элементы диалога.
При закрытии окна в методе OnClose() нужно взять текст из контрола Edit и записать его в переменную m_text. После закрытия окна диалога введённый текст будет находиться в переменной m_text. Можно воспользоваться механизмом обмена данными и валидации DDX/DDV, тогда не придётся вручную писать код получения данных из контрола, это будет сделано с помощью визарда MFC.
Поумнеть несложно, куда труднее от дури избавиться.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Decoder, это то, как следует поступить в случае модального диалога. Человек подчеркнул, что у него диалог не модальный.

bigory, я только что перечитал изначальное сообщение, и понял, что, согласно заданию, CnotepadDlg является главным, а не Dialog. В этом случае вообще всё с ног на голову становится. Тебе следует разместить в классе Dialog указатель на главный класс CnotepadDlg в качестве поля. При создании экземпляра Dialog через CreateDialog (а создаваться он будет внутри CnotepadDlg), сдедует проставить в новый указатель поинтер this. Затем, нужно исправить приведённый выше код. Создание нового экземпляра класса CnotepadDlg следует выкинуть и использовать вместо него новое поле, хранящее указатель на CnotepadDlg.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
rrrFer
Сообщения: 237
Зарегистрирован: 07 сен 2008, 14:15
Контактная информация:

Через сокет можно нормально взаимодействовать, можно через каналы (не знаю есть они в win или нет..). Если все совсем уныло - через глобальную переменную, но остерегайся маньяка, который будет поддерживать твой код.

Кнешно если в вашем МФЦ нет ничего типа сигналов и слотов ))

Ну или да, кнопка может содержать указатель на родительский диалог, а диалог - указатель на кнопку. Через эти указатели они и могут взаимодействовать ))
Приглашаю на свой блог о программировании: pro-prof.com
Аватара пользователя
Decoder
Сообщения: 308
Зарегистрирован: 19 фев 2008, 23:11
Откуда: Moscow

В общем понятно, что у него за проблема.
Всё делается ещё проще, даже не нужно объявлять дополнительную переменную в классе немодального диалога для хранения указателя на родительское окно.
При создании окна диалога из класса главного окна CNotepadDlg нужно передать в параметр родительского окна указатель this.
А уже из дочернего диалога можно получить указатель на родительское окно через метод GetParent().
Вот как это выглядит:

// Это код создания дочернего немодального диалога
void CNotepadDlg::OnBnClickedButton1()
{
if (!::IsWindow(m_newDlg))
{
m_newDlg.Create(CNewDialog::IDD, this);
}
m_newDlg.ShowWindow(SW_SHOWNORMAL);
}


В обработчике нажатия кнопки на дочернем немодальном диалоге используется примерно такой код:

void CNewDialog::OnBnClickedButton1()
{
CNotepadDlg* pMainDlg = (CNotepadDlg*)GetParent();
if (pMainDlg != NULL)
{
pMainDlg->m_Edit.SetWindowText(_T("Hello world!"));
}
}
Поумнеть несложно, куда труднее от дури избавиться.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

rrrFer, а сокетами ты, видно, специально запугать решил человека :) Тут излишни сокеты, так как нету не только межпроцессного взаимодействия, а даже мультипоточности. Топик стартер ведь предоставил конкретный код.

Decoder, верно, так даже проще будет.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить