Разработка прикладных программ для ОС Windows с помощью интегрированных сред Delphi/C++Builder
Первоначальные теоретические знания о функционировании ОС Windows и исследование практических основ создания приложений в системах Delphi/C++Builder. Механизм и основные этапы разработки простых Windows-приложений, основы программирования в нем.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | методичка |
Язык | русский |
Дата добавления | 28.06.2009 |
Размер файла | 813,1 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
- 2 -
Кафедра `Персональные компьютеры и сети'
В.М. Баканов
Разработка прикладных программ для ОС WINDOWS с помощью
интегрированных сред Delphi / C++Builder
Москва
2000
Введение
Известно, что до 5070% времени на создание (с помощью традиционных средств) программного обеспечения (и часто столько же по объему) приходится на разработку интерфейсной части программы (функционирование окон ввода и вывода данных, управление режимами функционирования программы etc). Современные операционные системы (например, ОС WINDOWS, [1]), снабженные графическим интерфейсом и набором стандартных интерфейсных элементов, значительно облегчают нелегкий (и часто неприятный) процесс разработки интерфейса пользователя.
С другой стороны пользователь не отказался бы от механизма, облегчающего рутинную работу по программированию повторяющихся участков кода - таймеров, блоков обращения к базам данных, системам статистической обработки данных и разрешения стандартных математических уравнений, подсистемам сетевого доступа и многих других.
Начало 90-х годов ознаменовалось значительным ростом аппаратных возможностей персональных ЭВМ (ПЭВМ) и, в связи с этим, массовым переходом к использованию оболочки WINDOWS разработки Microsoft Corporation, снабженной дружественным графическим интерфейсом и обладающей возможностью многозадачности. Полное соответствие международным стандартам CUA (Common User Access), огромный набор системных процедур WINDOWS и отсутствие ограничений на создание собственных (концепция DLL-библиотек), возможность доступа к оперативной памяти практически неограниченного объема и многие другие поддерживаемые возможности обусловили применение WINDOWS почти на каждом оснащенном ПЭВМ рабочем месте. Дальнейшее перерастание оболочки WINDOWS'3.1 в полноценную операционную систему WINDOWS'9x/WINDOWS'NT еще более увеличило интерес к ней (не всегда, впрочем, полностью оправданный).
Однако переход к новому поколению программных средств разработки прикладных пользовательских программ значительно (до 35 лет) задержался - программирование под WINDOWS на «старом добром» С (или Pascal'е) более чем нерационально, работа на C++ непроста даже с использованием библиотек классов MFCL (Microsoft Foundation Class Library) фирмы Microsoft Corp. и OWL (Object Windows Library) фирмы Borland. Явно необходим был новый подход к созданию программного продукта уровня разработчика, что позволяло самому широкому классу программистов включиться в бесконечную гонку создания собственных WINDOWS-приложений.
Новый подход действительно был разработан; соответствующие системы были названы RAD (Rapid Application Design - среды быстрой разработки приложений); основа этих систем - соответствующая библиотека классов VCL (Visual Components Library - библиотека визуализируемых классов). Конечно, RAD-системы не появились на пустом месте - одним из их «прародителей» была широко известная библиотека Turbo Vision (имеющаяся в С- и Pascal-вариантах разработки Borland), полностью основанная на плодотворнейших идеях программирования конца 20 века - объектно-ориентированном программировании (ООП). После внедрения Turbo Vision оставался лишь один прямо напрашивающийся шаг - добавление возможностей работы с объектами как с визуальными сущностями именно на этапе проектирования интерфейса - DesignTime (используя естественную для WINDOWS концепцию «перетаскивания» - Drag&Drop), и этот шаг был сделан в основанных на VCL-подходе RAD-системах.
В первом пятилетии 90-х годов приблизительно одновременно появились первые RAD-продукты - Visual Basic и Visual C++ (Microsoft Corp.), Delphi (Borland), Optima C++ и некоторые другие.
С точки зрения автора (давнего приверженца интегрированных сред фирмы Borland), наиболее удобным RAD-пакетом являются системы класса Delphi / C++Builder (http://www.borland.com.ru), обладающая удачным соотношением между сложностью (а значит, и определенной негибкостью при использовании) и широтой набора объектов (как визуальных, так и невизуальных, что как раз и определяет гибкость). Огромным преимуществом интегрированных сред (ИС) Delphi (http://www.borland.com.ru/delphi) и C++Builder (http://www.borland.com.ru/cbuilder) является значительная открытость системы - возможно добавление (и удаление) специфических объектов (в соответствии с требованиями конкретного разработчика - например, разработчика баз данных, специалиста по численному моделированию, создателя малтимедиа-приложений etc); в настоящее время существуют (часто бесплатно распространяемые) сотни мегабайт самых разнообразных объектов, разработанных третьими фирмами и / или независимыми разработчиками. Наличие компилятора с командной строкой в стиле MS-DOS, поставляемые в комплекте EXPERT'ы (аналоги WIZARD'ов фирмы Microsoft Corp.), регулярный выпуск новых версий Delphi делают Delphi не только удобным, но перспективным продуктом разработчика.
Недостатки Delphi - определенная «раздутость» выполняемых файлов (всегда являющаяся оборотной стороной легкости этапа разработки); причем невозможность множественного наследования в базовом для Delphi языке программирования Borland Object Pascal 8.0 практически не ограничивает разработчика.
Весной 1997 году Borland выпустила полностью С-базированную версии RAD / VCL-среды (получившую название Borland C++Builder), что позволило включить в список сегодняшних клиентов фирмы Borland армаду С-программистов. Есть надежды на достаточно быстрое и безболезненное внедрение C++Builder'a в практику разработчиков WINDOWS-приложений (хотя разработчики Borland не славятся эффективными С-компиляторами). Набор (палитра) компонентов C++Builder'a полностью соответствует таковой для Delphi. Последние версии указанных пакетов отличаются мощной поддержкой разработки программных продуктов, предназначенных для эксплуатации в сети InterNet и объектов ActiveX.
В целом семейство интегрированных сред Delphi / C++Builder фирмы Borland столь хороши, что более чем конкурентоспособны с (несколько запоздавшим) пакетом Developer Studio фирмы Microsoft Corp. На грани нового 21 века Borland предложила аналог Delphi для разработки приложений на платформе Linux - интегрированную среду Kylix [14] (http://www.borland.ru/kylix/index.html), существенно расширяющую область применения ПО данной фирмы.
Разработчики пакетов Delphi и C++Builder расширяют ассортимент своих продуктов в иные области информационных технологий
Поддержка Java-ориентированных технологий многоплатформенных приложений - собственноразработанная интегрированная среда JBuilder (http://www.borland.com.ru/jbuilder).
Разработка средств управления и мониторинга объектных распределенных систем Inprise AppCenter (управление объектами технологии CORBA и Enterprise Java Beans (EJB), см. http://www.borland.com.ru/appcenter.
Применение интегрированного комплекса средств Inprise Application Server (IAS) на основе стандартов CORBA и J2EE (http://www.borland.com.ru/appserver).
Внедрения многозвенной архитектуры MIDAS (MulIi-tier Distributed Application Services); данная технология расширяет возможности предложенной ранее Microsoft Corp. технологии DCOM (Distributed Component Object Model) и поддерживается начиная с Delphi 3 и C++Builder 3 (http://www.borland.com.ru/midas).
Таким образом, в данной работе именно система Delphi выбрана базовой для разработки пользовательских WINDOWS-приложений; в соответствующих местах после заголовка абзаца C++Builder будут приведены данные по пакету C++Builder; подробнее о различиях см. также раздел 13.
На WEB-сайте http://imc.misa.ac.ru/pilger_roll автора данной работы можно найти примеры разработок на Delphi и C++Builder, иллюстрирующие некоторые особенности применения указанных ИС.
Введение в возможности Delphi и C++Builder по работе с базами данных приведено в методической разработке «Введение в язык SQL запросов к базам данных» того же автора.
1. Цель работы
Целью работы является дать первоначальные теоретические знания о функционировании ОС WINDOWS и рассмотреть практические основы создания приложений в системах Delphi / C++Builder. После ознакомления с данным методическим руководством (желательно параллельно с работой на ПЭВМ) пользователь сможет разрабатывать простые WINDOWS-приложения; данная основа и постоянная практика позволят программисту стать профессионалом.
Для желающих самостоятельно изучать дополнительную литературу (а это наряду с ежедневной работой на ЭВМ является единственным способом приобрести профессиональные знания) можно рекомендовать литературные источники [1] для ознакомления с идеологией функционирования WINDOWS, [2] для знакомства с объектно-ориентированной версией языка Pascal, источник [3] для освоения малтимедийных возможностей WINDOWS, [4] для изучения функций WINDOWS API, [5,10] для создания приложений с помощью Delphi, [6,7,10] для освоения возможностей Delphi по работе с базами данных, [7] для практики работы с Delphi (в частности, разработки собственных компонентов), [8] как прекрасный справочник по стандартным компонентам Delphi и [9] в качестве руководства для продвинутых Delphi-программистов.
Для ознакомления с версией C++ для C++Builder'a можно рекомендовать работу [11].
2. Модель программирования и концепция многозадачности в операционной системе Windows
Принципиальная разница между программированием на стандартном языке С и программированием в WINDOWS состоит в том, что все программы для WINDOWS разрабатываются на основе понятия передачи сообщений. Каждая программа для WINDOWS имеет цикл ввода сообщений и (для каждого из окон) - свою процедуру обработки сообщений.
Таким образом, сущность программирования в WINDOWS состоит в принятии сообщения (а при необходимости и генерации оного), пересылке его в то окно, для которого оно предназначено, возможно быстрой обработке этого сообщения и возврата к чтению следующего сообщения [1].
Зачем передавать сообщения? Дело в том, что WINDOWS - многозадачная ОС, способная выполнять одновременно несколько программ; при этом ни одна программа не должна захватывать центральный процессор (ЦП) на слишком долгое время (так как это может вызвать ошибки в параллельно выполняемых и чувствительных к замедлению программах). В приоритетных многозадачных ОС (например, UNIX) выполнение программы прерывается по истечению априорно отведенного ей кванта времени (даже если в этот момент заканчивается важная и неотложная операция). В WINDOWS параллельное выполнение не является приоритетным - передача управления от одной задачи к другой производится в явном виде самими этими задачами. WINDOWS функционирует как многозадачная ОС каждый раз, когда прикладная программа анализирует очередь сообщений. Если предназначенных данной программе сообщений не оказывается, WINDOWS начинает искать сообщения для других активных в данный момент программ и передает управление той, для которой сообщение имеется; далее процесс повторяется.
При разработке предназначенной для WINDOWS программы ее необходимо структурировать таким образом, чтобы она могла поддерживать передачу управления по вышеописанной схеме. Если не принять соответствующих мер, внешне корректная вновь созданная программа, возможно, будет работоспособной, но запущенные вместе с ней другие программы сильно рискуют остановиться вовсе (программа монопольно займет ресурсы всей ОС).
Заметим, что вышеприведенный метод реализации многозадачности в WINDOWS носит название кооперативной многозадачности (cooperative multitasking) и является единственным для WINDOWS'3.1; в ОС WINDOWS'9x (и, соответственно, WINDOWS'NT) реализован метод так называемой вытесняющей многозадачности (preemptive multitasking), при этом ОС сама решает, у какой программы отобрать управление и какой его передать (кооперативная многозадачность оставлена в WINDOWS'9x только в целях поддержки 16-битных приложений). Каждое 32-битное приложение в WINDOWS'9x имеет отдельную очередь сообщений и не зависит от того, как другие задачи работают со своими очередями (поэтому ситуация «повисания системы» вследствие слишком редкой проверки очереди сообщений 16-битным приложением теоретически невозможна).
Кроме сказанного, 32-битные приложения в WINDOWS'9x могут использовать особый механизм - многопоточность (multithreading). В принятой для WINDOWS'9x терминологии исполняемое 32-битное приложение называется процессом (process); процесс состоит как минимум из одного потока.
Поток (thread) - часть кода программы, которая может выполняться одновременно с другими частями кода; потоки в пределах одного процесса используют одно адресное пространство, описатели оьъектов и иные общие ресурсы, но имеют отдельные счетчики команд; приоритетностью выполнения потоков (как и процессов) управляет ядро ОС на основе системы приоритетов. Потоки являются средством обеспечения параллельности обработки данных и часто используются для выполнения в программе асинхронных операций (asynchronous operations) - операций, которые могут быть инициализированы в любое время безотносительно к основному течению программы (лежащий на поверхности пример - периодическое сохранение редактируемого документа или опрос устройства пользовательского ввода - например, `мыши' или клавиатуры). Потоки требуют меньших издержек, создаются (и уничтожаются) быстрее процессов (поэтому их иногда называют `дегковесными процессами'). В связи с использованием всеми потоками данного процесса общей памяти (конечно, за исключением индивидуальных стеков и содержимого регистров) обмен данными между ними предельно прост; по этой же причине создание использующего многопоточность приложения требует особой тщательности вследствие возможности случайного `пересечения' по адресному пространству и / или нарушения последовательности операций (например, чтения / записи). ИС Delphi и C++Builder предоставляют родительский класс (в смысле ООП) TThread для реализации потоков [10].
Операционная система с симметричной мультипроцессорной обработкой (symmetric multiprocessing, SMP); такая как WINDOWS'NT, может выполнять на любом процессоре как код пользователя, так и код собственно ОС; при превышении числом потоков числа процессоров поддерживается многозадачность путем разделения времени каждого процессора между всеми ожидающими потоками.
Разработчики WINDOWS'NT ввели понятие волокон (fibers); волокном называется небольшой (`облегченный') поток, планировку которого осуществляет приложение.
2.1 Windows - операционная система, управляемая событиями
WINDOWS генерирует сообщение, когда происходит какое-либо событие или должно быть выполнено действие. Например, при перемещении «мыши» (а это типичное событие) генерируется сообщение, указывающее (в числе других параметров) координаты точки, в которой находится курсор. Таким же образом сама ОС WINDOWS информирует прикладную программу о том, что в меню был выбран определенный пункт (например, 'Прекратить выполнение').
2.2 Понятие о сообщениях windows и их обработке
Все сообщения в WINDOWS строятся в соответствии со строго определенным и компактным форматом. Любители C++ могут заглянуть в файл WINDOWS.H и проанализировать структуру сообщений MSG
/* структура сообщения WINDOWS */
typedef struct tag MSG
{
HWND hwnd;
WORD message;
WORD wParam;
LONG IParam;
DWORD time;
POINT pt;
} MSG;
Первый элемент приведенной структуры указывает на окно, которому предназначено сообщение (каждому окну присвоен уникальный номер - handle, идентифицирующий окно в течение сеанса работы в WINDOWS). Второй элемент сообщения - идентификатор сообщения (начинающийся с символов WM_ идентификатор, см. файл WINDOWS.H). Третий и четвертый элементы (wParam и IParam) несут дополнительную информацию. В элементе time содержится время помещения события в очередь, в pt - координаты «мыши» в этот момент.
Если сообщение порождено входным событием, WINDOWS помещает его в общую для всех прикладных программ системную очередь сообщений. Помимо этого каждая прикладная программа имеет свою собственную очередь сообщений, куда помещаются (минуя системную очередь) сообщения, прямо адресованные конкретной программе.
Сообщения анализируются в цикле, который имеется в каждой написанной для WINDOWS программе. Ниже даны С- и Pascal-варианты указанного цикла.
// С - вариант цикла обработки сообщений
MSG msg; // объявление структуры типа MSG
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
{Pascal - вариант цикла обработки сообщений}
while GetMessage (Message, 0, 0, 0) do
begin
TranslateMessage(Message);
DispatchMessage(Message);
end;
Функция GetMessage ищет (сканируя очередь) сообщение в очереди данной программы. Если сообщений не найдено, анализируется системная очередь, где распознаются поступившие от клавиатуры или «мыши» сообщения; если таковых не оказалось, прикладная программа 'засыпает'. Функция GetMessage приостанавливает выполнение программы до тех пор, пока в очередь сообщений данной программы поступит какое-либо сообщение, далее поступившее первым сообщение извлекается и выполнение программы возобновляется.
Функция GetMessage возвращает значение FALSE, если получено сообщение WM_QUIT, означающее, что программа должна закончить работу.
Функция TranslateMessage обрабатывает только поступившие с клавиатуры сообщения, преобразуя последовательность событий типа «клавиша отпущена / клавиша нажата» в одно из следующих сообщений WM_DEADCHAR, WM_SYSCHAR и WM_SYSDEADCHAR.
Последняя в цикле функция DispatchMessage передает сообщение в окно (реально - связанной с данным окном процедуре обработки сообщений).
В действительности с каждым окном, создаваемым под управлением WINDOWS, связана некоторая функция обработки сообщений, именуемая оконной функцией WinProc. Связывание соответствующей WinProc-функции с заданным окном осуществляется присвоением имени WinProc-функции полю lpfnWndProc структуры типа WNDCLASS, определяющей данное окно, и регистрацией класса окна функцией RegisterClass.
При вызове SendProc или DispatchMessage в действительности вызывается именно функция WinProc (ниже приведен пример данной функции, оформленной как С-функция с Pascal-вызовом); приведенная функция обрабатывает всего два стандартных сообщения WINDOWS - WM_PAINT (перерисовать окно - в данном простейшем случае вывести в окно заданный текст) и WM_DESTROY (уничтожить окно)
LONG FAR PASCAL
WinProg_1 (HWND hWnd, // идентификатор данного окна
WORD msg, // код кообщения
WORD wParam,
LONG lParam)
{
HDC hdc; // дескриптор устройства вывода
PAINTSTRUCT ps; // параметры отображения окна
RECT rect; // размер клиентской области вывода
switch (msg)
{
// ………………………………….
case WM_PAINT: // полность перерисовать окно
hdc=BeginPaint (hWnd, &ps); // взять дескриптор устройства
GetClientRect (hwnd, (LPRECT) &rect); // определить область вывода
DrawText (hdc, (LPSTR) `'Hello, BAKANOV!'', // выдать текст
-1, (LPRECT) &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint (hWnd, &ps); // освободить дескриптор устройства
break;
// ………………………………….
case WM_DESTROY: // уничтожить окно
PostQuitMessage(0);
break;
// обработать другие сообщения Windows
default: // обработчик по умолчанию (обязательная часть)
return DefWindowProc (hWnd, msg, wParam, lParam);
}
return 0L;
} // конец процедуры
Выше было сказано, что каждое WINDOWS-окно имеет (связанную с ним) функцию WinProc. WinProc-функции часто имеют весьма громоздкий вид вследствие перенасыщенности операторами switch/case (иногда вложенными), что затрудняет непосредственную отладку программ. Однако тела case-вариантов в различных (соответствующих разным окнам приложения) WinProc-функциях в основном повторяются. С переходом на ООП-технологию положение сильно упростилось - пишется одна (родительская) базовая функция WinProc, от которой наследуются (с модификацией - обычно заключающейся в дополнении возможностей) соответствующие процедуры для каждого окна.
Важно отметить, что позиция default в списке оператора switch обязательна (при вызове функции DefWindowProc происходит обработка сообщений, не учтенных соответствующими case-вариантами; в большинстве случаев процедура DefWindowProc является пустой - т.е. все неучтенные сообщения `теряются').
2.3 Два способа передачи сообщений
Сообщения может генерировать не только сама система WINDOWS, но и любая из поддерживаемых ею программ (причем отправить сообщение можно как самой себе, так и любой другой активной программе). Для передачи сообщений в окно существуют два различных способа - непрямой (он же отсроченный) и прямой (реализуемые WINDOWS API-функциями PostMessage и SendMessage соответственно, прототипы этих функций в С-транскрипции приведены ниже).
BOOL
PostMessage (HWND hwnd, // дескриптор окна, которому
// передается сообщение
UINT Msg, // собственно сообщение
WPARAM wParam, // первый параметр сообщения
LPARAM lParam); // второй параметр сообщения
Здесь hWnd - идентификатор (дескриптор) окна, которому передается сообщение. При равенстве этого параметра HWND_BROADCAST сообщение передается всем окнам верхнего уровня в системе (включая недоступные, невидимые, перекрытые другими и всплывающие), за исключением дочерних окон. Если этот параметр равен NULL, то сообщение ставится в очередь (если она есть) сообщений текущего процесса. Параметр Msg определяет собственно передаваемое сообщение, параметры wParam и lParam содержат дополнительную информацию (при необходимости). При успехе функция PostMessage возвращает ненулевое значение, при неудаче - нуль (причину ошибки можно установить вызовом функции GetLastError).
LPRESULT
SendMessage (HWND hwnd, // дескриптор окна, которому
// передается сообщение
UINT Msg, // собственно сообщение
WPARAM wParam, // первый параметр сообщения
LPARAM lParam); // второй параметр сообщения
Параметры функции SendMessage в основном идентичны таковым функции PostMessage; возвращаемое функцией значение зависит от вида сообщений.
При непрямой передаче сообщение помещается в очередь окна-адресата; если очередь не пуста, окно получит данное сообщение лишь после обработки всех предыдущих (на что потребно некоторое время).
При прямой передаче происходит обращение непосредственно к процедуре окна, минуя очередь (применяется при необходимости немедленной реакции на сообщение). Например, следующее WINDOWS API-предписание посылает сообщение EM_LINEFROMCHAR компоненту (понятие компонента см. ниже) Memo_1 с целью получения номера первого выделенного в Memo_1 символа
var
LineNumb: Longint; {номер начального символа
выделенного участка текста в Memo_1}
LineNumb:=SendMessage (Memo_1. Handle, EM_LINEFROMCHAR,
Memo_1. SelStart, 0);
В системах C++Builder и Delphi определена (в качестве метода класса TControl) функция Perform, обладающей функциональностью вышеприведенных
int __fastcall Perform (Cardinal Msg,
int WParam,
int LParam);
Например, нижеследующий С-оператор передает сообщение WM_CLOSE форме Form_1
Form_1 -> Perform (WM_CLOSE, 0, 0);
Пользователь имеет возможность определить (в дополнение к предоставляемым WINDOWS) и свои собственные сообщения - значение соответствующего идентификатора должно быть больше величины WM_USER. Например, можно определить пользовательское сообщение WM_BAKANOV_IS_NOT_VERY_STUPID в стиле С как
#define WM_BAKANOV_IS_NOT_VERY_STUPID (WM_USER+Ox13)
Константа WM_USER используется для разграничения зарезервированных для WINDOWS номеров сообщений и частных (определенных пользователем) сообщений. Все возможные номера сообщений разделены на 5 диапазонов
от 0 до WM_USER-1 |
Номера сообщений, используемые WINDOWS |
|
от WM_USER до 0x7FFF |
Номера частных сообщений внутри данного класса оконных компонентов |
|
от 0x8000 до 0xBFFF |
Зарезервированные для будущего использования в WINDOWS номера сообщений |
|
от 0xC000 до 0xFFFF |
Номера, соответствующие строкам сообщений, используемых для обмена между приложениями и зарегистрированным функцией RegisterWindowMessage окном |
|
выше 0xFFF |
Зарезервированные для будущего использования в WINDOWS номера сообщений |
Для объявления пользовательского сообщения следует определить его имя
#define WM_MyMessage WM_USER
и в необходимый момент послать это сообщение
SendMessage (Form1->Handle, WM_MyMessage, 0, iMessage);
здесь iMessage - целое число, являющееся параметром сообщения. Для обработки сообщения в теле адресата должна быть объявлена и реализована соответствующая функция обработки (иначе сообщение будет принято, но не обработано - будет вызван обработчик по умолчанию).
Синтаксис C / C++ требует наличия подобного нижеприведенному исходного кода (в базовом для Delphi языке Object Pascal подобная функциональность реализуется значительно проще, см. ниже)
// модуль U1_Mess_2.h
………….
#define WM_MyMessage WM_USER
………….
class TForm1: public TForm
{
….
private: // User declarations
void __fastcall OnMyPost (TMessage &Message);
public: // User declarations
__fastcall TForm (Tcomponent *Owner);
BEGIN_MESSAGE_MAP
….
MESSAGE_HANDLER (WM_MyMessage, TMessage, OnMyPost)
END_MESSAGE_MAP(TComponent)
};
// -
// модуль U1_Mess_2.cpp
….
void __fastcall TForm1: OnMyPost (TMessage &mess)
{
Label1->Caption = «Получено сообщение + IntToStr (mess.LParam);
}
Таким образом, обработка сообщений в WINDOWS происходит по следующей цепочке
событиеMainWndProcWndProcDispatchобработчик события
Например, С-оператор
PostMessage (Form2->Handle, WM_CLOSE, 0, 0);
передает окну формы Form2 сообщение WM_CLOSE, закрывающее это окно. Оператор
PostMessage (FindWindow(«TForm1», «Приложение_Primer_2»,
WM_CLOSE, 0, 0);
передает аналогичное сообщение окну класса TForm1 с заголовком Приложение_Primer_2 (используя WINDOWS API - функцию FindWindow).
Например, нижеприведенный вызов
SendMessage (Form2->Handle, WM_CLOSE, 0, 0);
передает окну формы Form2 закрывающее это окно сообщение WM_CLOSE. Вызов
SendMessage (FindWindow(«TForm1», «Приложение_Primer_2»,
WM_CLOSE, 0, 0);
передает аналогичное сообщение окну класса TForm1.
Функция PostMessage возвращает управление вызвавшей ее программе, не дожидаясь окончания обработки сообщения (этим она существенно отличается от функции SendMessage, которая возвращает управление вызывающей программе только после окончания обработки сообщения и на это время блокирует пославшее сообщение приложение).
Вышеприведенные данные дают некоторые основы знания о функционировании ОС WINDOWS, в то же время демонстрируя сложность предмета (для заинтересованных в профессиональных знаниях рекомендуется работы [12,411]). Для работающих на MFCL / OWL C++ знание всех тонкостей необходимо, начинающий Delphi-разработчик может и не иметь представления о тонкостях функционирования WINDOWS-программ (хотя серьезная дальнейшая работа в WINDOWS и потребует дополнительных знаний).
Например, в Delphi доступно прямое связывание сообщений WINDOWS с методами-обработчиками (message-handling methods). Прототип соответствующей процедуры-обработчика должен быть объявлен с директивой message, непосредственно за которой следует идентификатор обрабатываемого сообщения
procedure WM_Reaction1 (var Message: TWMSize); message
WM_MOUSEMOVE;
Теперь при генерации сообщения WM_MOUSEMOVE (любое перемещение 'мыши') будет вызвана процедура WM_Reaction_1 (название метода, а также имя и тип единственного описанного с квалификатором var формального параметра в данном случае не имеют значения)
procedure TForm1.WM_Reaction_1 (var Message: TWMSize);
begin
Label_1. Сарtion:='Получено очередное сообщение ' +
'о перемещении мыши…';
end;
Приведенный подход доступен для квалифицированных разработчиков, в большинстве же случаев Delphi / C++Builder - пользователь даже не подозревает о существовании сообщений имея дело только с определенными событиями.
3. Интегрированные среды Delphi / C++Builder
Стартовый файл интегрированной среды (ИС) Delphi называется DELPHI32.EXE (для C++Builder'а файл BCB.EXE) и стартуется стандартными средствами WINDOWS.
При старте ИС создает главное окно, «нависающее» над текущими окнами WINDOWS (см. рис. 1).
На приведенной копии экрана ПЭВМ окно ИС Delphi 4 расположено в виде полоски в верхней части экрана, пользователю доступно горизонтальное меню и линейка кнопок «быстрого» вызова команд, дублирующая команды главного меню.
Кроме непосредственно ИС, в стартовом окне WINDOWS доступны другие компоненты системы Delphi - утилиты, вспомогательные модули и др. ИС Delphi включает все основные компоненты интегрированных сред WINDOWS - текстовый редактор, редактор ресурсов, компилятор, встроенный отладчик, систему настройки самой ИС, систему контекстной помощи и серию вспомогательных утилит.
Внешний вид окон C++Builder'a практически полностью соответствует таковым для Delphi, принципы работы в ИС также подобны. В дальнейшем для сокращения термин `Delphi' будет применяться к обоим интегрированным средам (Delphi и C++Builder), если разница между обоими ИС в данном контексте несущественна.
Рис. 1. Копия экрана дисплея ПЭВМ при загруженной ИС Delphi
3.1 Считывание, сохранение и создание проектов
Считывание (существующего) проекта доступно через главное меню (см. рис. 1) File|Open Project, запись (сохранение) - File|Save Project (здесь и далее вертикальная черта отделяет выбор из горизонтального меню и далее выбор из открывающегося подменю). Изменение имени проекта доступно сохранением его через вариант File|Save Project As…, закрытие проекта (очистка рабочей области ИС) - File|Close Project.
Создание нового проекта инициализируется File|New Project. Новый проект по умолчанию получит имя Project1; Delphi / C++Builder потребует введения реального имени проекта (как и имени каждого модуля) в момент сохранения проекта.
Выход из ИС реализуется выбором File|Exit.
3.2 Основные файлы проекта Delphi
Каждый проект (фактически список необходимых при создании конкретного пользовательского приложения данных - исходных файлов, параметров компиляции etc) состоит из нескольких (иногда нескольких десятков) файлов, причем каждый из них необходим.
Настоятельно рекомендуется для каждого проекта выделять отдельный каталог! Отказ от этого правила неминуемо приведет к полной дезорганизации последующей работы (некоторые файлы разных проектов имеют по умолчанию одинаковые имена).
Главный файл проекта имеет расширение DPR (Delphi Project, для C++Builder расширение BPR), совпадающее с именем проекта имя и содержит список всех необходимых для проекта файлов.
Для каждого окна (формы в терминологии Delphi) создаются минимум два файла - текстовый файл с расширением PAS (содержащий исходный текст модуля на Pascal'е) и двоичный файл с расширением DFM (содержащий иерархическое представление содержащихся в модуле компонент Delphi). Заметим, что DFM-файл может быть просмотрен (и отредактирован - чего, кстати, не следует делать новичкам) в ИС в текстовом виде (как, впрочем, и любой текстовый файл) посредством выполнения File|0pen File, File|Save File, File|Save File As… и File|Close File.
Проект включает в себя (текстовый) файл опций проекта (расширение - DOF) и, возможно, файл (файлы) формата VBX (Visual Basic eXtensions, начиная с Delphi 2.0 файлы VBX не используются, их роль выполняют ОСХ/ActiveX-компоненты).
Ниже приведена диаграмма, иллюстрирующая процесс создания исполняемого файла в системе Delphi.
Файлы форм (*.DFM) |
|||||
Модули (*.PAS) |
Проект (*.DPR) |
Программа (*.EXE) |
|||
OCX/ActiveX - элементы |
Опции проекта (*.DOF) |
Для системы C++Builder объединяющий файл имеет расширение BPR, в проекте присутствуют DFM, CPP, H, RES - файлы. Общего правила «отдельный проект = отдельный каталог» рекомендуется придерживаться неизменно. Вышеприведенный список файлов проекта минимален - в процессе работы над проектом могут требоваться ВМР, DCR, ICO, DSK, HLP и другие файлы.
При перенесении проекта между ПЭВМ следует транспортировать все (за исключением включающих в расширение тильду - волнистую черту - файлов). Заметим, что применяющий компоненты третьих фирм разработчик должен перенести также файлы указанных компонентов и инсталлировать их (при этом модифицируются файлы библиотеки).
C++Builder. В этом случае прототипы функций и описания данных помещаются в файл с расширением Н (который, впрочем, также автоматически модифицируется при проектировании приложения). Н-файл фактически заменяет USES'ы в стиле Delphi.
4. Создание простых Windows-приложений
Создание приложений (пользовательских программ) в среде Delphi не требует знания тысяч тонкостей программирования под WINDOWS (хотя по мере повышения требований и собственной квалификации пользующийся Delphi разработчик неизменно вынужден будет постепенно постигать тонкости WINDOWS-программирования).
Delphi / C++Builder скрывают (инкапсулируют) от пользователя бесконечные тонкости WINDOWS-программирования, позволяя строить приложения «на лету» - буквально в течении минут создавая готовое WINDOWS-приложение.
4.1 Форма - основа разработки приложения в Delphi
Основным интерфейсным элементом в Delphi является форма (Form). С точки зрения WINDOWS форма суть прототип будущего окна WINDOWS. С точки зрения Delphi форма представляет собой присущий любой исполняемой с этой среде программе визуальный компонент, являющийся контейнером (т.е. включающий в себя) другие компоненты, определяющие функциональность данного приложения.
Заметим, что приложение может содержать несколько форм (многооконное приложение), несущих каждая свою функциональную нагрузку и активизируемых / закрываемых в нужный момент.
На рис. 1 приведена копия экрана дисплея, содержащая (в правой части) пустую форму с именем Form1 (форма является принадлежащим к классу TForm Delphi - компонентом). Созданная в проекте первой форма будет являться главной (появляющейся первой) формой приложения.
В принципе содержащий одну форму (и только форму) проект вполне работоспособен и может быть откомпилирован и выполнен (для компиляции следует использовать Compile|Compile или сочетание клавиш Ctrl+F9 или Compile|Build All, для запуска на исполнение Run|Run или F9). При старте такого ЕХЕ-файла на экране дисплея появится пустое, не реагирующая на нажатия клавиш windows-окно, которое, однако можно перемещать по экрану, изменять его размеры, минимизировать, свертывать в иконку и закрывать. Заметим, при этом пользователем не написано ни строки кода!
В левой части рис. 1 видно окно Object Inspector'a (Инспектора Объектов) - инструмента, с помощью которого пользователь устанавливает свойства объектов и назначает (во время разработки программы - DesignTime) методы-обработчики событий. На примере использования Object Inspector'a при проектировании формы рассмотрим особенности его функционирования при конкретизации свойств и методов всех других объектов (Object Inspector вызывается View|Object Inspector или клавишей F11).
В верхней части окна Object Inspector'a имеется выпадающий список (фактическое выпадение происходит при одинарном щелчке «мыши» по расположенной справа вверху кнопке со стрелкой вниз) включенных в данную форму объектов - компонентов Delphi (включая саму форму).
В нижней части окна Object Inspector находятся два ярлычка - переключателя между страницами Properties (свойства) и Events (сообщения), см. рис. 2,3; переключения между ними осуществляется одинарным щелчком «мыши» по соответствующему ярлычку.
Каждая строка окон Properties и Events соответствует конкретному свойству / сообщению соответственно; причем левый (неизменяемый пользователем) столбец содержит имена свойств / сообщений, а правый - задаваемое пользователем значения свойства (для окна Properties) или имени вызываемой при генерации выбранного сообщения процедуры (для окна Events).
Заметим, что в большинстве случаев пользователю нет необходимости вводить какие-либо значения - Delphi предлагает их величины и названия по умолчанию.
4.1.1 Настройка свойств формы
Рассмотрим процесс задания свойств формы (см. рис. 2,3); упомянув только важнейшие из них (пользователь всегда может использовать систему контекстной помощи или литературные источники).
Свойство Borderlcons определяет наличие трех стандартных для WINDOWS кнопок данной формы - biSystemMenu, biMinimize и biMaximizee. Редактирование этих свойств производится выделением строки BorderIcons в окне Properties Инспектора Объектов (выделенная строка изменяет цвет), нажатием правой клавиши «мыши» для появления всплывающего меню и выбора варианта Expand в этом меню (см. рис. 1), после чего в строке BorderIcons расширится (признаком расширяемости строки служит знак плюс в качестве первого символа строки) до трех строк - biSystemMenu, biMinimize и biMaximize; затем появляется возможность установить каждое из этих свойств в TRUE/FALSE (одинарным щелчком «мыши» на появившейся в правой части строки кнопке со стрелкой вниз и выбором соответствующего значения или просто двойным щелчком «мыши» по соответствующей строке). `Свернуть' свойства в строке можно выбором варианта Collapse во всплывающем по нажатию правой клавише «мыши» меню.
Рис. 2. Окно Object Inspector'а в режиме редактирования свойств (Properties) выбранного компонента
Рис. 3. Окно Object Inspector'а в режиме назначения связей событий (Events) и методов-обработчиков дан-ного события для выбранного компонента
Тип рамки формы (окна) задается свойством BorderStyle. По умолчанию это значение установлено в bsSizeable - форма может изменять свой размер. Допустимо указание следующих значений - bsDialog (форма в виде диалоговой панели), bsSingle (тонкая рамка), bsNone (рамка отсутствует).
Свойство Position определяет местоположение формы (при ее первоначальном появлении на экране). По умолчанию используется poDesigned - форма располагается в том месте экрана и имеет те размеры, которые были заданы при ее создании в DesignTime. Возможны иные значения свойства Position - например, poScreenCenter (сохраняется размер DesignTime, но форма располагается в центре экрана) и др.
Свойство WindowState задает начальный способ отображения формы (окна). При WindowState=wsNormal (умолчание) форма отображается с размерами DesignTime, значения wsMaximized и wsMinimized соответствуют расширению формы во весь экран дисплея и свертке окна соответственно (свойство Icon задает иконку, отображаемую при минимизации формы).
Свойство Меnu указывает на компонент типа TMainMenu (стандартная для WINDOWS полоса меню, включающее вложенные меню).
Свойство PopUpMenu указывает на компонент типа TPopUpMenu (вплывающее по нажатию правой клавиши «мыши» меню).
Свойство Name задает пользовательское имя компонента (вместо Form1, Form2, Form3 и т.д. по умолчанию), Caption - появляющийся в верхней части окна текст-заголовок окна, Color позволяет задать цвет формы, Hint - появляющуюся при небольшой задержке курсора «мыши» над некоторым элементом интерфейса строку текста, являющуюся контекстной подсказкой (Hint является аббревиатурой словосочетания `Help Instance', необходимо установить в TRUE свойство ShowHint), HelpContext - задать номер темы помощи при вызове системы контекстной помощи (по клавише F1 во время исполнения программы - RunTime, значение HelpContext=0 отменяет вызов темы помощи для данного компонента), Cursor - определяет форму курсора «мыши» в момент нахождения курсора в пределах данного компонента.
Свойство FormStyle формы определяет тип окна - простое (SDI-окно) или содержащее дочерние окна (mdi-окно, значение свойства для «родительского» окна fsMDIForm, для «дочернего» окна - fsMDIChild). Для функционирования окна «поверх всех» необходимо установить свойство FormStyle=fsStayOnTop.
У каждого компонента Delphi свои свойства, для уяснения которых следует пользоваться системой контекстной помощи и / или внешней документацией (для компонентов третьих фирм).
Важно, что присваивать значения свойствам можно и во время выполнения приложения (RunTime), для этого выполняется простое присваивание типа нижеприведенного
Form1. ShowHint: =TRUE;
Подобные документы
Разработка 32-разрядных приложений Windows с помощью системы виртуального объектно-ориентированного программирования Delphi. Работа с коммуникационными портами. Виртуальное проектирование Windows. Назначение контактов COM порта (разъём DB-9S.).
реферат [32,7 K], добавлен 28.08.2009Основы работы с многооконным графическим пользовательским интерфейсом операционной системы Windows95/NT. Основы работы с прикладными программами Windows и DOS. Разработка простого приложения для Windows при помощи средства разработки приложений DELPHI.
контрольная работа [281,0 K], добавлен 15.01.2009Delphi как среда разработки программ, ориентированных на работу в Windows. Назначение и преимущество использования электронных учебников. Описание возможностей среды Delphi 5 для разработки электронного учебника. Варианты применения служб Internet.
дипломная работа [3,6 M], добавлен 13.07.2011Изучение учебника и справочной подсистемы Windows 95/NT, получение навыков работы с "мышью", манипулирование окнами и значками программ и документов, запуска программ в системе Windows 95/NT. Разработка простого приложения для Windows при помощи Delphi.
контрольная работа [1,1 M], добавлен 15.01.2009Основные приемы работы в среде программирования Delphi. Особенности технологии создания простейших приложений. Работа с компонентами среды разработки приложений. Ввод, редактирование, выбор и вывод информации. Аспекты использования структуры ветвления.
методичка [619,9 K], добавлен 17.11.2011Теоретические основы написания Windows-приложений с использованием библиотеки MFC. Основы программирования под Windows. Проектирование приложений в среде Microsoft Visual C++. Описание логической структуры приложения, его функциональное назначение.
курсовая работа [1,3 M], добавлен 12.12.2011Проектирование, кодирование и отладка службы Windows: "Контроль приложений", осуществляющей контроль набора приложений и управление ими; разработка приложения, управляющего этой службой. Взаимодействие службы и приложения; тестирование и сопровождение.
курсовая работа [1,1 M], добавлен 22.05.2013Использование языка программирования Delphi для записи программ, представляющих собой последовательность инструкций. Классы и директивы в объектно-ориентированном программировании. Разработка демонстрационной программы. Процесс настройки Windows XP.
дипломная работа [917,4 K], добавлен 15.01.2014История создания. Windows 9x/NT. Операционная система Microsoft Windows. Преимущества и недостатки Windows. Некоторые клавиатурные комбинации Windows 9x и NT. Windows XP Professional. Наиболее совершенная защита.
реферат [19,3 K], добавлен 18.07.2004Общая характеристика операционных систем и приложений Windows. Разделение ресурсов, работа с окнами, назначение диска, видов памяти, системы сохранения и передачи данных. История возникновения приложений, их виды и особенности, порядок написания.
курс лекций [321,0 K], добавлен 24.06.2009