Шаг 151 - Еще раз о Документ - Вид - Диалог

Hi!
Вот тут вопрос хотел задать, если можно. В шагах
искал, искал, и не нашел чего-то. Как реализовать
в однодокументном приложении диалог, который будет
выполнять ввод и вывод данных? Причем числовых
(Везде все почему-то на примере строк).
Может есть уже где такое?
Т.е. проблемы две в принципе... Как получить
из этого диалога доступ к документу и как
обработать введенные циферки.
Заранее благодарен...

with best regards,
Vladimir V. Kvassov

Ну давайте созадим полный пример диалога. Задача такая. Наша программа будет рисовать эллипс. Параметры эллипса будут задаваться из диалогового окна. Эллипс будет записываться на диск и читаться. Вобщем полное короткое приложение.

Создаем приложение MFC AppWizard, как SDI и даем ему имя TestEllipse. Переходим на вкладку Resoure View и создаем новое диалоговое окно. Размещаем на этом диалоге 4 элемента редактирования (CEdit). Для того, чтобы в этот элемент управления вводились числа необходимо указать это в свойствах.

151_1.gif (5559 b)

Теперь давайте из этого диалогового окна создадм класс. Это просто. Выделите диалог и вызовите ClassWizard об этом я точно писал. Дайте имя классу CMyDialog. Теперь нам надо к элементам диалога привязать переменные. Об этом я тоже писал. Только тип переменных надо дать int.

151_2.gif (7484 b)

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

class CMyDialog : public CDialog
{
..............
// Dialog Data
	//{{AFX_DATA(CMyDialog)
	enum { IDD = IDD_DIALOG1 };
	int		m_X1;
	int		m_Y1;
	int		m_X2;
	int		m_Y2;
	//}}AFX_DATA
.............

Класс диалога теперь готов к эксплуатации. Теперь нам нужно создать переменные в классе документа CTestEllipseDoc. Давайте с такими же именами, чтобы не путаться. В них и будут храниться параметры эллипса.

class CTestEllipseDoc : public CDocument
{
........
public:
	int Y2;
	int X2;
	int Y1;
	int X1;
........
};

Вот нам теперь их нужно иницилизировать. Лучше это сделать в функции CTestEllipseDoc::OnNewDocument(). Так как эта функция всегда вызывается при создании нового документа и можно задавать значения по умолчанию.

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

	X1=10;
	Y1=10;
	X2=100;
	Y2=100;


	return TRUE;
}

Вот есть. Давайте теперь сделаем, чтобы этот эллипс рисовался, а это можно сделать в функции Draw класса вида.

void CTestEllipseView::OnDraw(CDC* pDC)
{
	CTestEllipseDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	
	pDC->Ellipse(pDoc->X1,pDoc->Y1,pDoc->X2,pDoc->Y2);    
}

Я хочу, что в этот диалог вызывался при нажатии правой кнопкой мыши на окне. Вот это событие я и превращу в функцию. Писал об этом.

void CTestEllipseView::OnRButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CView::OnRButtonDown(nFlags, point);
}

Для вызова класса диалога необходимо объявить заголовок.

// TestEllipseView.cpp : implementation of the CTestEllipseView class
//
........
#include "TestEllipseView.h"
#include "MyDialog.h"
........

Теперь сам вызов диалога и организация обмена данными.

void CTestEllipseView::OnRButtonDown(UINT nFlags, CPoint point) 
{
    CTestEllipseDoc* pDoc = GetDocument();

	CMyDialog cm;
	cm.m_X1 = pDoc->X1;
	cm.m_Y1 = pDoc->Y1;
	cm.m_X2 = pDoc->X2;
	cm.m_Y2 = pDoc->Y2;
	
	if (cm.DoModal()==IDOK)
	{
		pDoc->X1=cm.m_X1;
		pDoc->Y1=cm.m_Y1;
		pDoc->X2=cm.m_X2;
		pDoc->Y2=cm.m_Y2;
		pDoc->UpdateAllViews(NULL); 
	}

	CView::OnRButtonDown(nFlags, point);
}

Пишем на диск. То есть организуем процедуру записи на диск.

void CTestEllipseDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		ar << X1;
		ar << Y1;
		ar << X2;
		ar << Y2;
	}
	else
	{
	    ar >> X1;
		ar >> Y1;
		ar >> X2;
		ar >> Y2;
	}
}

Ну вот и всё, можно тестировать. Попробуйте нажимайте правую кнопку. Появится диалоговое окно с параметрами по умолчанию. Поменяйте цифры нажмите Ok. Эллипс изменится. Только делайте изменения большие скажем со 100 на 200.


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