Для работы возьмем наш первый проект и внесем изменения (вообще я так и задумал). Пока у нас все в одном СРР файле (это не хорошо, исправимся). Самый простой способ - это создать новый проект 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() используется очень часто и есть у многих объектов. Обычно она требует:
this означает, что "вставлять туда где находишься" (мы в классе рамки окна).
Вот так должна выглядеть программа после запуска.
Обратите внимание на схему ниже. На ней показана вложенность объектов. То есть кому, какой объект принадлежит. Создаются объекты в порядке от CWinApp и дальше, а разрушаются в обратном.
CStatic* MyStatic; ......
MyButton = new CButton(); MyButton->Create("MyButton",WS_CHILD|WS_VISIBLE|SS_CENTER, CRect(120,10,220,50),this,IDC_MYBUTTON); ......
if (MyStatic!=NULL) delete MyStatic; if (MyButton!=NULL) delete MyButton; ......