Файл проекта
Файл проекта нужен для объединения в один комплекс всех файлов, входящих в приложение. Обычно используется не менее трех файлов даже для самого простого приложения, которое практически ничего не умеет делать.
Файл проекта, в основном, состоит из следующих файлов:
файл.ide - сам файл проекта
файл.срр - текст программы
файл.def - спец.информация
файл.rc - файл ресурсов (как выглядят окна, меню,кнопки,иконки, курсоры, если рисунки - то небольшие). Вставлять большие рисунки, музыку и видео невыгодно, т.к. EXE-файл будет огромных размеров.
После того как эти файлы написаны, компиллируем проект. Будет создан файл с расширением .ехе из срр, def, rc с ссылками на ресурсные файлы, которые не вошли в файл .rc(музыка, видео, большие рисунки).
Это уже законченная работа.
Как правило, получается файлов раза в три больше, т.к. срр - не один, а несколько, и к ним в помощь добавляются еще файлы с расширением .h
Функция Paint().
Эта функция имеет три входных параметра:
void Paint(TDC&, bool, TRect&); - из текста определения класса StartWindow.
TDC& - указатель (&) на класс TDC.
bool - булева (всего два значения - да и нет - true и false) переменная, указывающая на перерисовку содержимого окна (по умолчанию - да).
TRect& - указатель(&) на класс ТRect (прямоугольник).
Теперь рассмотрим определение этой функции:
void StartWindow::Paint(TDC& dc, bool, TRect&)
{
dc.TextOut(20, 20, "SerVit Mas")
}
Эта функция не возвращает никакого значения в нашу программу (void), контекст устройства (где будет что-то рисоваться) назван нами dc. Остальные два параметра мы будем использовать по умолчанию (bool - erase, TRect& - не используем).
Теперь необходимо вызывать объекты класса GDI (графического интерфейса пользователя) для того, чтобы что-нибудь отразить на экране. Все функции должны вызываться для объекта dc (в нашем примере) - в данном случае контекста экрана.
Мы выбрали функцию TextOut() для вывода текста. Вот как это выполнено в нашей функции:
dc.TextOut(20, 20, "SerVit Mas");
Пояснение: для объекта dc вызывается функция вывода текста TextOut() в точку с координатами. Координаты:
по X - 20 пикселей,
по Y - 20 пикселей,
выводимый текст - SerVit Mas.
Изменить цвет текста можно используя функцию SetTextColor(TColor), а цвет знакоместа - функцией SetBkColor(TColor). Вот как это может выглядеть:
В определение функции Paint(), перед выводом текста вставим две строчки:
dc.SetTextColor(0, 0, 0);
dc.SetBkColor(255, 0, 0);
Вот как это должно быть:
1. Запускаем Borland IDE (файл bc5\bin\bcw.exe).
2. Открываем новый проект.
3. Устанавливаем статическое подключение библиотек (Static). Выбираем директорию и имя проекта (кнопка "Browse"). Target Expert устанавливает директорию и имя файла по умолчанию.
4. Выбрана папка (директория), имя и тип файла проекта.
5. В поле "Target Type" выбираем тип выходного файла (Application [exe]).
6. Нажимаем кнопку "OK". Target Expert сгенерировал файлы, входящие в проект.
7. Удаляем из проекта файл "Paint.def", т.к. для простых проектов подойдет файл "default.def", который Target Expert подключит самостоятельно.
8. Открываем файл "Paint.cpp" (двойной щелчок левой кнопкой мыши по имени файла в окне) и вводим текст программы.
9. Компилируем программу (нажимаем кнопку "Run").
10. Во время компиляции внизу откроется окно "Message".
11. Готовое окно приложения.
Изменить цвет текста можно используя функцию SetTextColor(TColor), а цвет знакоместа - функцией SetBkColor(TColor). Вот как это может выглядеть:
В определение функции Paint(), перед выводом текста вставим две строчки:
dc.SetTextColor(0, 0, 0);
dc.SetBkColor(255, 0, 0);
Можно изменить цвет окна приложения, вставив функцию SetBkgndColor(TColor) в конструктор главного окна приложения.
Графический интерфейс устройства GDI.
Под графическим интерфейсом устройства GDI скрывается подсистема Windows, отвечающая за работу с графическими объектами. Она непосредственно отвечает за всю работу с графикой и весь внешний облик Windows. Все, что мы видим на экране монитора, все, что выдает принтер, все, что использует графическую информацию, то использует и GDI. Когда говорят о графике под Windows - говорят о GDI.
На системном уровне GDI достаточно сложен, и включает в себя более чем 200 функций. Borland предлагает встроенную поддержку GDI в виде отдельной библиотеки классов, поставляемой вместе с Borland C++ 5.02 - OWL. При этом, использовать OWL значительно проще, чем непосредственно программировать в Win32 API (Application Programming Interface).
Для понимания того, как библиотека OWL обеспечивает поддержку GDI, необходимо знакомство с двумя понятиями:
контекстом устройства;
объектами GDI;
содержит большое количество настраиваемых параметров,
Интегрированная среда разработки Borland C++ 5.02 (IDE) содержит большое количество настраиваемых параметров, но о многих из них не надо беспокоиться, так-как они настроены по умолчанию очень удобно.
Запустите IDE Borland C++ 5.02 (файл bcw.exe).
Первое, что необходимо сделать, так это установить значения каталогов пользователя, в которых будут храниться исходные (Source), промежуточные (Intermedia) и конечные (Final) файлы, которые возникают при разработке программного проекта. Выберите команду меню OPTION>PROJECT.
В появившемся окне "Project Option", в поле "Topics:", выберите пункт "Directories" и задайте значения Source, Intermedia и Final. Проверьте значения Include (включаемые) и Library (библиотечные). Если IDE установлена стандартным способом, то для этих файлов должны быть указаны каталоги …\bc5\include и …\bc5\lib, где … - место установки BC5 (Borland C++ 5.02).
Далее, в пункте меню OPTION>ENVIRONMENT>EDITOR>DISPLAY установите шрифт с русскими буквами (Courier New Cyr) и его размер.
Borland C++ 5.02 предназначен для программирования Windows-приложений с помощью объектно-ориентированной библиотеки OWL (Object Windows Library версия 5.0), входящей в состав инструментального пакета.
Библиотека OWL, как и любая другая объектно-ориентированная библиотека, содержит описания классов для реализации практически всех основных средств Windows (окон, диалогов, органов управления, средств графического интерфейса CGI и т.д.).
Поддержка MFC.
Контекст устройства.
Контекст устройства - это структура данных, в которой содержатся различные графические параметры. По умолчанию они принимают стандартные значения, чтобы сразу после создания контекста его можно было сразу использовать. Например, после создания нами контекста dc мы получили:
белый цвет фона (Brush - кисть);
черный цвет карандаша (Pen - карандаш);
стандартный тип линии (PS_SOLID - непрерывная);
Однако придерживаться стандартных параметров не обязательно. С помощью функций-членов класса TDC мы можем определить свой контекст.
Объекты GDI.
Базовые методы:
MoveTo()
1. MoveTo(10, 10); - перемещает текущую позицию в точку с координатами A(10,10).
2. TPoint p1(10, 10);
MoveTo(p1); - перемещает текущую позицию в точку с координатами A(10,10) с использованием класса TPoint() - точки.
LineTo()
1. LineTo(10, 10); - рисует линию от текущей позиции до точки с координатами A(10,10).
2. TPoint p1(10, 10);
LineTo(p1); - рисует линию от текущей позиции до точки с координатами A(10,10) с использованием класса TPoint() - точки.
Прямоугольники:
Rectangle()
1. dc.Rectangle(10, 10, 100, 100); - рисует прямоугольник между точками с координатами A(10,10) и B(100,100).
2. TPoint p1(10, 10), p2(100, 100);
dc.Rectangle(p1, p2); - рисует прямоугольник между точками с координатами A(10, 10) и B(100, 100) с использованием класса TPoint() - точки.
3. TPoint p1(10, 10);
TSize sz(90, 90);
dc.Rectangle(p1, sz); - рисует прямоугольник между точками с координатами A(10, 10) и B(100, 100) с использованием класса TPoint() - точки и TSize - размера.
4. TRect rect(10, 10, 100, 100);
dc.Rectangle(rect); - рисует прямоугольник между точками с координатами A(10, 10) и B(100, 100) с использованием класса TRect() - прямоугольник.
RoundRect()
1. TPoint p1(10, 10), pRadius(100, 100);
TSize sz(200, 200);
dc.RoundRect(p1, sz, pRadius); - рисует прямоугольник с закругленными углами, лежащий между точками с координатами A(10, 10) и B(210, 210) с использованием класса TPoint() - точки и TSize - размера.
FillRect()
1. TBrush brush(TColor::LtRed);
TRect rect(10, 10, 100, 100);
dc.FillRect(rect, brush); - рисует закрашенный красным цветом прямоугольник между точками с координатами A(10, 10) и B(100, 100) с использованием класса TRect() - прямоугольник и TBrush - кисть.
InvertRect()
1. dc.InvertRect(10, 10, 100, 100); - инвертирует цвета в прямоугольной области между точками с координатами A(10, 10) и B(100, 100).
2. TRect rect(10, 10, 100, 100);
dc.InvertRect(rect); - инвертирует цвета в прямоугольной области между точками с координатами A(10, 10) и B(100, 100) с использованием класса TRect() - прямоугольник.
Окружности:
Ellipse()
1. dc.Ellipse(10, 10, 100, 100); - рисует эллипс, вписанный в прямоугольник, лежащий между точками с координатами A(10, 10) и B(100, 100).
2. TPoint p1(10, 10), p2(100, 100);
dc.Ellipse(p1, p2); - рисует эллипс, вписанный в прямоугольник, лежащий между точками с координатами A(10, 10) и B(100, 100) с использованием класса TPoint() - точки.
4. TRect rect(10, 10, 100, 100);
dc.Ellipse(rect); - рисует эллипс, вписанный в прямоугольник, лежащий между точками с координатами A(10, 10) и B(100, 100) с использованием класса TRect() - прямоугольник.
Arc() - дуга.
1. TRect rect(100, 30, 300, 330);
TPoint p1(350, 45), p2(50, 45);
dc.Arc(rect, p1, p2); - рисует дугу, расположенную между точками C(350, 45) и D(50, 45) и вписанную в прямоугольник, лежащий между точками с координатами A(100, 30) и B(300, 330). Угол изменяется при движении по эллипсу против часовой стрелкию
Методы Chord() (сегмент) и Pie() (сектор) принимают такие же аргументы, имеющие тот же смысл, что и в случае метода Arc(). Сегмент получается из дуги соединением конечных точек, а сектор - соединением конечных точек с центром эллипса. Вывод текста.
1. dc.TextOut(10, 10, "Текст"); - выводит текст в точку с координатами A(10, 10).
2. TPoint p1(10, 10);
dc.TextOut(p1, "Текст"); - выводит текст в точку с координатами A(10, 10) с использованием класса TPoint() - точки.
Другие объекты GDI.
Перья - класс TPen().
Класс TPen имеет шестьразличных конструкторов, принимающих различный набор аргументовю Самая употребительная форма:
TPen(TColor color, int width = 1, int style = PS_SOLID);
Первый параметр - экземпляр объекта TColor, который определяет конкретный цвет. Второй аргумент представляет ширину, а последний стиль.
Ниже перечислены возможные стили:
Перья используются для того, чтобы установить цвет и стиль линий или границ фигур.
Кисти - класс TBrush().
Создание простой кисти:
TBrush(TColor color)
Создание штриховой кисти:
TBrush(TColor color, int style)
В первом случае кисть просто заполняет фигуры указанным цветом.
Во втором - фон заполнится конкретным шаблоном штриховки соответствующего цвета.
Ниже перечислены возможные шаблоны штриховок:
Кисти используются для указания цвета и стиля фонов или заливок.
Общие положения программирования в среде Windows
При запуске приложения Windows управление всегда передается программам Windows, которые загружают в память нашу программу и вызывают из нее главную функцию приложения. Такую функцию имеет любая программа, написанная для Windows. Вызывая эту функцию, Windows передает ей четыре параметра.
Первый параметр (тип HINSTANCE, локальная переменная hInstance) представляет собой дескриптор данного экземпляра приложения. Проще говоря - это идентификационный номер нашего окна (которое мы программируем). Этот дескриптор назначается приложению при его запуске и служит для его идентификации.
Второй параметр (тип HINSTANCE, локальная переменная hPrevInstance) является дескриптором предыдущего экземпляра этого-же приложения и используется только тогда, когда приложение запускается в нескольких экземплярах. Анализ этой переменной позволяет определить, является ли данный экземпляр приложения единственным.
Третий параметр (тип LPSTR) представляет собой указатель на командную строку, содержащую параметры, которые были заданы при запуске приложения из командной строки.
Четвертый параметр (тип int, локальная переменная nCmdShow) характеризует режим запуска приложения (свернуто в иконку, имеет нормальный размер, развернуто на весь зкран).
В типичном Windows-приложении главная функция должна выполнять по меньшей мере три важнейших процедуры:
1. Зарегистрировать в системе Windows класс главного окна. Если помимо главного окна будут выводиться на экран внутренние, порожденные окна, то их классы тоже необходимо зарегистрировать. Windows выводит на экран и обслуживает только зарегистрированные окна.
2. Создать главное окно и показать его на экране. Порожденные окна тоже необходимо создать, но это можно сделать позже и не только в главной функции.
3. Организовать цикл обработки сообщений, поступающих в приложение. Вся дальнейшая работа приложения будет состоять в бесконечном выполнении этого цикла и в обработке поступающих в приложение сообщений до тех пор, пока пользователь не подаст команду его завершения с помощью системного меню или вводом <Alt> + <F4>. Это приводит к завершению работы главной функции и удалению приложения из списка действующих задач Windows.
По моему мнению, Borland C++ (release 5.02), более дружественен начинающему программисту, чем Microsoft Visual C++ (о Borland C++ Builder ничего сказать не могу, к моему стыду - не видел). Фирма Borland оснастила свой компилятор таким количеством прекрасных примеров, что получив только начальные знания о программировании в среде Windows, уже можно вполне прилично научиться программировать в этой среде
Разберем текст программы
Разберем текст программы.
Как мы уже говорили выше (смотри Урок №1), для того чтобы создать полноценное Windows-приложение, необходимо выполнить несколько важнейших и обязательных процедур:
1. Создать сам объект приложения.
2. Зарегистрировать в системе Windows класс главного окна. Если помимо главного окна будут выводиться на экран внутренние, порожденные окна, то их классы тоже необходимо зарегистрировать. Windows выводит на экран и обслуживает только зарегистрированные окна.
3. Создать главное окно и показать его на экране. Порожденные окна тоже необходимо создать, но это можно сделать позже и не только в главной функции.
4. Организовать цикл обработки сообщений, поступающих в приложение. Вся дальнейшая работа приложения будет состоять в бесконечном выполнении этого цикла и в обработке поступающих в приложение сообщений до тех пор, пока пользователь не подаст команду его завершения с помощью системного меню или вводом <Alt> + <F4>. Это приводит к завершению работы главной функции и удалению приложения из списка действующих задач Windows.
Приложения под Windows на любом языке можно создавать несколькими путями:
1. Используя вызовы стандартных функций Windows API (Application Programming Interface - Интерфейс Прикладного Программирования);
2. Используя одну из прикладных библиотек (OWL, MFC);
С Borland C++ 5.02 поставляется библиотека OWL 5.00. Также есть возможность использовать библиотеку MFC (Microsoft Foundation Classes - Базовые Классы Microsoft).
Мы будем рассматривать библиотеку OWL.
Библиотека OWL имеет все возможности для создания любых Windows - приложений. В ее состав входит огромное число классов:
TApplication - для создания объекта-приложения;
TFrameWindow - для создания главного окна;
TWindow - базовый класс окон, также применяется и для создания дочерних окон;
TDecoratedFrame - для создания декорированных окон;
TDialog - для создания диалоговых окон;
TMenu - для создания объекта меню;
TBitmap - для рисунков;
TPen - для кистей для рисования; и много-много других классов.
Мы с Вами хотим создать простое окно, пока не умеющее взаимодействовать с пользователем.Для этого мы должны создать:
1. Объект-приложение (для этого в OWL создан класс TApplication);
2. Главное окно (для этого OWL имеет класс TFrameWindow);
Отсюда следует, что наше с Вами приложение будет иметь в своем составе два класса: производный от TApplication и производный от TFrameWindow.
При программировании на языке С++ необходимо придерживаться правила:
"Используя класс программист обязан сначала объявить, а после определить используемый им класс".
Объявим используемые нами классы:
class StartApp : public TApplication
{
public:
StartApp() : TApplication() {}
void InitMainWindow();
};
Давайте рассмотрим, какой код здесь написан?
В первой строке: class StartApp : public TApplication - Мы хотим, чтобы наш с Вами класс с именем StartApp умел делать все, что умеет делать класс OWL TApplication. (При программировании на языке С++ это звучит так: класс StartApp наследует классу TApplication).
Во второй строке: { - открывающая фигурная скобка обозначает начало класса.
В третьей строке: public: - Обозначает то, что методы (функции) и члены (данные) нашего класса будут общедоступны.
В четвертой строке: StartApp() : TApplication() {} - описан конструктор по умолчанию (о нем мы поговорим позже).
В пятой строке: void InitMainWindow(); - наш класс будет иметь собственную функцию InitMainWindow(), а не ту, которая содержится в классе TApplication.
В шестой строке: }; - закрывающая фигурная скобка обозначает окончание класса, причем ; (точка с запятой) - указывает на то, что это объявление класса.
Так как наше приложение будет использовать класс OWL TApplication, мы обязаны включить в код нашей программы включаемый файл этого класса из этой библиотеки.
Выполнено это в самой первой строке кода нашей программы:
#include <owl\applicat.h>
Теперь мы должны определить класс главного окна.
1. Включаем в код нашей программы включаемый файл класса TFrameWindow из библиотеки OWL. - это сделано во второй строке кода нашей программы:
#include <owl\framewin.h>
2. Объявляем наш класс StartWindow от TFrameWindow из библиотеки OWL:
class StartWindow : public TFrameWindow
{
public:
StartWindow(TWindow *parent, char far *title);
};
Этот код практически повторяет код объявления класса TApplication за исключением того, что выбран конструктор не по умолчанию и мы не будем использовать методы (функции) и члены (данные) в этом классе.
Следующим действием которое нам предстоит сделать, будет определение конструкторов (кроме конструкторов по умолчанию) и методов (функций) классов нашего приложения.
Определим используемые нами классы и методы (функции):
// Конструктор главного окна
StartWindow::StartWindow(TWindow *parent, char far *title)
:TFrameWindow(parent, title)
{
// код конструктора главного окна
}
Первая и вторая строки:
Из класса StartWindow ( StartWindow:: ), конструктор StartWindow ( StartWindow(TWindow *parent, char far *title): ), наследующий классу TFrameWindow(parent, title), передаст своему базовому классу два параметра (TWindow *parent, char far *title). Эти параметры - два объекта класса TWindow и символьная строка char far. Откуда будут взяты эти данные, мы увидим позднее.
Проще говоря, для того чтобы Windows смогла правильно сконструировать программируемое нами окно, необходимо передать в базовый оконный класс TFrameWindow библиотеки OWL, два параметра: parent (номер родительского окна) и title (строку символов, которая будет напечатана в заголовке окна).
Третья строка:
{ - открытие тела конструктора.
Четвертая строка:
// код конструктора главного окна. - Код конструктора указывает системе какое окно мы хотим получить (цвет, размеры, положение окна, наличие системных кнопок, рамки окна, меню, полос прокрутки и т.д.). В этой программе мы не набираем код конструктора. Поэтому Windows сама побеспокоится как будет выглядеть наше окно (она подставит значения по умолчанию).
Пятая строка:
} - закрытие тела конструктора.
Это очень важно!!!
Обратите внимание, что определение
отличается от объявления отсутствием
знака ; после закрытия тела.
После этого нам необходимо определнть метод (функцию) класса StartApp нашего приложения.
Выполнено это следующим образом:
// Функция InitMainWindow класса TStartApp
void StartApp::InitMainWindow()
{
StartWindow *startWnd = new StartWindow(0, "Первое окно");
SetMainWindow(startWnd);
}
Рассмотрим этот код подробнее:
Первая строка:
void StartApp::InitMainWindow()
Функция InitMainWindow(), принадлежащая классу StartApp, не принимающая (внутри круглых скобок не вписаны данные) никаких значений и не выдающая никаких значений (void).
Вторая строка:
{ - открытие тела функции.
Третья строка:
StartWindow *startWnd = new StartWindow(0, "Первое окно");
Объявляется указатель (*startWnd) с именем startWnd на объект класса StartWindow и создается динамический объект (= new StartWindow(0, "Первое окно")) класса StartWindow с параметрами, которые будут переданы в класс TFrame Window библиотеки OWL (0, "Первое окно"). Первый параметр 0 (нуль) - т.к. окно единственное и не имеет родителя. Второй - символьная строка, значение которой мы хотим увидеть в строке заголовка нашего окна.
Четвертая строка:
SetMainWindow(startWnd);
Окно, на которое указывает указатель startWnd, назначается главным окном приложения.
Пятая строка:
} - закрытие тела конструктора.
Последнее, что нам необходимо сделать - это определнть метод (функцию) OwlMain, обязательную функцию для всех Windows-приложений, создающихся с помощью библиотеки OWL.
Вот код этой функции:
// Функция OwlMain()
int OwlMain(int, char*[])
{
return StartApp().Run();
}
Код этой функции практически никогда не изменяется. Она запускает Windows-приложение, используя функцию Run() класса TApplication (через унаследованный класс StartApp).
Программирование. Borland C++ 5.02 Функция Paint() и интерфейс GDI.
Ранее была рассмотрена структура простейшего OWL - приложения с главным окном. Можно было изменять размеры и цвет окна. Но приложение должно каким-то образом взаимодействовать с пользователем - выводить текст и графику на экран. Для этого необходимо обрабатывать сообщение WM_PAINT и использовать инструменты графического интерфейса GDI.
Мы воспользуемся кодом, приведенном в предыдущем примере:
Текст программы:
файл: Start.cpp
#include <owl\applicat.h>
#include <owl\framewin.h>
// Класс приложения
class StartApp : public TApplication
{
public:
StartApp() : TApplication() {}
void InitMainWindow();
};
// Класс главного окна
class StartWindow : public TFrameWindow
{
public:
StartWindow(TWindow *parent, char far *title);
};
// Конструктор главного окна
StartWindow::StartWindow(TWindow *parent, char far *title)
:TFrameWindow(parent, title)
{
// код конструктора главного окна
// расположение и размеры главного окна
Attr.X = 100;
Attr.Y = 150;
Attr.W = 400;
Attr.H = 300;
}
// Функция InitMainWindow класса TStartApp
void StartApp::InitMainWindow()
{
StartWindow *startWnd = new StartWindow(0, "Первое окно");
SetMainWindow(startWnd);
}
// Функция OwlMain()
int OwlMain(int, char*[])
{
return StartApp().Run();
}
Вставляем в конструктор нашего окна функцию Paint(). Для этого:
1. Необходимо объявить функцию Paint() в объявлении класса нашего окна.
2. Необходимо определить функцию Paint() в определении класса нашего окна.
Вот, что должно у Вас получиться:
файл: Start.cpp
#include <owl\applicat.h>
#include <owl\framewin.h>
// Класс приложения
class StartApp : public TApplication
{
public:
StartApp() : TApplication() {}
void InitMainWindow();
};
// Класс главного окна
class StartWindow : public TFrameWindow
{
public:
StartWindow(TWindow *parent, char far *title);
void Paint(TDC&, bool, TRect&);
};
// Конструктор главного окна
StartWindow::StartWindow(TWindow *parent, char far *title)
:TFrameWindow(parent, title)
{
// код конструктора главного окна
// расположение и размеры главного окна
Attr.X = 100;
Attr.Y = 150;
Attr.W = 400;
Attr.H = 300;
}
void StartWindow::Paint(TDC& dc, bool, TRect&)
{
dc.TextOut(20, 20, "SerVit Mas")
}
// Функция InitMainWindow класса TStartApp
void StartApp::InitMainWindow()
{
StartWindow *startWnd = new StartWindow(0, "Первое окно");
SetMainWindow(startWnd);
}
// Функция OwlMain()
int OwlMain(int, char*[])
{
return StartApp().Run();
}
После компиляции и запуска этой программы, на экран будет выведена строка текста "SerVit Mas" в точку с координатами 10, 10 пикселей.
Рассмотрим код этой программы подробнее.Изменения в программе коснулись только того, что в класс нашего главного окна добавлен метод (функция) Paint(). Эта функция замещает открытую виртуальную функцию класса TWindow Paint(). Как произошло это замещение? Очень просто. Класс нашего главного окна приложения StartWindow наследует классу библиотеки OWL TFrameWindow, имеющему в своем составе метод (функцию) Paint(). Поэтому функция Paint() нашего окна унаследовала все возможности функции Paint() класса библиотеки OWL TFrameWindow. Более того, все оконные классы библиотеки OWL (и в частности класс TFrameWindow) наследуют базовому классу библиотеки OWL - TWindow. В связи с этим функция Paint() класса TFrameWindow наследует функции Paint() своего базового класса TWindow. Получилась следующая картина наследования:
функция Paint() класса StartWindow -> функция Paint() класса TFrameWindow -> функция Paint() класса TWindow.
Отсюда следует, что функция нашего класса главного окна StartWindow::Paint() наследует функции TWindow::Paint() - класса TWindow.
Это очень важно!!!
Методы (функции) и переменные базовых
классов можно посмотреть в заголовочных
файлах библиотеки OWL. Они расположены
в дирректории BC5/INCLUDE/OWL.
Например: классу TFrameWindow соответствует
заголовочный файл framewin.h, классу
TApplication - applicat.h и т.д.
Функция Paint() очень важна, она вызывается программами OWL в ответ на приход в окно приложения сообщения WM_PAINT. В нашем примере обработка этого сообщения заключается в выводе в окно с помощью функции TextOut() строки текста.
Программирование. Borland C++ 5.02 Курсоры и пиктограммы.
Мы воспользуемся кодом, приведенном в примере, использующем функцию Paint():
файл: Start.cpp
#include <owl\applicat.h>
#include <owl\framewin.h>
// Класс приложения
class StartApp : public TApplication
{
public:
StartApp() : TApplication() {}
void InitMainWindow();
};
// Класс главного окна
class StartWindow : public TFrameWindow
{
public:
StartWindow(TWindow *parent, char far *title);
void Paint(TDC&, bool, TRect&);
};
// Конструктор главного окна
StartWindow::StartWindow(TWindow *parent, char far *title)
:TFrameWindow(parent, title)
{
// код конструктора главного окна
// расположение и размеры главного окна
Attr.X = 100;
Attr.Y = 150;
Attr.W = 400;
Attr.H = 300;
}
void StartWindow::Paint(TDC& dc, bool, TRect&)
{
dc.TextOut(20, 20, "SerVit Mas")
}
// Функция InitMainWindow класса TStartApp
void StartApp::InitMainWindow()
{
StartWindow *startWnd = new StartWindow(0, "Первое окно");
SetMainWindow(startWnd);
}
// Функция OwlMain()
int OwlMain(int, char*[])
{
return StartApp().Run();
}
Вставляем в конструктор нашего окна функцию GetWindowClass();. Для этого:
1. Необходимо объявить функцию GetWindowClass(); в объявлении класса нашего окна.
2. Необходимо определить функцию GetWindowClass(); в определении класса нашего окна.
3. Необходимо определить дескрипторы пиктограммы и курсора.
4. Необходимо создать рисунки пиктограммы и курсора.
4. Включить рисунки пиктограммы и курсора в файл ресурсов.
Вот, что должно у Вас получиться:
файл: Start.cpp
#include <owl\applicat.h>
#include <owl\framewin.h>
// Глобальные переменные
HICON hIcoh;
HCURSOR hCursor;
// Класс приложения
class StartApp : public TApplication
{
public:
StartApp() : TApplication() {}
void InitMainWindow();
};
// Класс главного окна
class StartWindow : public TFrameWindow
{
public:
StartWindow(TWindow *parent, char far *title);
void GetWindowClass(WNDCLASS&);
void Paint(TDC&, bool, TRect&);
};
// Конструктор главного окна
StartWindow::StartWindow(TWindow *parent, char far *title)
:TFrameWindow(parent, title)
{
// код конструктора главного окна
// расположение и размеры главного окна
Attr.X = 100;
Attr.Y = 150;
Attr.W = 400;
Attr.H = 300;
}
void StartWindow::GetWindowClass(WNDCLASS& wc)
{
TWindow::GetWindowClass(wc);
wc.hIcon=hIcon;
wc.hCursor=hCursor;
}
void StartWindow::Paint(TDC& dc, bool, TRect&)
{
dc.TextOut(20, 20, "SerVit Mas")
}
// Функция InitMainWindow класса TStartApp
void StartApp::InitMainWindow()
{
StartWindow *startWnd = new StartWindow(0, "Курсор");
SetMainWindow(startWnd);
hIcon=LoadIcon("Icon1");
hCursor=LoadCursor("Cursor1");
}
// Функция OwlMain()
int OwlMain(int, char*[])
{
return StartApp().Run();
}
После этого необходимо создать рисунки курсора и пиктограммы и включить их в файл ресурсов. Здесь нам поможет встроенный специализированный редактор ресурсов Resourse Workshop, входящий в состав пакетов Borland C++. Файл с изображением значка должен иметь расширение .ICO, а файл с изображением курсора - .CUR. Открываем Resourse Workshop (меню File\New\Resourse Project).
Появится окно New Resourse Project. Выбираем создаваемый ресурс (в данном случае - курсор). Выбираем Options для изменения задаваемых параметров.
Появится окно New Cursor Project Options. Устанавливаем нужное количество цветов и нажимаем кнопку "OK".
Появится окно файла курсора.
Увеличиваем рисунок.
Даем файлу название.
Рисуем курсор. Сохраняем под именем "cursor1.cur".
Теперь создаем рисунок пиктограммы и сохраняем его под именем "icon1.ico".
Компилируем файл ресурсов, для этого необходимо нажать два раза на файл "paint.rc" в окне проекта (в правом окне) левой кнопкой мыши.
После компиляции увидим состав ресурсов нашего приложения.
Нажав на "+", увидим наш курсор
и пиктограмму.
Теперь необходимо создать идентификаторы курсора и пиктограммы. Для этого один раз кликаем на файл "paint.rc" в окне проекта и выбираем "View" и "Text Edit".
Откроется файл ресурсов для редакции в текстовом виде. Задаем идентификаторы курсора и пиктограммы.
Закрываем файл ресурсов с сохранением.
После компиляции и запуска этой программы, на экран будет выведена строка текста "SerVit Mas" в точку с координатами 10, 10 пикселей, нашим курсором и ...
...иметь собственную пиктограмму.
Рассмотрим код этой программы подробнее. Изменения в программе коснулись только того, что в класс нашего главного окна добавлен метод (функция) GetWindowClass(). Эта функция замещает открытую виртуальную функцию класса TWindow GetWindowClass(). Она предназначена для установки структуры WNDCLASS, устанавливаемой в момент создания окна. Эта структура имеет следующие параметры:
lpszClassName - имя класса окна.
hInstance - дескриптор приложения.
lpfnWndProg - оконная функция главного окна.
hCursor - дескриптор курсора.
hIcon - дескриптор пиктограммы.
hbrBackground - цвет фона окна.
lpszMenuName - имя класса меню.
Для того, чтобы наше приложение имело собственный курсор, пиктограмму или цвет фона, мы должны переопределить структуру WNDCLASS. Если этого не сделать, то все параметры этой структуры загрузятся по умолчанию и наше приложение будет иметь стандартные курсор, пиктограму, цвет фона и т.д.
Посмотрим текст функции GetWindowClass():
void StartWindow::GetWindowClass(WNDCLASS& wc)
{
TWindow::GetWindowClass(wc);
wc.hIcon=hIcon;
wc.hCursor=hCursor;
}
1. Вызываем функцию GetWindowClass() класса TWindow - для установки значений по умолчанию.
2. Заносим в структуру WNDCLASS дескриптор пиктограммы нашего приложения.
3. Заносим в структуру WNDCLASS дескриптор курсора нашего приложения.
Надо обратить внимание на то, что вэтом месте можно изменить цвет фона окна.
Программирование. Borland C++ 5.02 Понятие класса.
1. Самым основным понятием в языке является понятие класса. Раньше он так и назывался - Си с классами. В общем, это по старым понятиям - подпрограммы (ближайшее определение).
Понять его можно попробовать так:
Вы сделали баннер размером 88*31. Я ссылаюсь на Ваш файл, содержащий код этого баннера. Теперь мой класс (из которого пошла ссылка, умеет делать все что и Ваш баннер (это уже два класса - Ваш (класс Баннер) и мой (любое название)). Причем Вы сделали свой баннер так, что я смогу произвольно менять размер, рисунки, кол.рисунков и время (к примеру, вообще-то изменяемых параметров может быть сколько-угодно много). Теперь, когда мне будет нужен любой баннер, я буду пользоваться Вашим классом Баннер.
2. Мы собираемся программировать в Windows. Это оконная система, поэтому мы будем программировать окна, а что будут они делать(рисовать, играть музыку и т.д.) - это уже внутреннее дело окна.
Есть основные категории классов:
1. Приложения(Application) - любая программа в Windows, это приложение.
2. Окна(Windows) - все окна, которые мы видим на экране.
3. Меню(Menus) - строка меню, панели инструментов и т.д.
4. Окна диалога(Dialog boxes) - окна диалога(выбор цвета и т.д.).
5. Элементы управления(Controls) - кнопки, линейки прокрутки.
6. Графика(Graphics).
7. Печать(Printing) - класс, поддерживающий принтеры.
8. Контроль ввода(Validators) - проверяет ввод символов(пароли и т.д.).
9. Просмотр документов(Document and views) - поддерживает модель "Документ/Вид"(на базе этого класса написан Word).
10. Буфер обмена(Clipboard) - передаются данные между приложениями.
Программирование. Borland C++ 5.02 Программирование главного окна.
а). Текст программы:
файл: Start.cpp
#include <owl\applicat.h>
#include <owl\framewin.h>
// Класс приложения
class StartApp : public TApplication
{
public:
StartApp() : TApplication() {}
void InitMainWindow();
};
// Класс главного окна
class StartWindow : public TFrameWindow
{
public:
StartWindow(TWindow *parent, char far *title);
};
// Конструктор главного окна
StartWindow::StartWindow(TWindow *parent, char far *title)
:TFrameWindow(parent, title)
{
// код конструктора главного окна
}
// Функция InitMainWindow класса TStartApp
void StartApp::InitMainWindow()
{
StartWindow *startWnd = new StartWindow(0, "Первое окно");
SetMainWindow(startWnd);
}
// Функция OwlMain()
int OwlMain(int, char*[])
{
return StartApp().Run();
}
Этот файл можно набрать вручную в любом текстовом редакторе, но мы воспользуемся IDE Borland(интегральная среда разработки). Для этого запускаем ее (файл bcw.exe). Входим в меню: File/New/Project.
Нам будет предложено назвать наш новый проект и директория, где будут размещаться файлы проекта. Назовем наш проект Start.
IDE сгенерирует наш новый проект. Этот проект будет иметь имя Start.ide, также будут сгенерированы все необходимые файлы проекта. Выглядеть это будет так:
Как видите, файл проекта с названием Start.ide состоит из трех файлов:
start.cpp
start.def
start.rc
Все три файла будут пустыми. Файл start.cpp - сам код программы. Файл Start.def - файл модуля программы (какая будет использоваться память и т.д.). Файл Start.rc - файл ресурсов программы (рисунки, иконки, курсоры и т.п.).
Нажимаем два раза на файл start.cpp. Будет открыто окно файла start.cpp для набора текста.
Набираем текст файла start.cpp.
Файл start.def в нашем случае можно не писать, а удалить из файла проекта (для таких легких программ его специально писать не требуется), в этом случае компилятор сам подставит в проект находящийся Borland-файл default.def.
В файле Start.rc тоже (пока) ничего писать не надо, он готов (для простых приложений).
Поэтому компилируем приложение, нажимаем кнопочку "RUN" в IDE.
Компьютер некоторое время будет работать, в нижней части IDE появится окно "Message", в котором будут отображаться ошибки, а в результате мы увидим созданный файл Start.exe.
Запустив его мы увидим окно Windows, где в строке заголовка будет написано: Первое окно. Это окно будет обладать всеми характеристиками окон Windows. Его можно будет свернуть, развернуть, спрятать, изменять его размеры и т.д.
Программирование. Borland C++ 5.02 Типы окон.
Типы окон (наиболее часто используемые):
1. Класс TFrameWindow - строка заголовка, меню и рамка.
2. Класс TDecoratedFrame - показано на рисунке(добавлены 2-е панели инструментов и строка состояния).
3. Класс TMDIFrame - приложение, позволяющее открывать одновременно несколько документов.
Существует всего три основных типа окон:
1. Перекрывающиеся (overlapped).
2. Всплывающие (popup).
3. Дочерние (child).
Комбинируя предопределенные биты стиля (имена с префиксом WS_), программист может создавать самые разнообразные объекты (окна).
Предопределенные биты стиля окон Windows:
WS_OVERLAPPED - Создает перекрывающееся окно, имеющее заголовок и рамку.
WS_POPUP - Создает всплывающее окно (не может использоваться совместно с WS_CHILD).
WS_CAPTION - Создает окно, имеющее заголовок и рамку.
WS_BORDER - Создает окно, имеющее рамку без заголовка.
WS_THICKFRAME - Создает окно, имеющее утолщенную рамку, при помощи которой можно изменять размер окна.
WS_SYSMENU - Создает окно, имеющее пиктограмму системного меню в полосе заголовка.
WS_MAXIMIZE - Создает окно в развернутом виде (на весь экран).
WS_MAXIMIZEBOX - Создает окно, имеющее кнопку "развернуть"
WS_MINIMIZE - Создает окно в свернутом виде (в виде пиктограммы).
WS_MINIMIZEBOX - Создает окно, имеющее кнопку "свернуть"
WS_HSCROLL - Создает окно, имеющее горизонтальную линейку прокрутки.
WS_VSCROLL - Создает окно, имеющее вертикальную линейку прокрутки.
WS_VISIBLE - Создает видимое окно.
WS_DISABLED - Создает неактивное окно.
WS_CHILD - Устанавливает дочернее окно.
WS_CLIPCHILDREN - Исключает область, занятую дочерним окном, из области рисования.
WS_CLIPSIBLINGS - Исключает все дочерние окна из своей области рисования.
WS_DLGFRAME - Создает окно, имеющее двойную рамку и не имеющее заголовка.
WS_GROUP - Определяет первый элемент управления группы окон.
WS_TABSTOP - Определяет группу окон, между которыми можно перемещаться с помощью клавиши табуляции "Tab".
Помимо перечисленных стилей в Windows определены также комбинации общеупотребительных стилей:
WS_OVERLAPPEDWINDOW - комбинация стилей WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX и WS_MAXIMIZEBOX.
WS_POPUPDWINDOW - комбинация стилей WS_POPUP, WS_BORDER и WS_SYSMENU.
Дополнительные или расширенные биты стиля окон Windows:
WS_EX_ABSPOSITION -
WS_EX_ACCEPTFILES -
WS_EX_CLIENTEDGE -
WS_EX_CONTEXTHELP -
WS_EX_CONTROLPANEL -
WS_EX_DLGMODALFRAME -
WS_EX_LEFT -
WS_EX_LEFTSCROLLBAR -
WS_EX_LTRREADING -
WS_EX_MDICHILD -
WS_EX_NOPARENTNOTIFY -
WS_EX_RIGHT -
WS_EX_RIGHTSCROLLBAR -
WS_EX_RTLREADING -
WS_EX_SMCAPTION -
WS_EX_STATICEDGE -
WS_EX_TOOLWINDOW -
WS_EX_TOPMOST - Создает окно, располагающееся поверх всех окон.
WS_EX_TRANSPARENT -
WS_EX_WINDOWEDGE -
Программирование. Borland C++ 5.02 Установка атрибутов главного окна приложения.
Итак, мы научились создавать объект приложения на основе OWL-класса TApplication, научились создавать оконный класс на основе класса TFrameWindow, но все равно мы не умеем управлять процессом отображения окна на экране. Наше окно появляется в том месте,которое ему укажет Windows, размеры окна устанавливает тоже Windows. Попробуем это исправить.
Каждый оконный класс библиотеки OWL наследует классу TWindow - общему классу окон и, в частности, наследует переменную Attr, содержащую атрибуты окна. Переменная Attr - это структура типа TWindowAttr, включающая следующие поля:
Члены класса TWindowAttr:
Style DWORD Стиль окна
ExStyle DWORD Расширенный стиль окна
X int X - координата
Y int Y - координата
W int Ширина окна
H int Высота окна
Menu TResId ID (идентификатор) ресурса меню
AccelTable TResId ID ресурса акселератора
Param char far* Информация MDI-окна
Для задания атрибутов окна необходимо только указать соответствующие поля Attr в конструкторе проектируемого окна.
Рассмотрим, как это можно сделать на примере предыдущей программы.
Находим в теле программы определение котструктора класса StartWindow.
// Конструктор главного окна
StartWindow::StartWindow(TWindow *parent, char far *title)
:TFrameWindow(parent, title)
{
// код конструктора главного окна
}
Вставляем в код конструктора следующий код:
Attr.Style &= ~WS_MAXIMIZEBOX;
Attr.Style |= WS_VSCROLL;
Attr.X = 100;
Attr.Y = 150;
Attr.W = 400;
Attr.H = 300;
Вот как это должно выглядеть:
// Конструктор главного окна
StartWindow::StartWindow(TWindow *parent, char far *title)
:TFrameWindow(parent, title)
{
// код конструктора главного окна
// выключить кнопку максимизации
Attr.Style &= ~WS_MAXIMIZEBOX;
// добавить к окну вертикальную линейку прокрутки
Attr.Style |= WS_VSCROLL;
// расположение и размеры главного окна
Attr.X = 100;
Attr.Y = 150;
Attr.W = 400;
Attr.H = 300;
}
Теперь компилируем и запускаем наше окно. Результат практически не отличается от предыдущего, только теперь окно имеет свои координаты, размер и стиль.
Пояснение кода конструктора:
Первая команда в теле конструктора выключает кнопку максимизациии:
Attr.Style &= ~WS_MAXIMIZEBOX;
Окно, производное от TFrameWindow, имеет по умолчанию стиль WS_OVERLAPPEDWINDOW. Окно этого стиля имеет заглавие, системное меню, широкую рамку, кнопки максимизации, минимизации и свертывания.
Для того, чтобы выключить кнопку максимизации, необходимо произвести логическое умножение (&) отрицания (~) WS_MAXIMIZEBOX и Attr.Style.
В следующей строке конструктора к окну с помощью логического сложения ( | ) добавляется вертикальная линейка прокрутки.
Attr.Style |= WS_VSCROLL;
Последнее, что делает конструктор класса StartWindow - задает исходное положение (Attr.X = 100; Attr.Y = 150;) окна на экране и его размеры (Attr.W = 400; - ширина и Attr.H = 300; - высота) в пикселах.
Программирование. Borland C++ 5.02. Вывод растровых изображений.
Для вывода растровых изображений необходимо:
1. Создать указатель на объект в памяти.
2. Загрузить ресурс (растровое изображение).
3. Создать совместимый контекст.
4. Загрузить ресурс.
Для этого примера мы также воспользуемся кодом, приведенном в примере, использующем функцию Paint():
файл: Start.cpp
#include <owl\applicat.h>
#include <owl\framewin.h>
// Класс приложения
class StartApp : public TApplication
{
public:
StartApp() : TApplication() {}
void InitMainWindow();
};
// Класс главного окна
class StartWindow : public TFrameWindow
{
public:
StartWindow(TWindow *parent, char far *title);
void Paint(TDC&, bool, TRect&);
};
// Конструктор главного окна
StartWindow::StartWindow(TWindow *parent, char far *title)
:TFrameWindow(parent, title)
{
// код конструктора главного окна
// расположение и размеры главного окна
Attr.X = 100;
Attr.Y = 150;
Attr.W = 400;
Attr.H = 300;
}
void StartWindow::Paint(TDC& dc, bool, TRect&)
{
dc.TextOut(20, 20, "SerVit Mas")
}
// Функция InitMainWindow класса TStartApp
void StartApp::InitMainWindow()
{
StartWindow *startWnd = new StartWindow(0, "Первое окно");
SetMainWindow(startWnd);
}
// Функция OwlMain()
int OwlMain(int, char*[])
{
return StartApp().Run();
}
Изменения в тексте программы:
1. Вставляем указатель на объект класса TBitmap в объявление класса нашего окна.
2. Вставляем деструктор в объявление класса нашего окна.
3. Загружаем ресурс в конструкторе класса нашего окна.
4. Освобождаем ресурс в деструкторе класса нашего окна.
5. Создаем рисунок.
6. Включаем рисунок в файл ресурсов.
7. Создаем совместимый (с памятью) контекст устройства.
Вот, что должно у Вас получиться:
файл: Start.cpp
#include <owl\applicat.h>
#include <owl\framewin.h>
// Класс приложения
class StartApp : public TApplication
{
public:
StartApp() : TApplication() {}
void InitMainWindow();
};
// Класс главного окна
class StartWindow : public TFrameWindow
{
private:
TBitmap* bitmap;
public:
StartWindow(TWindow *parent, char far *title);
~StartWindow();
void Paint(TDC&, bool, TRect&);
};
// Конструктор главного окна
StartWindow::StartWindow(TWindow *parent, char far *title)
:TFrameWindow(parent, title)
{
// код конструктора главного окна
// расположение и размеры главного окна
Attr.X = 100;
Attr.Y = 150;
Attr.W = 400;
Attr.H = 300;
bitmap = new TBitmap(*GetModule(),"Picture");
}
// Деструктор главного окна
StartWindow::~StartWindow()
{
delete bitmap;
}
void StartWindow::Paint(TDC& dc, bool, TRect&)
{
TMemoryDC memdc(dc);
memdc.SelectObject(*bitmap);
dc.BitBlt(10,80,bitmap->Width(),bitmap->Height(),memdc,0,0,SRCCOPY);
}
// Функция InitMainWindow класса TStartApp
void StartApp::InitMainWindow()
{
StartWindow *startWnd = new StartWindow(0, "Курсор");
SetMainWindow(startWnd);
}
// Функция OwlMain()
int OwlMain(int, char*[])
{
return StartApp().Run();
}
После компиляции программы у Вас получится:
Программирование на С++
На С++ можно создавать приложения как для MS DOS, так и для Windows. Главное отличие языка С от С++ состоит в том, что С - процедурный, а С++ - объектно-ориентированный. Процедурное программирование - последовательный вызов команд-процедур обработки данных, а объектно-ориентированное программирование (ООП) - взаимодействие объектов.
Для Windows можно разрабатывать 16-ти и 32-разрядные приложения (программы). Можно разрабатывать как MS DOS, так и Windows-приложения. Приложение пишется на языке высокого уровня (С, С++, Pascal, Fortran и т.п.), после этого программа компилируется компилятором (компиляция - получение исполняемого файла с расширением exe или com). В настоящее время хорошим компилятором является компилятор фирмы Borland версии 5.02.
В последнее время широко стало применяться визуальное программирование: Microsoft Visual C++ версии 6.00 и Borland C++ Builder.
По крайней мере два первых имеют дружественную IDE (интегрированная среда разработки). Проще говоря - это обычное окно Windows, в котором можно программировать. Оно содержит очень много полезных встроенных утилит, которые значительно ускоряют и упрощают программирование.
Программирование на С++ с помощью компилятора Borland C++ 5.02 и библиотеки OWL 5.00.
Урок 1. Введение в С++. Общие положения программирования в среде Windows.
Урок 2. Интегрированная среда разработки Borland C++ 5.02. Файл проекта.
Урок 3. Программирование. Borland C++ 5.02. Понятие класса. Типы окон. Программирование главного окна.
Урок 4. Программирование. Borland C++ 5.02. Установка атрибутов главного окна приложения. Типы окон, определенных в системе Windows.
Урок 5. Программирование. Borland C++ 5.02. Функция Paint() и интерфейс GDI.
Урок 6. Программирование. Borland C++ 5.02. Курсоры и пиктограммы.
Урок 7. Программирование. Borland C++ 5.02. Вывод растровых изображений.