Шаг 2 - Вставка элемента управления в окно (Controls)

Создание проекта

Для работы возьмем наш первый проект и внесем изменения (вообще я так и задумал). Пока у нас все в одном СРР файле (это не хорошо, исправимся). Самый простой способ - это создать новый проект step2. Пустой естественно. Скопировать в него step1.cpp. Переименовать его в step2.cpp. И вставить в проект Add File to Project. В результате весь код с прошлого проекта Вы перенесете в новый.

Создаем код

Это нужно поместить где-нибудь после всех #include:

#define IDC_MYBUTTON 100	// Идентификатор кнопки
#define IDC_MYEDIT 102	// Идентификатор поля редактирования

Необходимо изменить описания конструктора класса окна.

class CMainWnd : public CFrameWnd
{
public:
	CMainWnd();	// Конструктор по умолчанию
	~CMainWnd(); 	// Деструктор
private:
	CStatic* MyStatic;	// Указатель на объект надпись
	CButton* MyButton;	// Указатель на объект кнопка
	CEdit* MyEdit;	// Указатель на объект поле редактирования
};

Изменения в конструкторе окна. В конструкторе результат создания объектов оператором new проверяется через проверку на NULL. Если ошибка, то все действия с этим элементом отменятся. На будущее это не самый лучший выход. Вообще-то, наверно, невозможность создания одного элемента должна приводить к завершению программы. Хотя это выбор программиста. В сложной программе, если произойдет ошибка создания объекта нужно выбирать, а на будущее у нас выбора не много. Либо перенести создание объектов в отдельную функцию, где можно проверить результат и закрыть программу, либо использовать исключения (try,throw,catch), чтобы отслеживать ошибки в конструкторах. Вы позже всему научитесь :-).

CMainWnd::CMainWnd()
{
	Create(NULL,"Step2",WS_OVERLAPPEDWINDOW,rectDefault,
		NULL,NULL);// Создать окно программы
	// оператор new по умолчанию в случае ошибки вернет NULL
	// проверка указателя на NULL дает возможность избавиться от дальнейших ошибок
	MyStatic = new CStatic();
	if (MyStatic!=NULL) MyStatic->Create("MyStatic",WS_CHILD|WS_VISIBLE|SS_CENTER,
		CRect(10,10,100,50),this);	// создали
	MyButton = new CButton();
	if (MyButton!=NULL) MyButton->Create("MyButton",WS_CHILD|WS_VISIBLE|SS_CENTER,
		CRect(120,10,220,50),this,IDC_MYBUTTON);
	MyEdit = new CEdit();
	if (MyEdit!=NULL) MyEdit->Create(WS_CHILD|WS_VISIBLE|WS_BORDER,
		CRect(240,10,340,50),this,IDC_MYEDIT);
}

Изменения в деструкторе. Когда класс окна в виде объекта будет уже не нужен, автоматически вызывается деструктор. Раз удаляется окно, значит элементы управления внутри него уже не нужны. Самое время их удалить:

CMainWnd::~CMainWnd()
{
	if (MyStatic!=NULL) delete MyStatic;	// удалить динамический объект
	if (MyButton!=NULL) delete MyButton;	// удалить динамический объект
	if (MyEdit!=NULL) delete MyEdit;	// удалить динамический объект
}

Описание

Windows, в отличие от DOS, содержит в себе много элементов управления. Оказалось, что кнопки, поля с надписями, списки и т.д. используются в каждой программе. Сам программный код реализации этих элементов находится в DLL Windows. То есть в вашем компиляторе нет реализации этих функций в библиотеках (lib), там только ссылки. Вот мы и используем их в своей программе. У всех элементов управления есть одно свойство. Они должны все иметь идентификатор - число, которое определяет этот элемент управления. Правило простое - хочешь элемент управления - определи идентификатор.

Первыми строками используя #define мы объявляем идентификаторы. Смысл этих команд в том, что набору символов присваивается число. И при компиляции вместо набора символов подставляется число, что очень удобно.

Дальше в класс рамки окна вставляются указатели на объекты элементов управления. Это только указатели, т.е. числа. Объекта самого нет. Каждый объект использует память и до того, как он не понадобится, хранится только указатель.

В конструкторе окна мы и создадим объекты new, а после этого вызовем функцию Create(), которая из объекта создаст элемент управления. Если вы обратили внимание, то у MyStatic нет идентификатора. Это обман, он просто задан по умолчанию, как 0xffff. Это подтверждает правило кесарю - кесарево, а элементу управления - идентификатор. Функция Create() используется очень часто и есть у многих объектов. Обычно она требует:

  1. Строку для имени или надписи
  2. Стиль
  3. Размеры и положение
  4. Куда вставлять
  5. Идентификатор

this означает, что "вставлять туда где находишься" (мы в классе рамки окна).

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

2_1.gif (1558 b)

Обратите внимание на схему ниже. На ней показана вложенность объектов. То есть кому, какой объект принадлежит. Создаются объекты в порядке от CWinApp и дальше, а разрушаются в обратном.

2_2.gif (1962 b)

Шпаргалка

  1. В конструкторе окна надо объявить указатели на элементы управления:
    CStatic* MyStatic;
    ......
  2. Указатели превратить в объекты и вызвать функцию Create():
    MyButton = new CButton();
    MyButton->Create("MyButton",WS_CHILD|WS_VISIBLE|SS_CENTER,
    	CRect(120,10,220,50),this,IDC_MYBUTTON);
    ......
  3. Обеспечить удаление динамических объектов при завершении программы:
    if (MyStatic!=NULL) delete MyStatic;
    if (MyButton!=NULL) delete MyButton;
    ......
    
  4. Откомпилировать, собрать и запустить.

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