Александр Чиртик - Программирование в Delphi. Трюки и эффекты
- Название:Программирование в Delphi. Трюки и эффекты
- Автор:
- Жанр:
- Издательство:Array Издательство «Питер»
- Год:2010
- Город:Санкт-Петербург
- ISBN:978-5-49807-118-3
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Александр Чиртик - Программирование в Delphi. Трюки и эффекты краткое содержание
Программирование в Delphi. Трюки и эффекты - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
К чему это все? Да к тому, что приложения на других языках программирования (в данном случае речь идет о продуктах Microsoft) не менее «тяжеловесны», чем приложения, написанные на Borland Delphi, если при их написании программист пользуется не только API-функциями. Особенно примечателен в этом случае пример исполняемого файла Visual Basic, который, хотя и имеет малый размер, требует наличия библиотеки, размер которой равен около 1,32 Мбайт. Программа на Visual C++ с использованием, например MFC, в которой реализованы классы оболочки над функциями Windows API (правда, не только они), требует наличия нескольких DLL-файлов. Для Microsoft это не проблема, так как операционная система Windows выпускается именно этой компанией, а следовательно, обеспечить переносимость (здесь – работоспособность без установки) приложений, написанных с использованием ее же сред разработки, очень просто – достаточно добавить нужные библиотеки в состав операционной системы.
Что же в таком случае осталось сделать Borland? Дабы не лишать программиста возможности пользоваться библиотеками, реализующими самые полезные классы (VCL и не только), код с реализацией этих самых классов приходится компоновать в один файл с самой программой. Вот и получается, что реализация этих самых классов в EXE-файле может занимать места гораздо больше, чем реализация собственно приложения. Так в данном случае и получилось.
Примечание
Кстати, проект на Visual C++ также можно статически скомпоновать с библиотекой MFC (то есть включить код реализации классов в сам EXE-файл). Таким способом можно добиться независимости приложения от различных библиотек, кроме тех, которые гарантированно поставляются с Windows, но при этом размер EXE-файла рассмотренного выше приложения (в Release-конфигурации) возрастет до 192 Кбайт.
Теперь обратимся к проекту на Delphi. Посмотрим, что записано в файлах Unit1.pas и Project1.dpr. Текст файла Unit1.pas приведен ниже (листинг 2.1).
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
private
{Private declarations}
public
{Public declarations}
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
end.
Обратите внимание на секцию uses. Здесь перечислены девять подключаемых модулей, объявлен собственно класс формы TForm1, а также записана строка, указывающая компилятору на использование файла ресурсов. Все модули, кроме первых двух, – труды компании Borland, облегчающие жизнь простым программистам. Модуль такого же рода используется и в файле Project1.dpr (листинг 2.2).
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas'{Form1};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Теперь обратите внимание на модули Windows и Messages. В первом определены константы, структуры данных, необходимые для работы с функциями Windows API, и, конечно же, объявлены импортируемые из системных библиотек API-функции. В модуле Messages можно найти определения констант и структур, предназначенных для работы с Windows-сообщениями (подробнее об этом смотрите в подразделе «Реакция на сообщения элементов управления» гл. 2 (стр. 66)).
Собственно, этих двух модулей должно хватить для того, чтобы реализовать оконное приложение, использующее, правда, только стандартные функции Windows API и стандартные элементы управления. В листинге 2.3 приведен пример элементарного Windows-приложения. Главное, на что сейчас стоит обратить внимание, – это размер приложения: всего 15 Кбайт.
program WinAPI;
uses
Windows, Messages;
{$R *.res}
begin
MessageBox(0, 'This is a test', 'Little application', MB_OK);
end.
Зачастую полностью отказываться от классов, реализованных Borland, неоправданно, но для чистоты эксперимента в этой главе будут рассмотрены радикальные примеры, построенные на использовании только Windows API.
Создание окна вручную
Раз уж речь зашла о приложениях с оконным интерфейсом, то самое время приступить к его реализации средствами Windows API. Итак, чтобы создать и заставить работать окно приложения, нужно выполнить следующие операции.
1. Зарегистрировать класс окна с использованием функции RegisterClass или RegisterClassEx.
2. Создать экземпляр окна зарегистрированного ранее класса.
3. Организовать обработку сообщений, поступающих в очередь сообщений.
Пример того, как можно организовать регистрацию класса окна, приведен в листинге 2.4.
function RegisterWindow():Boolean;
var
wcx: WNDCLASSEX;
begin
ZeroMemory(Addr(wcx), SizeOf(wcx));
//Формирование информации о классе окна
wcx.cbSize:= SizeOf(wcx);
wcx.hInstance:= GetModuleHandle(nil);
wcx.hIcon:= LoadIcon(0, IDI_ASTERISK); //Стандартный значок
wcx.hIconSm:= wcx.hIcon;
wcx.hCursor:= LoadCursor(0, IDC_ARROW); //Стандартный указатель
wcx.hb rBackground:= GetStockObject(WHITE_BRUSH); //Серый цвет фона
wcx.style:= 0;
//..самые важные параметры
wcx.lpszClassName:= 'MyWindowClass'; //Название класса
wcx.lpfnWndProc:= Addr(WindowFunc); //Адрес функции обработки сообщений
//Регистрация класса окна
RegisterWindow:= RegisterClassEx(wcx) <> 0;
end;
Здесь существенным моментом является обязательное заполнение структуры WNDCLASSEX информацией о классе окна. Наиболее необычной вам должна показаться следующая строка:
wcx.lpfnWndProc:= Addr(WindowFunc); //Адрес функции обработки сообщений
Здесь сохранен адрес функции WindowFunc (листинг 2.5) – обработчика оконных сообщений (называемый также оконной процедурой). После вызова функции RegisterClassEx система запомнит этот адрес и будет вызывать указанную функцию-обработчик каждый раз при необходимости обработать сообщение, пришедшее окну. Код простейшей реализации функции WindowFunc приведен в листинге 2.5.
//Функция обработки сообщений
function WindowFunc(hWnd:HWND; msg:UINT; wParam:WPARAM; lParam:LPARAM):LRESULT; stdcall;
var
ps: PAINTSTRUCT;
begin
case msg of
WM_CLOSE:
if (hWnd = hMainWnd) then
PostQuit Message(0); //При закрытии окна – выход
WM_PAINT:
begin
//Перерисовка содержимого окна
BeginPaint(hWnd, ps);
Text Out(ps.hdc, 10, 10, 'Текст в окне', 12);
EndPaint(hWnd, ps);
end;
else
begin
//Обработка по умолчанию
WindowFunc:= DefWindowProc(hWnd, msg, wParam, lParam);
Exit;
end;
end;
WindowFunc:= S_OK; //Сообщение обработано
end;
В этой функции реализована обработка сообщения WM_PAINT – запроса на перерисовку содержимого окна. Обработка сообщения WM_CLOSE предусмотрена для того, чтобы при закрытии главного окна происходил выход из приложения. Для всех остальных сообщений выполняется обработка по умолчанию.
Обратите особое внимание на прототип этой функции: типы возвращаемых значений, типы параметров и способ вызова функции (stdcall) должны быть именно такими, как в листинге 2.5. Возвращаемое значение зависит от конкретного сообщения. Чаще всего это S_OK (константа, равная 0) в случае успешной обработки сообщения.
Читать дальшеИнтервал:
Закладка: