Шаг 158 - Обновление вида из панели диалога

 -----Исходное сообщение-----
От: Denis Lazebnik 
Кому: kaev@yandex.ru
Дата: 18 марта 2000 г. 11:52
Тема: Идея о новом шаге в MFC
Привет!

При написании программы на Visual C++ 6.0 я наткнулся на небольшую 
проблемму и подумал что для её решения можно уделить целый шаг на сайте.
Проблемма такова:
Скажем у меня самая простая программа SDI и нажатием левой кнопки крысы у
меня появляется  Modal Dialog в котором введя какую-то строку текста и 
нажав OK этот текст у меня появляется в окне View. В мой Dialog я хочу 
добавить кноку Update Now при нажатии которой, текст в окне View обновляется,
но сам Dialog не закрывается.
Спасибо.

Задача мне понравилась. Спасибо Денис. Вот и давайте её реализуем. Ну во-первых делаем приложение SDI c именем TestOutDialog c помощью AppWizard. Теперь обычные вещи. Делаем диалоговое окно с полем редактирования CEdit и кнопкой Update. Для диалогового окна длеаем класс. Об этом много раз писал как. Называем этот класс CMyDialog. Этот класс унаследует все функции класса CDialog. Теперь некоторые нюансы. Данные должны храниться в классе документа. У нас класс документа называется CTestOutDialogDoc, кроме того класс документа умеет обновлять все виды связанные с ним. Поэтому для реализации необходимой нам кнопки вот чего надо. Надо, чтобы в классе диалога была ссылка на класс документа и тогда ...... . Вот давайте конструктор класса диалога и изменим, и еще сделаем ссылку на класс документа.

#include "TestOutDialogDoc.h"

/////////////////////////////////////////
// CMyDialog dialog

class CMyDialog : public CDialog
{
// Construction
public:
	CMyDialog(CTestOutDialogDoc* pD,CWnd* pParent = NULL);   // standard constructor


protected:
	CTestOutDialogDoc* pDoc;
	.........
};

Код конструктора тоже надо изменить. Вот так, чтобы сохранить в диалоге ссылку на документ.

CMyDialog::CMyDialog(CTestOutDialogDoc* pD,CWnd* pParent)
	: CDialog(CMyDialog::IDD, pParent)
{
	pDoc=pD;
	......
}

С этим разобрались. Теперь в любой момент мы будем из класса диалога иметь доступ к классу документа. Давайте займемся нашим полем редактирования. Вы когда-нибудь пробовали к полю редактирования привязать две переменных типа строки и элемента управления. Не пробовали тогда сделайте вот так.

158_1.gif (6308 b)

Зачем я это делаю ? Проблема в получении текста из строки редактирования. Единственный гарантированный способ получить текст если завести переменную типа элемент управления и воспользоваться функцией GetWindowText не дожидаясь механизма DDX. А со строкой работать удобнее во всех других случаях. Давайте посмотрим код к кнопке.

void CMyDialog::OnButton1() 
{
	char buffer[100];
	m_Edit.GetWindowText(buffer,sizeof(buffer)); ; 
	pDoc->str=buffer;
	pDoc->UpdateAllViews(NULL); 
}

При нажатии на кнопку получаем текст, потом передаем его в класс документа и вызываем функции обновления видов. Теперь нужно создать пункт меню для вызова диалога. Делали, писать не буду. Имя ему New Str. Код нужно, чтобы обрабатывался в классе вида. Тоже писалось. А вот и код.

void CTestOutDialogView::OnTestNewstr() 
{
	CTestOutDialogDoc* pDoc = GetDocument();
	CMyDialog cm(pDoc);
	cm.m_Str=pDoc->str;  
	cm.DoModal() 
}

Передаем класс документа. Правда перед выводом на экран передаем переменную из класса документа, в которой хранится строка. Вот её описание.

class CTestOutDialogDoc : public CDocument
{
	.......
public:
	CString str;
        ......
};

И начальная инициализация при создании нового документа.

BOOL CTestOutDialogDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	str="Hello MFC";
	return TRUE;
}

В классе вида вывод на экран.

void CTestOutDialogView::OnDraw(CDC* pDC)
{
	CTestOutDialogDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	

	pDC->;TextOut(10,10,pDoc->str); 
}

Идея была рассказана следующая. В класс диалога был передан указатель на класс документа. С помощью этого указателя изменялись данные и обновлялся экран без закрытия диалога.


Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 19.03.2000