Borland delphi vcl faq


Содержание

Borland Delphi FAQ

Q-12: Delphi 2 и 3 не отображают русские TTF под Windows NT WorkStation + ServicePack#3

[HKLM\Software\Microsoft\Windows NT\CurrentVersion\FontMapper]
DEFAULT=0xcc (204) вместо 0x00 (Именно DEFAULT, а не (Default) :-)

получше маленько будет.

Q-13: Как включить окошко CPU Window?

Соответственно, для Delphi 3 — Delphi\3.0.

Q-14: Как установить компонент от Delphi одной версии под Delphi другой версии, если имеется только .DCU

————————————————————
Hикак. Фирма Borland всегда поддерживала несовместимость .DCU-файлов между
разными версиями. Ищите исходник или .DCU, скомпилированный для
соответствующей версии Delphi.

Q-15: При возникновении ошибки во время отладки программы машина перезагружается. Что делать?

————————————————————
Снести QEMM. Hачисто. Простое отключение его функций не помогает. Впрочем,
это исправлено в QEMM 9.0.

Q-16: Delphi 4 виснут при запуске. Видеокарта S3 Virge.

Если не помогает, то попробуйте добавить в system.ini:

Можно также попробовать снизить аппратное ускорение или поиграться
количеством цветов, но наиболее кардинальное решение — сменить видеокарту.

Q-17: При работе программ на D1 под Win95 на иконках TBitBtn’ов обнаруживаются странные артефакты

————————————————————
При работе программ на Delphi 1 под Windows 95 в hicolor-режимах на иконках
TBitBtn’ов обнаруживаются странные коричневые артефакты. Как от них
избавиться?

(AB): Залить фон битмапа синим цветом.

Q-18: Можно ли скомпилировать на Delphi 2/3/4 программу, работающую под Windows 3.1?

————————————————————
NP): Hет, но в дистрибутиве с Delphi 2/3/4 поставляется Delphi 1 специально
для этой цели.

Q-19: Куда из Delphi 3 делся модуль для работы с ReportSmith? А мои любимые модули работы с OLE

Q-20: Hе работает передача данных по OLE в русский Excel.

————————————————————
(SM): Дело в том что в VCL твои команды OLE2 передаются Excel’у в русском
контексте (не знаю, как это правильно назвать). Для исправления необходимо
найти в файле OLEAUTO.pas в функции GetIDsOfNames строчку

if Dispatch.GetIDsOfNames(GUID_NULL, @NameRefs, NameCount,
LOCALE_SYSTEM_DEFAULT, DispIDs) <> 0 then

и заменить ее на

if Dispatch.GetIDsOfNames(GUID_NULL, @NameRefs, NameCount,
((LANG_ENGLISH+SUBLANG_DEFAULT*1024)+SORT_DEFAULT* 65536 ), DispIDs) <> 0
then

После этого у меня Excel стал понимать нормальные английские команды :)).
Hеобходимая комбинация для установки английского языка взята из C-шных
хедеров.

Q-21: Как русифицировать сообщения программы?

Ежели кому интересно то на http://members.xoom.com/PolarisSoft/ есть файлы
строковых ресурсов на русском языке для Delphi 3 и Delphi 4.

Q-22: Как во время компиляции модуля определить, под какой версией Delphi она происходит?

Пользуйтесь вот такой таблицей:

* VER80 — Delphi 1
* VER90 — Delphi 2
* VER93 — C++Builder 1
* VER100 — Delphi 3
* VER110 — C++Builder 3
* VER120 — Delphi 4
* VER130 — Delphi 5
* VER140 — Delphi 6

(Sergey Anvarov, 2:5012/27.204)

Q-23: Как сделать так, чтобы программу можно было запустить только в одном экземпляре?

————————————————————
Воспользуйтесь функцией ActivatePrevInstance из библиотеки rxLib. Для
завершения второго экземпляра используйте Application.Terminate.

(AS): Другой вариант: X:\DELPHI2\DEMOS\IPCDEMOS\ipcthrd.pas, функция
IsMonitorRunning().

Q-24: Как мне вывести какое-нибудь окошко с картинкой, пока программа грузится?

Удобно использовать функцию ShowSplashWindow из rxLib.

Q-25: А как поместить свою иконку на taskbar, там где часы и переключатель клавиатуры?

В библиотеке rxLib есть компонент TrxTrayIcon. Заметьте, что для корректного
завершения работы операционной системе вам потребуется обрабатывать
сообщение WM_QUERYENDSESSION.

Borland delphi vcl faq

Изучив основы программирования в среде Delphi, включая даже такую область, как объектно-ориентированный подход, мы подошли к главной цели – вопросу быстрого создания приложений при помощи Delphi IDE и предоставляемых VCL компонент. Но прежде, чем исследовать сами компоненты, разберемся с вопросом их добавления и редактирования, а так же познакомимся поближе с фундаментом для размещения всех остальных компонент – классом TForm.

Работа с визуальным редактором

Когда вы только создаете новый проект в Delphi, вы сразу же получаете не только файл проекта, но и готовое к дальнейшему использованию окно программы. В терминологии Delphi это окно называется формой (form) и представляет собой основу, на которую помещаются все остальные компоненты приложения. Эта форма будет называться Form1, поскольку автоматическое наименование компонент в Delphi производится по принципу «название компонента + порядковый номер». Таким образом, для первого по счету компоненту типа Form мы получим название Form1. Кроме того, для компонент, имеющих текстовые подписи, включая ту же форму, это же название используется для свойства типа Caption или Text.

Чтобы поместить новый элемент интерфейса на поверхность формы, следует выбрать нужный компонент из палитры, щелкнув по нему мышкой, а затем щелкнуть по тому месту на форме, где этот компонент должен находиться по вашему замыслу. Например, если щелкнуть по компоненте Button (кнопка), находящейся на закладке Standard, а затем – по центру формы, то на форме появится кнопка, причем ее левый верхний угол будет, по возможности, находиться как раз в том месте, где был произведен щелчок мышкой (рис. 11.1).

Рис. 11.1. Форма Delphi с помещенной на нее кнопкой

При этом появившийся на форме объект будет заключен в «рамку», обозначенную 8 черными квадратиками по углам и по серединным точкам сторон. Наличие такой рамки на объекте означает, что он в данный момент является выбранным для редактирования, и именно его свойства отображаются в данный момент в окне инспектора объектов.

Впрочем, эта рамка имеет еще одно предназначение: так, если потянуть за квадратик мышкой, то размер компонента будет изменен путем растягивания или сжатия в выбранном направлении. Переместить же компонент, можно просто перетащив его мышкой, подобно тому, как это делается с ярлыками на рабочем столе Windows. При этом «сетка», к которой привязываются компоненты, имеет размер 8 на 8 пикселей. Впрочем, при желании сетку можно перенастроить, или отключить вообще, для чего следует из меню Tools выбрать пункт Environment Options и установить нужные значения в группе Grid Options, находящейся на закладке Designer.

Но вернемся к тому, что можно сделать с компонентой при помощи инспектора объекта. Разумеется, учитывая то, что расположение компоненты на форме – не более, чем визуальное отображение свойств Left и Top, а ее размеры – свойств Height и Width, то, внося изменения в соответствующие поля инспектора объекта, можно добиться максимально точного расположения.

Вместе с тем, если компонент необходимо, скажем, отцентрировать по отношению к форме, или, что еще более актуально – выровнять интервалы между группой компонент, то можно воспользоваться утилитой выравнивания. Для этого следует щелкнуть по компоненте правой клавишей мышки и из контекстного меню выбрать пункт Position > Align, в результате чего откроется окно Alignment (рис. 11.2).

Рис. 11.2. Выравнивание компонент

Выравнивать можно как по горизонтали, так и по вертикали. Допустим, если у нас имеется единственная кнопка, которую мы хотим поместить в центр окна, то следует выбрать пункты Center in window как для горизонтального (Horizontal), так и для вертикального (Vertical) выравнивания.

Теперь рассмотрим вариант, когда следует выровнять сразу несколько объектов. Для этого поместим на форму еще 2 кнопки, в произвольном месте. Затем следует выделить их. Сделать это можно двумя способами. В том случае, если форма пустая, а область, занимаемая нужными компонентами, не содержит других компонент (т.е. как в нашем случае), то достаточно охватить их общей рамкой при помощи мышки, нажав ее левую кнопку в одном углу группы (но не на области компонента), и протянув виртуальный прямоугольник до противоположного угла. Таким образом, все компоненты, попавшие хотя бы одним краем в такой прямоугольник, окажутся выделенными, что будет отмечено 4 серыми квадратиками по углам каждого компонента (рис. 11.3). Альтернативным способом является выбор компонент путем последовательного щелканья по ним мышкой при удерживаемой клавише Shift.

Рис. 11.3. Выбранная группа компонент

Когда выбрано несколько компонент, в инспекторе объектов отображаются только те свойства, которые можно изменить коллективно, для всех выбранных компонент сразу. Но если дело касается центрирования или взаимного выравнивания компонент, то лучше, опять-таки, обратиться к окну выравнивания. Так, чтобы выровнять все кнопки по центру формы по вертикали, а по горизонтали их сделать равноудаленными друг от друга, в окне выравнивания следует отметить Space equally в Horizontal и Center in window – в Vertical. В результате кнопки выстроятся в стройный ряд по середине окна (рис. 11.4).

Рис. 11.4. Группа компонент после выравнивания

С помощью другого инструмента – Size (размер) можно упорядочить размеры у группы элементов. Для вызова диалогового окна Size следует выбрать из контекстного меню пункт Position > Size, после чего можно будет изменять размеры по вертикали и горизонтали, приводя их к наибольшему или наименьшему общему, или же указывая размеры явно, в пикселях. Прочем, последнее можно сделать и из инспектора объектов, задав нужные значения для свойств Height и Width.

В остальном, правка свойств как отдельных компонент, так и их групп, производится путем установки соответствующих значений в окне инспектора объектов. Если при этом свойство отмечено значком «+», то это говорит о том, что оно составное, и для установки всех параметров следует сначала щелкнуть по этому значку, а затем выбрать значения во всех раскрывшихся полях. Что касается допустимых значений полей, то они так же определяются описанием класса данного компонента. При этом инспектор объекта, как правило, просто не допускает установки заведомо недопустимых значений. Так, для свойств булевского типа можно выбрать только True или False, а для полей перечисляемого типа будет приведен список с допустимыми значениями. Кроме того, для тех свойств, которые задаются, скажем, целыми числами, значениями, вы не сможете указать строку или вещественное число. Все это автоматически исключает целый ряд возможных ошибок.

СОВЕТ
Еще раз напомню, что нажатие на клавишу F1 в момент, когда курсор ввода находится на том или ином поле в инспекторе объектов, приводит к вызову справочной информации по данному свойству объекта.

Наконец, открою один маленький секрет: если произвести двойной щелчок по любому полю-списку, то будет выбрано следующее значение. Но если дважды щелкнуть по списку свойства Color, то откроется стандартное для Windows окно выбора цвета. Вместе с тем следует отметить, что такое поведение – открытие дополнительного окна редактирования – типично для тех свойств, которые имеют кнопку с многоточием, например, Font или Hint.

Формы в Delphi

Приложения, создаваемые в среде Delphi, как, впрочем, и любые другие Windows-программы, сосредоточены вокруг форм – окон приложения. К каждой форме в Delphi привязываются 2 файла. Один из них, с типичным для языка Pascal расширением pas, является программным модулем, описывающим класс формы и все ее компоненты. Другой файл, имеющий тип dfm, описывает расположение всех компонент на форме, их свойства, а так же параметры самой формы – т.е. все то, что можно настроить при помощи инспектора объектов. Это сделано, в том числе, с той целью, чтобы не загромождать сам код программы множеством определений различных свойств компонентов, относящихся к визуальному представлению. Файлы, содержащие описание форм и их компонентов, создаются и изменяются в полностью автоматическом режиме, в зависимости от того, какие действия были проделаны в визуальной среде с данной формой.

Тем не менее, посмотреть и даже отредактировать исходный код такого файла можно – для этого достаточно щелкнуть по форме правой клавишей мышки и выбрать из контекстного меню пункт View as text. Это приведет к тому, что окно с формой закроется, а в редактор кода вместо файла с программным кодом будет загружен объектный код, являющийся описанием формы со всеми ее свойствами, объектами и свойствами объектов. Вариант такого кода для формы с расположенной на ней кнопкой можно увидеть на листинге 11.1.

Листинг 11.1. Объектный файл формы

object Form1: TForm1 Left = 192 Top = 114 W TabOrder = 1 end end

Исследовав подобные файлы, можно убедиться, что в них сохраняются все параметры, необходимые визуальному объекту для представления. В частности, в них хранятся размеры, параметры шрифтов, цвета, тексты надписей и т.д. В том случае, если вы назначите какие-либо дополнительные свойства, в том числе обработчики событий, то они так же будут отображены в таком файле.

Что касается возможности правки, то сразу следует отметить, что добавлять новые объекты путем помещения их описания в объектный файл – не лучшая идея. В то же время, использовать правку формы в текстовом виде может быть удобно, например, в том случае, если требуется изменить, скажем, какое-нибудь слово, которое повторяется во многих текстовых подписях на одной форме, или же передвинуть ряд перекрывающих друг друга компонентов, и т.д.


При всем этом следует учитывать, что правка исходного текста должна производиться с максимальной осторожностью, поскольку в том случае, если вы случайно повредите структуру этого файла, то это приведет к невозможности вернуться к визуальному режиму и продолжить работу над программой, содержащей испорченный таким образом модуль. Собственно для того, чтобы вернуться к обычному, визуальному, режиму работы над формой, следует вновь воспользоваться контекстным меню, только на этот раз не формы, а редактора кода, и выбрать из него пункт View As Form, или же нажать Alt+F12.

Что касается другой составляющей формы – файла pas, который мы, собственно и видим в паре с ее визуальным представлением, то в нем хранится описание формы как класса, а так же подпрограмм, типов и переменных, не являющихся частью формы как таковой, но по тем или иным соображениям помещенных в данный файл. Применительно к той же самой форме, содержащей лишь одну простую кнопку, то pas-файл для нее будет выглядеть так, как представлено на листинге 11.2.

Листинг 11.2. Программный файл формы

unit Unit1; interface uses Windows, Messages, SysUtils, Variants, >

Мы видим, что модуль формы в части interface содержит включение целого ряда других модулей из библиотеки VCL, описание класса формы и глобальную переменную, представляющую собой форму как объект во время выполнения программы. В части implementation пока ничего нет, вернее, там имеется лишь ссылка на включение того самого объектного файла, который, с точки зрения Object Pascal, можно считать ни чем иным, как своеобразным конструктором формы.

Класс TForm

Итак, ключевую часть в программном модуле, описывающем то или иное окно приложения, является класс, описывающий это самое окно. Для форм в VCL, подобно другим компонентам, определен специальный класс – TForm. Однако следует учитывать, что на самом деле, класс TForm никогда напрямую не используется в приложениях: вместо него мы всегда будем работать с классами, порожденными на его основе. Дело в том, что формы всегда индивидуальны, ведь окна приложений содержат в себе другие элементы управления которые, в свою очередь, являются ни чем иным, как свойствами класса, описывающего форму. В частности, если вернуться к листингу 11.2, то видно, что форма в нем описывается как класс TForm1, а кнопка (Button1) является свойством этого класса. Если добавить к кнопке обработчик события (например, для OnClick), то этот обработчик автоматически получит имя Button1Click и будет определен как метод класса TForm1.

Разумеется, что при всем этом создаваемый класс, описывающий форму, унаследует все свойства и методы от базового класса TForm, который происходит от класса TCustomForm, добавляя к нему лишь методы, связанные с многооконным интерфейсом (MDI). Класс TCustomForm, в свою очередь, происходит от класса TScrollingWinControl, являющегося прямым потомком уже упоминавшегося ранее класса TWinControl, опять-таки, имеющего по отношению к своему родителю лишь одно глобальное отличие – возможность прокрутки содержимого. Учитывая все вышеизложенное, рассмотрим методы и свойства класса TCustomForm, которые достаточно часто используются применительно к создаваемым классам форм. В частности, среди методов следует отметить такие, как Close, Hide, Show, ShowModal, SetFocus и Release. Так, метод Close закрывает окно формы, но не удаляет ее из памяти. Правда, если это было единственным, или же главным окном приложения, то его закрытие приведет к завершению работы всего приложения.

ПРИМЕЧАНИЕ
Каждое приложение в Windows имеет главное окно. Если окно единственное, то оно и будет главным, в том же случае, когда окон несколько, главным назначается то, которое будет создано первым. Порядок создания окон можно посмотреть на закладке Forms окна свойств проекта (Project > Options), или же непосредственно в файле проекта. При необходимости этот порядок всегда можно изменить.

Методы Show и Hide делают окно видимым и невидимым, соответственно. А метод ShowModal делает окно не только видимым, но и единственным доступным для приложения, закрывая за собой все остальные окна – модальным. Типичный пример модального окна – диалог подтверждения при выходе из программы (рис11.5).

Рис. 11.5. Типичный модальный диалог

Метод SetFocus устанавливает фокус ввода на тот или иной элемент управления, находящийся на форме. Ну и, наконец, метод Release является специализированным деструктором форм, т.е., если для обычных классов используется метод Destroy, а для компонент – Free, то для окон – Release.

Что касается свойств класса TForm, то все они являются унаследованными от родительских классов. Те их них, что принадлежат к еще не рассмотренному нами классу TCustomForm, представлены в таблице 11.1.

Таблица 11.1. Основные свойства класса TCustomForm

Свойство Описание
Active Указывает, имеет ли в данный момент форма фокус ввода
ActiveControl Указывает на компонент, имеющий фокус ввода на форме
BorderIcons Определяет, какие кнопки должны быть на системном заголовке окна. Допустимые значения: biSystemMenu, biMinimize, biMaximize, biHelp
BorderStyle Определяет вид и возможности рамки окна. Допустимые значения: bsNone, bsSingle, bsSizeable, bsDialog, bsToolWindow, bsSizeToolWin
Canvas Предоставляет доступ к холсту окна
ClientHeight Указывает высоту клиентской части окна в пикселях (клиентская область исключает рамки, заголовок, полосы прокрутки и т.д.)
ClientRect Указывает габариты прямоугольника, образующего клиентскую часть окна
ClientWidth Указывает ширину клиентской части окна в пикселях
FormState Указывает на текущее состояние формы. Допустимые значения: fsCreating, fsVisible, fsShowing, fsModal, fsCreatedMDIChild, fsActivated
FormStyle Определяет тип формы. Допустимые значения: fsNormal, fsMDIChild, fsMDIForm, fsStayOnTop
HelpFile Определяет файл справки, предназначенный для данной формы
Icon Определяет иконку формы
Menu Определяет компоненту-главное меню окна
ModalResult Используется для возвращения результата из модальных диалоговых окон
Position Определяет размеры и расположение окна. Допустимые значения: poDesigned, poDefault, poDefaultPosOnly, poDefaultSizeOnly, poScreenCenter, poDesktopCenter, poMainFormCenter, poOwnerFormCenter
Visible Определяет, должно ли окно быть видимым
WindowState Определяет, в каком виде должно появиться окно на экране. Допустимые значения: wsNormal, wsMinimized, wsMaximized

ПРИМЕЧАНИЕ
Все свойства, связанные с отображением и типом формы, в частности, для рассматриваемых кнопок системного меню, а так же BorderStyle, FormStyle, Position, Visible и WindowState, проявляют себя только во время выполнения программы.

Еще одно важное замечание по свойству BorderIcons состоит в том, что на него имеет непосредственное влияние значение свойства BorderStyle. Например, кнопка контекстной справки (biHelp) будет видна только в том случае, если в качестве значения BorderStyle установлено bsDialog. Однако при этом кнопки сворачивания и разворачивания не будут отображены, вне зависимости от того, что установлено для них в свойстве BorderIcons. Ну а если свойство BorderStyle имеет значение bsNone, то вообще не только никаких кнопок, но и самого заголовка окна выведено не будет. В целом эффект установки значений для свойства BorderStyle и его воздействие на некоторые другие свойства формы, рассмотрены в таблице 11.2.

Таблица 11.2. Свойство BorderStyle

Значение Описание Воздействие на другие свойства
bsNone Системный заголовок окна и рамка отсутствуют Установка BorderIcons не имеет смысла
bsSingle Одинарная рамка окна, не позволяющая изменять его размеры Для BorderIcons нельзя установить biHelp
bsSizeable Стандартное изменяемое окно Для BorderIcons нельзя установить biHelp
bsDialog Окно типа диалога. Рамка есть, но изменить размеры окна, свернуть его или развернуть нельзя Для BorderIcons нельзя установить biMinimize и biMaximize. Свойство MainMenu не имеет смысла
bsToolWindow Аналогично bsSingle, но с маленьким заголовком Отображается только кнопка закрытия окна
bsSizeToolWin Аналогично bsSizeable, но с маленьким заголовком Отображается только кнопка закрытия окна

Свойство Position отвечает за то, в каком месте экрана появится окно. Его возможные значения и их описания приведены в таблице 11.3.

Таблица 11.3. Свойство Position

Значение Описание
poDesigned Окно появится на экране в том же месте и при тех же размерах, что во время разработки в среде Delphi
poDefault Размеры и расположение окна определяются операционной системой. При каждом запуске окно будет сдвигаться немного вниз и вправо
poDefaultPosOnly Расположение окна будет определяться операционной системой, а его размеры будут такими же, как во время разработки
poDefaultSizeOnly Размеры окна будет определяться операционной системой, а его расположение будет таким же, как во время разработки
poScreenCenter Размеры окна будут такими же, как при разработке, а его расположение будет выровнено по центру экрана
poDesktopCenter Аналогично psScreenCenter, но для приложений, рассчитанных на несколько экранов, выбор главного монитора не будет произведен
poMainFormCenter Размеры окна будут такими же, как при разработке, а его расположение будет выровнено по центру главного окна приложения. Данное значение используется только для вторичных форм приложения
poOwnerFormCenter Размеры окна будут такими же, как при разработке, а его расположение будет выровнено по центру окна-владельца, задаваемого при помощи свойства Owner

Еще одно свойство, отвечающее за появление окна на экране – WindowState — определяет, в каком состоянии оно должно появиться. При этом данное свойство действует «с оглядкой» на BorderStyle: если при выбранном для BorderStyle значении окно не может быть свернуто или развернуто, то установка соответствующих значений для WindowState так же не возымеет силы.

Наконец, такие свойства, как Active, ActiveControl и FormState, являются доступными только во время выполнения программы и могут быть использованы для определения текущего состояния окна.

Приложения SDI и MDI

При рассмотрении класса TForm мы намеренно опустили ряд свойств и методов, относящихся к многодокументному интерфейсу приложения. Дело в том, что прежде следует разобраться с самими принципами построение интерфейса приложений в ОС Windows.

Исторически сложилось так, что все Windows-приложения классифицируются по двум типам организации оконного интерфейса – SDI (Single Document Interface – однодокументный интерфейс) и MDI (Multiple Document Interface – многодокументный интерфейс). Во времена Windows 3.x Microsoft продвигала многодокументные версии приложений (начиная от диспетчера программ Windows и заканчивая офисными программами, например, Word for Windows). Но с момента появления Windows 95 сначала Microsoft, а затем и другие разработчики стали все чаще склоняться к однодокументной компоновке программ. Судя по всему, это было вызвано тем, что неподготовленному пользователю сложнее разобраться с «окнами в окнах» в стиле MDI. Вместе с тем, оба подхода к организации приложения имеют право на существование, поэтому рассмотрим вопросы организации MDI-приложений.

Итак, программы с однодокументным интерфейсом имеют одно или несколько окон, которые можно перемещать, открывать и закрывать вне зависимости друг от друга. Большинство современных приложений (скажем, Delphi) реализуют SDI-интерфейс: вы можете открыть несколько документов, при этом каждый из них будет находиться в отдельном, вполне самостоятельном окне.

В противоположность такому подходу, приложения с многодокументным интерфейсом имеют одно главное окно, а все остальные документы открываются внутри этого окна. Из примеров такого подхода среди современных программ можно привести, пожалуй, браузер Opera, хотя реализация MDI в последних версиях этого браузера несколько закамуфлирована.

В Delphi поддерживаются оба типа приложений, причем если по умолчанию создаются SDI-программы, то для создания MDI-приложения можно либо использовать заготовку, либо сделать главную (первую) форму приложения MDI-контейнером. Первый способ кажется быстрее: достаточно в меню File > New выбрать пункт Other, а в группе Projects открывшегося окна New Items щелкнуть по MDI Application и выбрать расположение проекта на диске. Результатом будет загрузка в рабочую среду Delphi нового приложения на основе шаблона многодокументного интерфейса, подготовленного специалистами Borland.

В итоге мы получим почти полноценное MDI-приложение, которое умеет создавать новые окна для своих «документов», открывать в них текстовые файлы и закрывать их, а так же упорядоченно размещать все дочерние окна в своей рабочей области (рис. 11.6). Фактически, приложив совсем немного усилий, на основе этой заготовки можно (но, откровенно говоря, вряд ли действительно не нужно!) создать очередной «улучшенный» вариант Блокнота (notepad.exe) на основе многодокументного интерфейса.

Рис. 11.6. Приложение с MDI на основе шаблона Delphi

Другой способ создать MDI-приложение заключается в том, что потребуется установить свойство FormStyle главного окна приложения в fsMDIForm. После этого можно создать еще одну форму (File > New > Form) и для нее установить это же свойство в значение fsMDIChild. Таким образом, первая форма станет главным окном, или MDI-контейнером, а вторая – дочерним окном.

Помимо свойства FormStyle, за реализацию MDI отвечают еще несколько свойств и методов класса TForm. Среди свойств это ActiveMDIChild, указывающее, какое из дочерних окон имеет фокус ввода, MDIChildCount, указывающее на количество открытых дочерних форм, а так же MDIChildren, предоставляющий доступ ко всем дочерним окнам. Последнее свойство представляет собой массив, ссылающийся на все дочерние окна, первое из них имеет индекс 0, а последнее – на единицу меньшее, чем их общее количество (т.е. MDIChildCount-1).

Кроме того, есть еще одно свойство – TileMode, определяющее, каким образом окна должны быть расположены при вызове метода Tile. Это свойство может принимать значения tbHorizontal – для горизонтального размещения, и tbVertical – для вертикального. Сам метод Tile, соответственно, используется для размещения дочерних окон в родительском на основе значения, заданного для свойства TileMode.

Другие методы формы, относящиеся к MDI-приложениям, это ArrangeIcons, Cascade, Next и Previous. Метод ArrangeIcons позволяет упорядочить все свернутые окна так, чтобы они расположились в линии и не перекрывали друг друга. Метод Cascade, наоборот, действует на раскрытые окна: обращение к этому методу расставляет окна каскадом, одно за другим со смещением вниз и влево (см. рис. 11.6). Что касается методов Next и Previous, то они, соответственно, позволяют переключаться к следующему и предыдущему дочернему окну.

При разработке MDI-приложений следует учитывать, что рабочая область главного окна не должна «загромождаться» какими-либо элементами управления. Единственное, что можно на нем разместить – это главное меню и инструментальную панель. Что касается дочерних окон, то на них, наоборот, не желательно иметь ни того, ни другого.

FAQ по Delphi

Вопрос: Как использовать свои курсоры в программе?

const
crZoomIn = 1;
crZoomOut = 2;

Screen.Cursors[crZoomIn] := LoadCursor(hInstance, ‘CURSOR_ZOOMIN’);
Screen.Cursors[crZoomOut] := LoadCursor(hInstance, ‘CURSOR_ZOOMOUT’);

Вопрос: Как правильно создавать компоненты в run-time? Что задавать в качестве параметра Owner при создании компоненты? Как обрабатывать события от созданных компонент, типа нажатий на кнопки?

Ответ: Hачнем с создания.

Сущность свойства Owner в том, что владелец перед смертью уничтожает (через Free) принадлежащие ему объекты. Таким образом, все зависит от того, кому вы хотите доверить уничтожение созданных форм/компонентов. В частности, если вы сами будете этим заниматься, то AOwner может быть, например, nil.

Для того, чтобы созданный компонент появился на экране, надо указать его родителя, заполнив свойство .Parent, например,

Пример кода, обрабатывающего события от свежесозданных компонентов:
type
TForm1 = class(TForm)
< . >
private
< эта процедура будет вызываться при нажатии на кнопку >
procedure ButtonClicked(Sender : TObject);

Вопрос: Как ограничить перемещение курсора мыши какой-либо областью экрана?

Вопрос: Как отловить события создания или удаления файлов другими программами?

Ответ: (Win32:) FindFirstChangeNotification/FindNextChangeNotification/
FindCloseChangeNotification

(Win16:) FileCDR, но она плохо документирована.

Вопрос: Как сделать так, чтобы по Alt-F4 форма не закрывалась, а выдавала запрос на сохранение?

Ответ: Обрабатывать OnCloseQuery.

Вопрос: При работе программ на D1 под Win95 в hicolor-режимах иконки на TBitBtn’ах обнаруживаются странные коричневые артефакты. Как от них избавиться?

Ответ: (AB): Залить фон битмапа синим цветом.

Вопрос: Как работать с registry?

Вопрос: Как получить короткий путь файла если имеется длинный? («c:\Program Files» ==> «c:\progra

Вопрос: Как напрямую работать с портами/памятью из-под Win95/NT?

Под Win95 можно обращаться к портам из ассемблерных вставок. Под NT этот номер не пройдет — скорее всего, придется писать драйвер устройства. RTFM WindowsNT Device Driver Kit.

Вопрос: Как переключать раскладку клавиатуры из своей программы?

Вопрос: Как просматривать HTML в программе?

Ответ: Можно воспользоваться Netscape Navigator или Internet Explorer — они умеют быть OLE-серверами.

(AL): Еще на www.pbear.com лежат THTMLViewer и TFrameViewer.

Вопрос: Как перехватывать клавиши, нажатые в окне другой программы? И вообще, любые события, поступающие другим программам?

Ответ: (AP): SetWindowsHookEx(). Пример использования лежит на www.i-connect.ru/

Вопрос: Как вывести диалог выбора директории?

Ответ: (DS): SelectDirectory, rxLib: TDirectoryEdit.

Вопрос: Hе работает передача данных по OLE в русский Excel.

Ответ: (SM): Дело в том что в VCL твои команды OLE2 передаются Excel’у в русском контексте (не знаю как это правильно назвать). Для исправления необходимо найти в файле OLEAUTO.pas в функции GetIDsOfNames строчку


if Dispatch.GetIDsOfNames(GUID_NULL, @NameRefs, NameCount,
LOCALE_SYSTEM_DEFAULT, DispIDs) <> 0 then

и заменить ее на

if Dispatch.GetIDsOfNames(GUID_NULL, @NameRefs, NameCount,
((LANG_ENGLISH+SUBLANG_DEFAULT*1024)+SORT_DEFAULT* 65536 ),
DispIDs) <> 0 then

После этого у меня Excel стал понимать нормальные английские команды :)).
Hеобходимая комбинация для установки английского языка взята из C-шных хедеров.

Вопрос: Можно ли скомпилировать на Delphi 2/3 программу, работающую под Windows 3.1?

Ответ: (NP): Hет, но на компактах с Delphi 2/3 поставляется Delphi 1 специально для этой цели.

Вопрос: Как вызывать из 32-битной программы 16-битные DLL?

Ответ: (EM): Hадо применять так называемы Thunks. Смотри статью на http://www.itecuk.com/delmag/thunk95.htm

Вопрос: Почему у меня record a : word; b : longint end; имеет размер восемь байт вместо шести?

Ответ: RTFM packed, $A.

Вопрос: Где взять подробную документацию по работе с RTF, TRichEdit?

Ответ: (MC): www.microsoft.com/msdn, зарегистрироваться и искать.

Вопрос: Как можно перетаскивать форму не только за заголовок?

Вопрос: Как мне упаковать Paradox или DBF таблицу?

Ответ: (AY): Самый простой метод — воспользоваться функцией PackTable из rxLib.
В версии 2.32 и, наверное, раньше, есть ошибка в процедуре PackTable:
измените кусок:

(JB): Для перегенерации индексов:
Table1.Exclusive := True;
Table1.Open;
Check(dbiRegenIndexes(Table1.Handle);

Вопрос: Почему при добавлении/изменении записей в некоторых запросах возникает ошибка Cannot modify a read-only dataset?

Ответ: Во-первых, должно быть RequestLive := True; во-вторых, чтобы запрос был редактируемым, он должен удовлетворять требованиям, изложенным в хелпе при поиске по «live result sets»

Вопрос: Database Desktop показывает содержимое таблиц шрифтом без русских букв. Что делать?

Ответ: Для DBD 5.0 в файл c:\windows\pdoxwin.ini вставить в секцию [Properties]

Если файла не существует, то его надо создать, если секции не существует, то ее надо создать.

(AY): Для DBD 7.0 нужно испpавить pеестp: ключ
HKCU\Software\Borland\DBD\7.0\Preferences\Properties\SystemFont=»Arial Cyr»

NB: Работает не у всех и не всегда. Разбираться ломы. Я лично использую rxDatabaseExplorer.

Вопрос: Почему не работает сортировка и функция UPPER() в Interbase’овской базе данных?

Ответ: Смотри в F.A.Q. по Borland Interbase от демо-центра вопрос 1.1.

Вопрос: Hе получается вставить в таблицу записи со строками на русском языке — некоторые буквы меняются на другие — что делать?

Ответ: В Database Desktop поставьте правильный Language Driver у таблицы, например, Pdox ANSI Cyrr.

Вопрос: Я переписал готовую программу на машину заказчика, а она там не запускается — говорит «Error initializing database engine». Что делать?

Ответ: Прочитать X:\DELPHI\DOC\deploy.txt.

Вопрос: Помню еще один хороший частый вопрос про коннект к Personal Oracle, но не помню ответа на него. Hапомните?

Ответ: (IS): user/password@2:
Это так для Oracle SQL Plus, и более других его утилит. А в BDE надо оставить все как для коннекта к сетевому серверу, (протокол TNS, имя юзера, кодировку, интерфейсную DLL) только вместо имени сервера написать «2:». Сие годится и для случая когда на одной машине и сетевой сервер и приложение.

Вопрос: Hе получается открыть таблицу, созданную в InterBase с DEFAULT CHARACTER SET WIN1251. Оно говорит, что «WIN1251 undefined».

Ответ: (AA): Ставьте Interbase в каталог с путем, соответствующим DOS-овским соглашениям (8:3).

Вопрос: У меня в программе происходит очень большой запрос — в районе нескольких тысяч или десятков тысяч записей. Соответственно большой сетевой трафик, программа тормозит и так далее. Можно ли как-нибудь оптимизировать это все?

Ответ: Постарайтесь изменить логику приложения так, чтобы таких запросов не возникало. Обычно подобные вещи свидетельствуют о несколько неверной архитектуре приложения.

Вопрос: Подскажите хорошую литературу по базам данных.

Ответ: 1) Мартин Грубер «Понимание SQL» (highly recommended)
2) Мартин Грубер «SQL: справочное руководство» (recommended)

Вопрос: WindowsNT 4.0 + Delphi 2.01 C/S + Oracle Client 7.3 + Oracle Server 7.3. После логина в базу данных возникает «EExternalError 0xC0000008». Что делать?

Ответ: (IA): (SK): Снести Oracle Trace Collection Services.

Вопрос: После работы программы не сохраняются изменения в базе Paradox. Что делать?

Ответ: Где-нибудь при закрытии главной формы выполните нижеследующие куски кода:

(SB, AS): Для Delphi 3: Table.FlushBuffers при открытой таблице.

Для прочих: Table.Open; Check(dbiSaveChanges(Table.Handle)); Table.Close;

(BP): Чтобы сбросить кэш, можно еще в после этого сделать
asm
mov ah, $0D
int $21
end;

Вопрос: А как включить окошко CPU Window?

Ответ: (AP): Вставьте в registry строковый ключ
HKCU\Software\Borland\Delphi\2.0\Debugging\EnableCPU=1
соответственно для Delphi 3 — Delphi\3.0.

Вопрос: А как печатать на матричном принтере в текстовом режиме для скорости?

var
f : textfile;
begin
AssignFile ( f, ‘prn’ );
Rewrite ( f );
WriteLn ( f, ‘some data’ );
CloseFile ( f );
end.

NB: Hе забудьте, что слать данные надо в 866 кодовой странице. См. ниже.

Вопрос: Посоветуйте хорошую книгу по Delphi.

Ответ:

  1. Кен Хендриксон «Руководство разработчика баз данных»
  2. Рэй Конопка «Hаписание оригинальных компонент в среде Delphi»
  3. Рэй Лишнер «Секреты Delphi 2»
  4. Том Сван «Програмирование в Delphi для Windows95»
  5. Tом Сван «Секреты 32 разрядного программирования в Delphi»
  6. Джеффри Рихтер «Windows для профессионалов» (highly recommended!)
  7. Т. Миллер, «Использование Delphi 3»

Вопрос: Как сделать плавно изменяющийся цвет заголовка окна, как в MSOffice’95?

Ответ: Hадо ловить сообщение WM_NCPAINT. Существует также компонент CustomNC by Alex Prilipko 2:5045/29, которые позволяет самому рисовать всю неклиентскую часть окна.

(AP): Тот компонент — плохой. Совсем. Правильный компонент, by Акжан Абдулин и еще кто-то был в фэхе(не WDEVDELPHI). Ищите cap*.zip.

NB: cap030.zip и cap031p.zip были в файлэхе FED32SRC.

Вопрос: Как мне перекодировать строки из Win-кодировки в Dos-кодировку и наоборот?

Ответ: CharToOEM/OEMToChar, CharToOEMBuff/OEMToCharBuff.

Вопрос: Как работать с архивными файлами, хотя бы с самыми распространенными, типа .ZIP?

Ответ: (AS): Воспользуйтесь библиотекой ExceedZip 3.0 (www.exceedsoft.com)

(VS): Hа CDROM с Delphi3 есть каталог INFO\EXTRAS\ZLIB. Подробности на http://quest.jpl.nasa.gov/zlib/

Вопрос: Как правильно закрыть и удалить форму? Почему моя MDI Child форма при закрывании просто минимизируется?

Ответ: Обрабатывайте событие OnClose для формы и выставляйте в нем параметр Action в caFree. Дело в том, что его значение по умолчанию для MDI Child форм =caMinimize. Кстати, если сделать Action := caNone, то форму нельзя будет закрыть.

Вопрос: Мне надо добавить много строк в TListbox или в TCombobox или в TMemo или в TRichEdit, при этом сам объект постоянно мигает, перерисовываясь. Как избавиться от этого?

Вопрос: Как исправить проблемы с вызовом помощи при одновременно стоящих Delphi 1 и Delphi2?


Ответ: (AP): Решаются так.

RegEdit — убейте из секции HKLM\SOFTWARE\Microsoft\Windows\Help все, что
равно «. \help».

Поправьте это, чтобы был _ваши_ пути.
————————— HelpPath.REG
REGEDIT4

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppPaths\
delphi32.exe] @=»C:\\DELPHI2\\BIN\\delphi32.exe» «Path»=»C:\\DELPHI2\\HELP»
—————————
. и скажите «START HelpPath.REG»:

Вопрос: Что такое rxLib?

Ответ: Одна из самых, если не самая лучшая библиотека общего назначения для Delphi. Огромное количество компонентов и полезных функций. Полные исходные тексты. Совместима со всеми Delphi (1, 2 и 3), а также с C++-Builder. Великолепные примеры использования. Исчерпывающие файлы помощи на русском языке. Текущая версия — 2.40.

IMHO — a must have для любого дельфиста. Прежде чем огорчаться отсутствием чего-либо или пытаться написать свое — посмотрите, нет ли этого в rxLib. Скажем так — без rxLib мое программирование на Delphi будет гораздо более утомительным.

Авторы:
Fedor Koshevnikov (kosh@masterbank.msk.ru)
Igor Pavluk (pavluk@masterbank.msk.ru)
Serge Korolev (korolev@masterbank.msk.ru)

Вопрос: Как мне запрограммировать непрямоугольную форму, например, как у Norton CrashGuard, в форме щита?

Ответ: (ArAs): SetWindowRgn(); (только Win32).

(AV): Есть компонент TFormShaper, free for noncommercial use:
http://www.wirtschaft.tu-ilmenau.de/

(AM:) (Win32) Пример кода, создающий эллиптическую форму, которую к тому же можно двигать за любую точку, что демонстрирует обработку сообщения WM_NCHITTEST:

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TForm1 = class(TForm)
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
< Private declarations >
rgn : HRGN;
procedure WMNCHitTest(var Message : TWMNCHitTest); message WM_NCHITTEST;
protected

var
Form1: TForm1;

procedure TForm1.FormCreate(Sender: TObject);
begin
rgn := CreateEllipticRgn(0, 0, Width, Height);
SetWindowRgn(Handle, rgn, True);
end;

procedure TForm1.WMNCHitTest(var Message : TWMNCHitTest);
begin
if PtInRegion(rgn, Message.XPos, Message.YPos) then
Message.Result := HTCAPTION
else
Message.Result := HTNOWHERE;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
DeleteObject(rgn);
end;

(DK:) Hадо задать форме стиль окна WS_EX_TRANSPARENT. Тогда будут рисоваться только лежащие на ней контролы.
Вот пример кода:

type
TForm1 = class(TForm)
< . >
protected
procedure CreateParams(var Params : TCreateParams); override;
end;

procedure TForm1.CreateParams(var Params : TCreateParams);
begin
inherited CreateParams(Params);
< форма становится прозрачной >
Params.ExStyle := Params.ExStyle or WS_EX_TRANSPARENT;
end;

Вопрос: Delphi 2 & 3 не отображают русские TTF под Windows NT WorkStation + ServicePack#3.

Ответ: (AlPe): Попробуй сделать
[HKLM\Software\Microsoft\Windows NT\CurrentVersion\FontMapper]
DEFAULT=0xcc (204) вместо 0x00 (Именно DEFAULT, а не (Default):-) получше маленько будет.

Вопрос: Как установить компонент от Delphi 2 под Delphi 3? Delphi требуют .PAS-файл.

Ответ: Hикак. Ищите исходник или .DCU, скомпилированный для Delphi 3.

Вопрос: Как получить от программы сообщения на русском языке?

Ответ: (EL):

  1. В X:\Delphi\Sources\vcl — отредактировать все файлы текстовых ресурсов Delphi (или наиболее часто возникающие Exception’ы и надписи на кнопках).
  2. В Delphi\bin есть компилятор текстовых ресурсов (brcc32.exe — точно не помню).Откомпилировать все изменненные *.rc.
  3. Получившиеся res-файлы кинуть в Delphi\Lib

(SB): Для Delphi 3:

  1. Delphi3\Doc\Consts.int переименовать в Delphi3\Doc\Consts.pas;
  2. внутри Consts.pas в конце дописать: «end.»;
  3. внутри Consts.pas исправить все «Yes», «No», «Cancel» и т. д. на русский вариант;
  4. откомпилировать consts.pas с помощью dcc32, получится Consts.dcu.
  5. Consts.dcu скопировать в Delphi 3\Lib вместо имеющегося там.

NB: Русские ресурсы для D1 и D2 проходили в свое время по WDEVDELPHI в файле .

Вопрос: Как работать с разными графическими форматами, кроме BMP, хотя бы самыми распространенными: GIF, JPG, TIFF?

Ответ: Воспользуйтесь библиотекой ImageLib. Лежит на www.imagelib.com.
Hа компакте с Delphi 3 в каталоге EXTRAS есть библиотека JPEG. Если сказать в модуле uses jpeg; то можно работать с .jpg как с TPicture.

(AA): Опять-таки, есть LightLib Images (url не помню, но по altavista находится с полпинка, поставляется с книжкой Чарлза Калверта).

Вопрос: Куда из Delphi 3 делся модуль для работы с ReportSmith? А мои любимые модули работы с OLE: ole2, oleauto и olectl?

Ответ: Они лежат в X:\DELPHI3\LIB\DELPHI2\.

Вопрос: Моя программа довольно долго делает какую-то полезную работу, типа чтения дерева каталогов или обильных вычислений, и в этот момент почти не работают остальные программы. Как разрешить им это делать?

(AA): Win32: Если вы хотите отдавать timeslices в нитях, пользуйтесь Sleep(0); это отдаст остаток слайса системе. Win16: Если вы хотите разрешить отработку сообщений другим программам, но не вашей, то лучше пользоваться Yield().

Вопрос: Как мне вывести какое-нибудь окошко с картинкой, пока программа грузится?

Ответ: Смотрите пример в X:\DELPHI\DEMOS\DB\MASTAPP\mastapp.dpr.

Удобно использовать функцию ShowSplashWindow из rxLib.

Вопрос: Как мне запустить какую-нибудь программу? А как подождать, пока эта программа не отработает? Как выяснить, работает ли программа или уже завершилась? Как принудительно закрыть выполняющуюся программу?

Ответ: WinExec() или ShellExecute. У второй больше возможностей.

(AY, VB): CreateProcess().

(SO): CreateProcess() в параметре process info возвращает handle запущенного процесса. Вот и делаешь WaitForSingleObject(pi.hProcess, INFINITE);

(AA): Win16: Delay можно взять из rxLib.

Вопрос: Как мне работать с файлами MS Word или таблицами Excel?

Ответ: Воспользоваться функцией CreateOLEObject и работать с VBA или WordBasic.

NB: Обратите внимание на то, как устанавливаются именованные параметры у процедур WordBasic’а, например, FileOpen(Name := ‘myname.doc’);

Пример проверен только на Word 7.0 (рус) . Вот, может поможет.

unit InWord;
interface
uses
. ComCtrls; // Delphi3
. OLEAuto; // Delphi2
[skip]
procedure TPrintForm.MPrintClick(Sender: TObject);
var W: Variant;
S: String;
begin
S:=VarToStr(Table1[‘Num’]); //В D3 без промежуточной записи
// в var у меня не пошло :(
try // А вдруг где ошибка :)
W:=CreateOleObject(‘Word.Basic’);
// Создаем документ по шаблону MyWordDot
// с указанием пути если он не в папке шаблонов Word
W.FileNew(Template:=’C:\MyPath\DB\MyWordDot’,NewTemplate:=0);
// Отключение фоновой печати (на LJ5L без этого был пустой лист)
W.ToolsOptionsPrint(Background:=0);

// Переходим к закладке Word’a ‘Num’
W.EditGoto(‘Num’); W.Insert(S);
//Сохранение
W.FileSaveAs(‘C:\MayPath\Reports\MyReport’)
W.FilePrint(NumCopies:=’2′); // Печать 2-х копий
finally
W.ToolsOptionsPrint(Background:=1);
W:=UnAssigned;
end;
end;
.

Вопрос: Как сделать так, чтобы запущенная программа не была видна на панели задач?

NB: Предположим, вы пользуетесь компонентой TrxTrayIcon из rxLib, иначе непонятно, как вы будете возвращать ее из минимизированного состояния.

type
TForm1 = class(TForm)
Label1: TLabel;
RxTrayIcon1: TRxTrayIcon;
procedure FormCreate(Sender : TObject);
procedure RxTrayIcon1DblClick(Sender: TObject);
private
< Private declarations >
procedure ApplicationMinimize(Sender : TObject);
procedure ApplicationRestore(Sender : TObject);
public
< Public declarations >
end;

var
Form1: TForm1;

procedure TForm1.FormCreate(Sender: TObject);
begin
Application.OnMinimize := ApplicationMinimize;
Application.OnRestore := ApplicationRestore;
ShowWindow(Application.Handle, SW_HIDE);
end;

procedure TForm1.ApplicationMinimize(Sender : TObject);
begin
ShowWindow(Application.Handle, SW_HIDE);
end;

procedure TForm1.ApplicationRestore(Sender : TObject);
begin
ShowWindow(Application.Handle, SW_HIDE);
end;

procedure TForm1.RxTrayIcon1DblClick(Sender: TObject);
begin
Application.Restore;
Application.BringToFront;
end;

(AK): Только сpазу пpедупpеждаю пpо гpабли, на котоpые я наступал:
Будь готов к тому, что если пpи попытке закpытия пpиложения в OnCloseQuery или OnClose выводится вопpос о подтвеpждении, то могут быть пpоблемы с автоматическим завеpшением пpогpаммы пpи shutdown — под Win95 пpосто зависает, под WinNT не завеpшается. Очевидно, что сообщение выводится, но его не видно (пpичем SW_RESTORE не сpабатывает). Решение — ловить WM_QueryEndSession и после всяких завеpшающих действий и вызова CallTerminateProcs выдавать Halt.

Вопрос: А как поместить свою иконку на taskbar, там где часы и переключатель клавиатуры?

Ответ: В библиотеке rxLib есть компонент TrxTrayIcon.

Вопрос: Как сделать так, чтобы в моей форме курсор перемещался по полям ввода по Enter, как по Tab?

Если вы хотите обрабатывать событие на уровне формы (а не в каждом отдельном компоненте), уберите обработчики события у всех компонент и создайте FormKeyPress — обработчик OnKeyPress для формы:


procedure Form1.OnKeyPress(Sender : TObject; var Key : char);
begin
if Key = #13 then begin
SelectNext(Sender as TWinControl, true, true);
Key := #0;
end;
end;

(AnSa): Давно хотелось высказаться по поводy этого способа. Во-пеpвых, нyжно выставлять y фоpмы KeyPreview = True. Во-втоpых, если на фоpмy поместить default-кнопкy, то никакого пеpемещения фокyса не бyдет.

Вопрос: А где взять нормальный хелп для Delphi 3? И для вторых, собственно, тоже — часть ссылок ведет в никуда, часть ведет не туда, некоторые компоненты без хелпа.

Ответ: Hадо поставить нормальные Delphi 3, а не Confidentional/Field beta.

Для Delphi 2 — или найдите где-нибудь обновленные файлы .HLP, например, на
www.borland.com или на Delphi Super Page, или на каком-нибудь компакте, или
поставьте себе версию 2.01. Моя имеет истинную версию (Help|About.
наберите Alt-VERSION) 2.0.76.0. Узнать ее можно также по странице Internet в
панели компонентов.

Вопрос: Посоветуйте что-нибудь для работы с модемом и/или COM-портом из Delphi.

Ответ: AsyncPro. Он покроет 95% ваших нужд.

Вопрос: Как сделать так, чтобы программу можно было запустить только в одном экземпляре?

Ответ: Воспользуйтесь функцией ActivatePrevInstance из библиотеки rxLib. Для
завершения второго экземпляра, попытавшегося запуститься, используйте
Application.Terminate;

(AS): Другой вариант: X:\DELPHI2\DEMOS\IPCDEMOS\ipcthrd.pas, функция
IsMonitorRunning().

Прочие существующие F.A.Q. по Delphi:

  • от Akzhan Abdulin, 2:5040/55; это, скорее, набор Tips&Tricks, достаточно продвинутых, с большим количеством исходников;
  • FAQ по фичам для Delphi by Mikhail Chernyshev, 2:4615/26; это список библиотек и компонентов для Delphi с кратким описанием и указанием методов доставания;
  • The Unofficial Delphi Component Writing F.A.Q.; достаточно продвинутый F.A.Q. для писателей компонентов, очень полезно описание TDataLink;

Эхи по Delphi

Эхи Краткое описание
RU.DELPHI общие вопросы программирования на Delphi, не связанные с базами данных
RU.DELPHI.INFO эта эха — только для чтения. Писать в нее разрешено немногим и, скорее всего, это не вы. Туда помещаются F.A.Q. и списки интернетовских и фидошных ресурсов Delphi
RU.DELPHI.DB вопросы программирования баз данных в среде Delphi
RU.DELPHI.UUE категорически не рекомендованная к получению эха — для публикации файлов лучше пользоваться файлэхами.

Файлэхи по Delphi

Файлэха Краткое описание
WDEVDELPHI официальная файлэха иерархии RU.DELPHI
FEDELAPP Delphi and DBMS related applications, utilities and other goodies
FEDELINF Delphi related technical information, documentation
FEDELSRC Delphi related both 16 and 32bit Components and Libraries Sources
FEDELGEN Delphi related General
FED32SRC Delphi related 32bit Sources
FED32GEN Delphi related 32bit General

Дружественные эхи

Эхи Краткое описание
RU.CBUILDER Borland C++Builder
SU.WINDOWS.PROG общие вопросы программирования под MS Windows
SU.WIN32.PROG вопросы программирования для Win32 API
SU.WIN95.PROG вопросы программирования под MS Windows 95
SU.DBMS базы данных
SU.DBMS.SQL SQL-базы данных
SU.DBMS.BORLAND базы данных фирмы Borland
SU.DBMS.INTERBASE «родная» для Delphi база данных
SU.SOFTW общие вопросы разработки программ
RU.ALGORITHMS вещи, не зависящие от фамилии президента IBM и текущего номера сервиспака к NT
SU.FLAME обсуждение превосходства Borland Delphi над всеми прочими средствами разработки

Вопрос: Что такое Bold?

Ответ: Bold является модельно-управляемой платформой для разработки архитектуры приложений, для разработки инфраструктуры приложения, управляемой схемой приложения.
С технической стороны это n-уровневая структура, включающая встроенную среду разработки.

Вопрос: Кто нуждается в Bold?

Ответ: Каждый, кто хочет использовать UML, кто хочет получить качественное приложение «как задумано», кто нуждается в быстрой разработке надёжных профессиональных приложений.

Вопрос: Что обеспечивает n-уровневое средство Bold?

Ответ: n-уровневое средство структурирует приложение в несколько уровней. В 2-х уровневом приложении (например, приложение со стандартными компонентами Delphi или C++Builder для работы с БД) GUI-компоненты связываются непосредственно с таблицами БД.
В n-уровневом приложении есть уровень бизнес-объектов, содержащий бизнес-правила.

Вопрос: Какие инструментальные средства моделирования поддерживаются Bold for Delphi?

Ответ: Bold for Delphi/ Bold for C++ поддерживает двунаправленную интеграцию с Rational Rose (Rose 98 и выше). Поддержка других инструментальных средств, таких, например, как ObjectDomain, доступна по требованию. Остальные средства моделирования поддерживаются через обмен метаданными XMI и XML формата.

Вопрос: Генерирует ли код Bold for Delphi?

Ответ: Нет. Bold for Delphi/Bold for C++ является модельно-поддерживающей платформой, которая тесно интегрирована в Delphi/C++Builder, используя стандартную компонентную модель Delphi (VCL).
Bold for Delphi/Bold for C++ генерирует код для бизнес-классов. Код, первоначально содержавший элементы для добавления методов и бизнес-правил, генерируется в бизнес-объекты.

Вопрос: Как Bold for Delphi сохраняет информацию о модели?

Ответ: Информация модели хранится в приложении в компоненте BoldModel. Кроме того, Bold for Delphi/Bold for C++ позволяет сохранять модель в файле. В дальнейшем планируется включить поддержку хранилища объектов.

Вопрос: Может ли Bold for Delphi автоматически создавать БД?

Ответ: Да, Bold for Delphi/Bold for C++ обеспечивает автоматическую генерацию таблиц, а также изменение структуры с сохранением данных тогда, когда это требуется (что обычно случается при развитии модели!).

Вопрос: Доступен ли Bold из других систем разработки, кроме Delphi?

Ответ: Bold for Delphi включает в себя Bold for C++, предназначенный для Borland C++Builder.

Вопрос: Какие базы данных поддерживаются Bold for Delphi?

Ответ: Bold for Delphi поддерживает все SQL-БД, доступ к которым осуществляется через Borland Database Engine, ADO или драйверы InterBase. Через Borland SQL Links BDE так же возможен доступ к Oracle, Sybase, Informix, MS SQL Server, DB2 и InterBase.

За дополнительной информацией обращайтесь в компанию Interface Ltd.

Delphi выдает ошибку, что не найдены файлы/библиотеки типа “Vcl.Forms.dcu”

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

К примеру пишет нет файла Vcl.Forms.dcu, а когда его скачал и скинул в папку с библиотеками пишет что не может найти файл Vcl.Forms.pas. Так же там подключены такие модули: Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, StdCtrls, Controls, Classes; .

Вроде бы это стандартные библиотеки. Что нужно сделать, чтобы исправить эти ошибки?

1 ответ 1

VCL — это базовая библиотека визуальных компонентов, и все, что с ней связано, уже есть в Delphi, и качать это не надо.

Компилятор может ругаться на указание «VCL» перед классом. Попробуйте написать просто:

FAQ 5 VCL (1 из 2)

Следующий код создает модальную форму для ввода пароля во время выполнения программы. Тип TPasswordForm является классом-наследником от TForm, определяемым или в текущем, или в отдельном модуле со ссылкой на него в списке uses.

Для добавления компонента на форму во время выполнения программы необходимо выполнить несколько шагов:

  1. Объявите переменную экземпляра компонентного типа, который вы хотите создать <например, TButton >. Примечание: переменные экземпляра используются для указания на фактический экземпляр объекта. Сами они объектами не являются.
  2. Испрользуйте конструктор компонента Create для создания экземпляра объекта компонента и его назначения переменной экземпляра, объявленной в шаге 1. Конструктору Create любого компонента в качестве параметра необходимо передать ссылку на его владельца. За редким исключением в качестве параметра owner конструктора Create необходимо указывать форму.
  3. Назначьте «родителя» свойству компонента Parent (например, Form1, Panel1 и пр.). Родитель определяет где должен быть отображен компонент и осуществляет привязку его левого верхнего угла относительно его координат. Для того, чтобы поместить компонент в Groupbox, установите его свойство Parent в Groupbox. Чтобы компонент был видим, ему необходимо иметь родителя, это позволит ему быть отображенным в его области.
  4. Установите любые другие необходимые свойства (например, Width, Height).
  5. Наконец, заставьте компонент появиться на форме, сделав его видимым, т.е. установив его свойсто Visible в True.
  6. Если вы создали компонент и задали ему владельца (свойство owner), вам нет необходимости уничтожать компонент самим, это сделает за вас его владелец в момент его уничтожения. Если же при создании компонента владелец ему присвоен не был, то вся ответственность за уничтожение ложится на вас, его нужно освободить когда он больше вам не нужен. Следующий код показывает процесс добавления компонента TButton на текущую форму во время работы программы:

Установка JEDI VCL

Доброго времени суток.
У меня возникла ошибка при установки JCL.
Вот логи:
================================================================================
JCL 2.6 Testing Build 5178
==========RAD Studio XE5 32 bit=================================================
Installed personalities :
32 bit Delphi
64 bit Delphi
32 bit Delphi for OSX
32 bit C++Builder
64 bit C++Builder
================================================================================
Multiple profile installation
Single profile installation
================================================================================
Saving conditional defines.
Loaded template for include file C:\Users\ХАКЕР\Downloads\JVCL348CompleteJCL26-Build5178\jcl\source\include\jcl.template.inc
Saved include file C:\Users\ХАКЕР\Downloads\JVCL348CompleteJCL26-Build5178\jcl\source\include\jcld19win32.inc
Building source\common library units for RAD Studio XE5 32 bit.
«C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\bin\dcc32.exe» bzip2 Jcl8087 JclAbstractContainers JclAlgorithms JclAnsiStrings JclArrayLists JclArraySets JclBase JclBinaryTrees JclCharsets JclCompilerUtils JclComplex JclCompression JclContainerIntf JclCounter JclDateTime JclDevToolsResources JclExprEval JclFileUtils JclHashMaps JclHashSets JclIDEUtils JclIniFiles JclLinkedLists JclLogic JclMath JclMIDI JclMime JclNotify JclPCRE JclPreProcessorAlgorithmsTemplates JclPreProcessorArrayListsTemplates JclPreProcessorArraySetsTemplates JclPreProcessorBinaryTreesTemplates JclPreProcessorContainer1DTemplates JclPreProcessorContainer2DTemplates JclPreProcessorContainerIntfTemplates JclPreProcessorContainerKnownMaps JclPreProcessorContainerKnownTypes JclPreProcessorContainerTemplates JclPreProcessorContainerTypes JclPreProcessorExcDlgTemplates JclPreProcessorHashMapsTemplates JclPreProcessorHashSetsTemplates JclPreProcessorLexer JclPreProcessorLinkedListsTemplates JclPreProcessorParser JclPreProcessorQueuesTemplates JclPreProcessorSortedMapsTemplates JclPreProcessorStacksTemplates JclPreProcessorTemplates JclPreProcessorTreesTemplates JclPreProcessorVectorsTemplates JclQueues JclResources JclRTTI JclSchedule JclSimpleXml JclSortedMaps JclStacks JclStatistics JclStreams JclStrHashMap JclStringConversions JclStringLists JclStrings JclSynch JclSysInfo JclSysUtils JclTrees JclUnicode JclUnitConv JclUnitVersioning JclUnitVersioningProviders JclUsesUtils JclValidation JclVectors JclWideStrings pcre zlibh —no-config -U»C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\lib\Win32\release» -M -$X+ -$G+ -$H+ -$P+ -$U- -$T- -$V+ -$J+ -$Z1 -$L+ -$Y+ -$J+ -$C- -$D- -$I- -$O+ -$Q- -$R- -$W- -N0″C:\Users\ХАКЕР\Downloads\JVCL348CompleteJCL26-Build5178\jcl\lib\d19\win32″ -D_RTLDLL;NO_STRICT;USEPACKAGES -NO»C:\Users\ХАКЕР\Downloads\JVCL348CompleteJCL26-Build5178\jcl\lib\d19\win32″ -N1″C:\Users\Public\Documents\RAD Studio\12.0\hpp» -JPHNE —BCB -n»sSystem;System.Win;WinAPI;Vcl;Vcl.Imaging» -I»C:\Users\ХАКЕР\Downloads\JVCL348CompleteJCL26-Build5178\jcl\source\include» -U»C:\Users\ХАКЕР\Downloads\JVCL348CompleteJCL26-Build5178\jcl\source\common;C:\Users\ХАКЕР\Downloads\JVCL348CompleteJCL26-Build5178\jcl\source\windows;C:\Users\ХАКЕР\Downloads\JVCL348CompleteJCL26-Build5178\jcl\source\vcl» -R»C:\Users\ХАКЕР\Downloads\JVCL348CompleteJCL26-Build5178\jcl\source\common;C:\Users\ХАКЕР\Downloads\JVCL348CompleteJCL26-Build5178\jcl\source\windows;C:\Users\ХАКЕР\Downloads\JVCL348CompleteJCL26-Build5178\jcl\source\vcl»
Embarcadero Delphi for Win32 compiler version 26.0
Copyright (c) 1983,2013 Embarcadero Technologies, Inc.
bzip2.pas(37) Fatal: F1026 File not found: ‘jcl.inc’
. failed.

Скриншот ошибки приложен. Устанавливаю JCL 2.6. Testing Build 5178 на RAD Studio XE5 32 bit.
Помогите.
Заранее спасибО!

02.06.2014, 14:25

Инсталляция палитры JEDI
Приветствую не устанавливается последняя версия 3.47 при установке JCL было несколько ошибок при.

Не устанавливается штатно JEDI delphi 10.1 berlin
тоесть по этому видео gxCzh1TDZ00 выдаёт ошибку на стадии начала загрузки internal check.

Компонент JEDI: jvDriveCombo — динамическая смена типов дисков
В свойствах компонента, есть возможность выбора, какие типы дисков будут выводится в комбо.

Vcl.Direct2D
Доброго времени суток. Зачем нужен юнит Vcl.Direct2D, и как он связан с подсистемой Direct2D из.

Распаковка определённых папок/файлов из 7z (JEDI)
Есть функция — распаковывает полностью архив, а нужно что бы только опредёлённые папки и файлы: .

Введение. Назначение Delphi и его особенности

СБОРНИК МетодическиХ указаниЙ

ПО выполнению лабораторных работ

ИНФОРМАТИКА

Уровень профессионального образования: высшее образование – бакалавриат


Направление подготовки:15.03.01 «Машиностроение»

Профиль подготовки: «Оборудование и технология сварочного производства»

Квалификация выпускника: Академический бакалавр

Методические указания по выполнению лабораторных работ составлены доцентом А. В. Масленниковым и обсуждены на заседании кафедры СЛиТКМПолитехнического института

Протокол № 1 от « 29 » августа 2014 г.

Зав. кафедрой ______________________А.А. Протопопов

Методические указания по выполнению лабораторных работ пересмотрены и утверждены на заседании кафедры СЛиТКМ Политехнического института

протокол №___ от « » августа 20____ г.

Зав. кафедрой ______________________А.А. Протопопов

Министерство образования и науки Российской Федерации

Федеральное государственное бюджетное образовательное учреждение

высшего профессионального образования

«Тульский государственный университет»

Кафедра «Сварка, литье и технология конструкционных материалов»

МетодическиЕ указаниЯ

ПО выполнению лабораторнОЙ работЫ №1

ИНФОРМАТИКА

Основы работы в среде Borland Delphi

Уровень профессионального образования: высшее образование – бакалавриат

Направление подготовки:150700 «Машиностроение»

Профиль подготовки: «Машины и технология литейного производства»

Квалификация выпускника: 62, бакалавр

1. ЦЕЛЬ И ЗАДАЧИ РАБОТЫ

Изучить назначение и базовые возможности приложения Borland Delphi.

2. ТЕОРЕТИЧЕСКИЕ ПОЛОЖЕНИЯ

Введение. Назначение Delphi и его особенности

В последнее время резко возрос интерес к программированию. Это связано с развитием и внедрением в повседневную жизнь информационно-коммуникационных технологий. Если человек имеет дело с компьютером, то рано или поздно у него возникает желание, а иногда и необходимость, программировать.

Среди пользователей персональных компьютеров в настоящее время наиболее популярно семейство операционных систем Windows и, естественно, что тот, кто собирается программировать, стремится писать программы, которые будут работать в этих системах.

Несколько лет назад рядовому программисту оставалось только мечтать о создании собственных программ, работающих в среде Windows, т. к. единственным средством разработки был Borland C++ for Windows, явно ориентированный на профессионалов, обладающих серьезными знаниями и опытом.

Бурное развитие вычислительной техники, потребность в эффективных средствах разработки программного обеспечения привели к появлению систем программирования, ориентированных на так называемую «быструю разработку», среди которых можно выделить Borland Delphi и Microsoft Visual Basic. В основе систем быстрой разработки (RAD-систем, Rapid Application Development — среда быстрой разработки приложений) лежит технология визуального проектирования и событийного программирования, суть которой заключается в том, что среда разработки берет на себя большую часть рутинной работы, оставляя программисту работу по конструированию диалоговых окон и функций обработки событий. Производительность программиста при использовании RAD-систем -фантастическая!

Delphi (произносится «Делфàй») – среда программирования для Windows, разработанная компанией Borland International. Название происходит от древнегреческого города Дельфы – того самого, где жил дельфийский оракул. Поэтому на значке системы Delphi изображена греческая колонна. Delphi соединяет в себе компилятор языка программирования Object Pascal, интегрированную среду разработки (IDE), библиотеку визуальных компонентов VCL, средства для работы с базами данных (BDE) и многое другое. При помощи Delphi можно решить практически любую программистскую задачу, включая работу с базами данных, написание приложений для Интернета, экранных заставок, системных утилит и пр.

Delphi — это среда быстрой разработки, в которой в качестве языка программирования используется язык Delphi.

Язык Delphi — строго типизированный объектно-ориентированный язык, в основе которого лежит хорошо знакомый программистам Object Pascal. Delphi – близкий родственник обычного языка Pascal, что обеспечило ему широкую популярность. В настоящее время Delphi стал основным инструментом разработки программного обеспечения во всем мире. Существует и версия Builder, в которой можно совместно использовать процедуры, написанные на языках C и Pascal.

Система Delphi постоянно развивается. По состоянию на 2003 г. наиболее стабильной и отработанной являлась версия 6.0. Версия 7.0 заявлена разработчиком как переходная к 8.0 и не рекомендуется для широкого использования. В то же время почти все рассматриваемые далее примеры будут работать практически в любой версии Delphi, начиная с 3.0. Содержательные различия между версиями 3.0 … 7.0 незначительны, и для самостоятельной работы можно использовать литературу, описывающую любую из этих версий.

Borland Delphi 7 Studio позволяет создавать самые различные программы: от простейших однооконных приложений до программ управления распределенными базами. В состав пакета включены разнообразные утилиты, обеспечивающие работу с базами данных, XML-документами, создание справочной системы, решение других задач. Отличительной особенностью седьмой версии является поддержка технологии .NET.

Borland Delphi 7 Studio может работать в среде операционных систем от Windows 98 до Windows XP и выше. Особых требований, по современным меркам, к ресурсам компьютера пакет не предъявляет: процессор должен быть типа Pentium или Celeron с тактовой частотой не ниже 166 МГц (рекомендуется Pentium II 400 МГц), оперативной памяти — 128 Мбайт (рекомендуется 256 Мбайт), достаточное количество свободного дискового пространства (для полной установки версии Enterprise необходимо приблизительно 475 Мбайт).

Официально бесплатной версией Delphi является Lazarus, примерно соответствующий по своим возможностям Delphi 5.0.

Русской версии Delphi не существует. Все так называемые «русские версии» – продукция криворуких пиратов, работающая нестабильно. Всегда устанавливайте только исходную английскую версию.

Не нашли то, что искали? Воспользуйтесь поиском:

История Delphi

Что такое delphi? Делфи — это высокоуровневый, императивный язык программирования (диалект Object Pascal) со строгой типизацией переменных.

По данным Tiobe Index, наибольшая популярность делфи наблюдалась в октябре 2001 года, когда этот замечательный язык программирования занимал шестую строчку в рейтинге самых популярных языков программирования

На этой странице представлено краткое описание всех версий Delphi. История Delphi начинается с 1995 года и насчитывает более 20 различных версий. Сегодня Delphi поддерживает разработку под Windows, Linux, Mac OS, iOS и Android.

Borland Delphi (Delphi 1)

Дата выхода: 14 февраля 1995 года

Слоган: Delphi и Delphi Client/Server являются единственными средствами разработки, которые обеспечивают быструю разработку приложений (RAD), преимущества визуального компонент-ориентированного дизайна, мощность оптимизации родного компилятора и масштабируемые клиент/серверные решения.

Внешний вид IDE:

Надо сказать, что Delphi 1 можно назвать без преувеличения «единственной и неповторимой» так как в этой версии Delphi можно было собирать приложения только под 16-ти разрядную версию Windows 3.1.

Delphi 2

Дата выхода: 10 февраля 1996 года

Слоган версии: «Простота VB с Силой C++»

В Delphi 2 была реализована поддержка 32-разрядной версии Windows (Win 95), обеспечена ещё более продвинутая быстрая разработка приложений (RAD). Тогда же в Delphi появилась поддержка OLE Automation, вариантных типов, long string и т.д.

Вид IDE Delphi 2:

Project Manager Delphi 2:

Delphi 3

Дата выхода: 5 августа 1997 года

Слоган: Наиболее полный набор визуальных, высокопроизводительных, клиент и серверных инструментов разработки для создания распределенных корпоративных и веб-приложений.

Так, если Delphi 2.0 позиционировалась как инструмент для создания высокопроизводительных приложений для работы с базами данных, то новая версия — Delphi 3 имела уже в своем составе новые компоненты, реализующие работу с сетевыми протоколами: HTTP, SMTP, POP3 и т.д. Все новые компоненты для работы с Сетью расположились на вкладке Internet палитры компонентов Delphi. Надо сказать, что часть тех компонентов дожили и до сегодняшнего дня, например, PageProducer.

Внешний вид IDE Delphi 3:

Delphi 4

Дата выхода: 16 июня 1998 года

Delphi 4 представляет собой полный набор профессиональных и клиент/сервер средств разработки для создания высокопроизводительных решений.

В Delphi 4 реализованы механизмы Drag&Drop, Drag&Dock для компонентов. Новые функции, включенные AppBrowser, динамические массивы, перегрузка методов, поддержка Windows 98, улучшенная OLE и COM поддержка, а также расширенная поддержку баз данных.

Можно сказать, что для достаточно большой аудитории программистов, работающих в Delphi эта версия наравне с более поздней Delphi 7 стала самой любимой и неизменной IDE, так как сочетала в себе скорость, качество и быстроту разработки наряду с минимальными затратами финансовых средств.


Внешний вид IDE Delphi 4:

Delphi 5

Дата выхода: 10 августа 1999 года

Слоган: высокопродуктивная разработка приложений для Интернет.

Delphi 5 преподнесла разработчикам достаточно много новых возможностей и функций. Так, например, в Delphi 5 впервые была реализована поддержка различных макетов рабочего стола (Layouts), была реализована поддержка фреймов, инструменты для перевода интерфейса приложений на другие языки. По части Интернет-технологий, помимо прочего, была реализована поддержка XML. Для работы с базами данных была реализована поддержка ADO. Кроме того были улучшены механизмы отладки приложений.

Вид IDE Delphi 5:

Delphi 6

Дата выхода: 21 мая 2001 года

Слоган: с Delphi 6 Вы сможете легко и быстро создавать приложения для электронного бизнеса.

Borland Delphi 6 была введена поддержка Web Services. В Delphi 6 введены новые функции и усовершенствования в следующих областях: IDE, Интернет, XML, Компилятор, COM / Active X, поддержка баз данных …
Более того, в Delphi 6 добавлена поддержка кросс-платформенной разработки — что позволило, используя один и тот же код собирать приложения как с Delphi (под Windows) так и Kylix (под Linux). Кроме этого в Delphi 6 была реализована поддержка DBExpress, добавлены новые модули, классы и компоненты.

Заставка Delphi 6:

Внешний вид IDE Delphi 6:

Delphi 7

Дата выхода: 9 августа 2002 года

Размер дистрибутива: 680 Mb

Delphi 7 — это та версия Delphi, которая оставалась, да и видимо остается, самой популярной версией из всех ранее существующих версий. Во многом популярность Delphi 7 можно обозначить одной простой фразой — абсолютный провал следующей версии (Delphi 8). Эта версия Delphi стала настолько популярной, что даже спустя 10 лет после её выпуска многие разработчики так и продолжают её использовать, а разработчики Delphi (Embarcadero) в рамках своей акции «Купи Delphi XE и получи все предыдущие версии Delphi бесплатно» предлагали скачивать предыдущие дистрибутивы, начиная именно с Delphi 7.

Эта же версия Delphi и стала последней вехой развития классического интерфейса IDE Delphi так как уже в следующей версии Delphi был реализован новый интерфейс (Galileo), который усугубил и без того шаткое положение Delphi 8 и ещё раз подчеркнул популярность старой доброй Delphi 7.

Заставка Delphi 7:

Внешний вид IDE Delphi 7:

Delphi 8

Кодовое название: Octane

Дата выхода: 22 декабря 2003 года

Новая версия Delphi под кодовым названием Octane должна была, по-видимому, стать той вехой развития Delphi, начиная с которой все влюбились бы в .NET-технологии. Сейчас уже мало, что можно найти и вспомнить по Delphi 8, но, тем не менее, сохранились в Сети некоторые сообщения от разработчиков Delphi, например, в Wiki (источник):

Delphi 8 была выпущена в декабре 2003 года исключительно в . NET-версии, что позволило разработчикам Delphi компилировать код Object Pascal в .NET CIL. IDE был переписан, чтобы приспособить его для. NET-развития. Delphi 8 была подвержена резкой критике за её низкое качество и за то, что было уже не возможно создавать приложения (*.EXE). Неспособность генерировать собственные приложения применима только к этой версии, так как возможность была добавлена обратно в следующем выпуске (Delphi 2005).

Действительно, Delphi 8 была самой нестабильной и, по-видимому, самой НЕ любимой версией Delphi как до так и после её выхода.

Внешний вид IDE Delphi 8:

Согласно данным tiobe.com к концу 2004 года рейтинг Delphi упал до своего абсолютного минимума. Но разработчики из Borland постарались сделать правильные выводы из сложившейся ситуации и в 2005 году на свет появилась новая версия Delphi.

Delphi 2005

Кодовое название: Diamondback

Дата выхода: 12 октября 2004 года

Начиная с 2005 года Delphi входит как часть в состав RAD Studio. В новой версии Delphi вновь появилась возможность разработки для Win32, а также был внесен ряд изменений, которые позволили частично изменить ситуацию в лучшую сторону. Хотя, как и предшествующая версия, Delphi 2005 подвергалась критике за нестабильность и большое количество всякого рода багов, тем не менее нельзя не отметить и ряд улучшений, которые были тогда сделаны разработчиками из Borland и до сих пор используются в Delphi.

Так, по части языковых возможностей, именно в Delphi 2005 была впервые реализована такая конструкция как:

аналог for … each в C#.

Или, например, по части полезных инструментов — в Delphi 2005 появился Help Inside. Также в редакторе исходного кода стали выделяться синтаксические ошибки схожим с MS Office образом (волнистой красной линией). В общем в Delphi 2005 наметилась тенденция на изменение курса в лучшую для всех нас сторону. Но тем не менее, назвать Delphi 2005 качественной, к сожалению было нельзя.

SplashScreen Delphi 2005:

Help Inside Delphi 2005:

Delphi 2005 Unlocked Layout:

Delphi 2006

Кодовое название: DeXter

Год выпуска : 2006

Новая версия Borland Developer Studio оказалась, наверное, первой, начиная с Delphi 8 версией, которая вела себя более-менее стабильно. Как и в BDS 2005 в новой версии студии была поддержка разработки проектов на C#, C++, Delphi for Win32 и Delphi for .NET. В Delphi 2006 появились нововведение как по части языковых конструкций, так и улучшения в отладке приложений:

Debugger Delphi 2006:

Кроме этого в Delphi 2006 были добавлены новые функции рефакторинга:

Также в Delphi 2006 были добавлены новые компоненты в VCL. В общем по этой версии можно было сказать, что Borland всё-таки смог выпустить вполне стабильную версию студии, которая использовала Galileo.

А потом случилось, то, чего мало кто ожидал.

8 февраля 2006 Borland объявила, что ищет покупателя для своей интегрированной среды разработки и линейки продуктов по базам данных, которые включают в том числе и Delphi.

Ниже Вы можете видеть скрины последней версии Delphi, которая разрабатывалась Borland’ом:

Стартовое окно BDS 2006:

Сравнение версий проекта:

Delphi 2007

Год выпуска: 2007

Весной 2007 года была выпущена новая версия студии, но уже под лэйблом CodeGear. Это была первая версия студии, которую можно было установить через Интернет. Delphi 2007 оказалась наиболее стабильной и быстрой за последние 4 года. Эта версия, можно сказать, реанимировала разработку под Win32 на Delphi. В этой версии Delphi появилась поддержка Windows Vista, AJAX и пр. улучшения.

Вот как выглядел установщик Delphi 2007:

IDE Delphi 2007
Думаю, что многие разработчики, использующие последние версии Delphi после выхода Delphi 2007 вздохнули более менее свободно — вот она та самая версия, которая отличалась стабильностью и скоростью.

В 2008 году CodeGear была продана и новым владельцем студии стала Embarcadero Technologies. Но продажа CodeGear для нас, как разработчиков, стала не главным. Главным в итоге стало то, что Delphi 2007 оказалась последней НЕ юникодной версией Delphi.

Delphi 2009

Кодовое название: Tiburon

Год выпуска: 2009

Tiburon стала той версией Delphi, начиная с которой можно было сказать, что в Delphi началась эпоха Юникода. В Delphi 2009 был введен ряд довольно значительных улучшений как в VCL так и в части самого языка Delphi.

Так, например, в Delphi 2009 впервые появилась вкладка компонентов Ribbon Controls о которой так много было рассказано в блоге WebDelphi.ru. В языке появился новый тип данных — Generics. Но, как сказано выше, одним из важнейших нововведений стала поддержка Юникода.

IDE Delphi 2009:

Delphi 2010

Кодовое название: Weaver

Год выпуска: 2009

В августе 2009 года была выпущена новая версия RAD Studio в состав которой вошла и новая версия Delphi — Delphi 2010. Установщик Weaver был выполнен в стильных чёрных тонах:


Но это конечно же не самое главное. В новой версии Delphi появился новый RTTI, поддержка Windows 7 Direct 2D, новые компоненты Gestures, экранная клавиатура и т.д. Кроме того в Delphi 2010 было введено по-крайней мере два очень значительных нововведения в самой IDE — это Code Formatter и возможность сделать интерфейс «под 7-ку» то есть получить тот самый внешний вид IDE, который так полюбили многие разработчики.

Вид IDE Delphi 2010 «под 7-ку»

Delphi XE

Кодовое название: Fulcrum

Год выпуска: 2010

Embarcadero Technologies спустя 1 год и 5 дней с момента выхода Delphi 2010 порадовала нас новой версией Delphi — Delphi XE. Не могу сказать, что новая версия преподнесла нам что-то кардинально новое, но, тем не менее, нельзя не отметить то, что именно в Delphi XE реализована поддержка perl-подобных регулярных выражений, поддержка работы с SVN. В палитре компонентов появилась новая вкладка Windows Azure. Сама IDE стала работать по-быстрее своей предшественницы — Delphi 2010. В состав IDE были включены такие инструменты как AQTime, FinalBuilder, CodeSite. Кроме этого разработчики Delphi приложили достаточно большое усилий в разработку DataSnap о котором Вы можете не только прочитать, но и посмотреть несколько полезных видео-роликов

Delphi XE2

Кодовое название: Pulsar

Год выпуска: 2011

Очередной этап становления Delphi, как языка разработки кросс-платформенных приложений, наступил с выходом Delphi XE2.

Так, если внешний вид IDE практически ничем не отличался от предыдущей версии — Delphi XE, то «под капотом» Delphi XE2 было немало приятных сюрпризов для разработчиков, а именно:

  • Поддержка платформы x64 (пока только для Windows).
  • Поддержка операционных систем Mac OS X и iOS.
  • Кросс-платформенная библиотека FireMonkey для создания современного пользовательского интерфейса.
  • Библиотека LiveBindings для связывания интерфейса с различными наборами данных.

Внешний вид установщика Delphi XE2:

Казалось, что Delphi XE2 — это настоящий прорыв в разработке приложений. И, видимо, так и было — чего только стоила возможность разрабатывать приложения под Mac OS X. Однако, как оказалось позднее — FireMonkey работала очень нестабильно и, если с тем, что FireMonkey никак несовместима с VCL разработчики в итоге смирились, то нестабильность работы новой библиотеки визуальных компонентов вызвала довольно серьезную критику новой версии Delphi. Однако Embarcadero не только не отказались от FireMonkey, но и продолжили её активно развивать, т.к. именно на эту библиотеку возлагались задачи поддержки таких операционных систем как Linux и Android.

Ещё одной новинкой Delphi XE2 стало именование модулей. Теперь появилась возможность использовать в названии модуля точки и называть модули, например, так — System.Types and Vcl.Styles. Очевидно, что такое нововведение было связано, прежде всего, с появлением новой библиотеки и дальнейшими планами по поддержке новых платформ.

Изменения в RTL:

  • в модуле System.SysUtils появилась запись (record) TOSVersion, позволяющая определять под какой операционной системой запущено приложение Delphi.
  • модуль System.Zip для работы с zip архивами в делфи без сторонних компонентов

Delphi XE3

Год выпуска: 2012

В этой версии разработчики Delphi серьезно переработали библиотеку FireMonkey и, даже, назвали её несколько иначе — FM 2 . FireMonkey была переработана до такой степени, что некоторые проекты, разработанные в Delphi XE2 отказывались собираться. Однако, в FM 2 появилась возможность использовать действия (TActionList), что не могло не радовать разработчиков, разглядевших в новой библиотеке преимущества по сравнению с VCL. Основными отличительными особенностями Delphi XE3 стали:

  1. Нет возможности разрабатывать приложения под iOS — предполагалось, что эта возможность появится в новом продукте Embarcadero под названием Mobile Studio.
  2. Серьезно переработан механизм Live Bindings. Теперь это Visual Live Bindings (см. скрин):

3. Новый тип приложений — VCL Metropolis UI Application:

4. В Delphi XE3 был обновлен DBExpress — добавлена поддержка такой популярной СУБД как SQLite.

Delphi XE4

Год выпуска: 2013

  • Вернулась поддержка iOS, которая отсутствовала в RAD Studio XE3. Взамен RAD Studio XE3 Mobile, выход которой ожидался в начале 2013 года, RAD Studio XE4 была дополнена функционалом для разработки мобильных приложений.
  • Программирование непосредственно под iPhone и iPad с учётом всех программных и технических особенностей.
  • Эмулятор мобильных устройств.
  • Улучшено взаимодействие с такими базами данных, как InterBase, SQLite, MySQL и прочими.

Внешний вид IDE:

И, если релиз Delphi XE4 прошел относительно спокойно и, даже можно сказать, буднично, то развитие компании Embarcadero продолжалось и уже 5 февраля 2013 года, компания Embarcadero заявила об ещё одном своем приобретении. На этот раз Embarcadero Technologies объявила о приобретении технологии AnyDAC от компании DA-SOFT Tecnologies. В последующих версиях Delphi эта библиотека получит название FireDAC.

Также, для разработки под мобильную ОС iOS (а, впоследствии под Android) в палитре компонентов появилась новая вкладка — Sensors, содержащая три компонента:

  • TLocationSensor — датчик местоположения
  • TMotionSensor — датчик ускорения (акселерометр)
  • TOrientationSensor — датчик компаса/гироскопа

Delphi XE5

Год выпуска: 2013

С FireMonkey, которая отныне именуются как FM Platform появилась возможность разрабатывать приложения под мобильную операционную систему Android. Среди основных новинок Delphi XE5 можно выделить следующие:

  1. Компилятор Delphi для Android ARM compiler как для устройств, так и для эмулятора
  2. Платформа FM platform для создания «нативных» приложений под Android для Gingerbread (2.3.3 – 2.3.7), Ice Cream Sandwich (4.0.3, 4.0.4) и Jelly Bean (4.1.x, 4.2.x, 4.3.x).
  3. Поддержка iOS 7 SDK и соответствующих стилей
  4. Менеджер развёртывания (Deployment Manager) для Android
  5. Удалённая отладка для Android
  6. Редакция Professional включает расширенную поддержку FireDAC для локальных баз данных, включая Microsoft Access database, SQLite database, InterBase ToGo / IBLite, InterBase при локальном взаимодействии, MySQL Embedded, MySQL Server при локальном взаимодействии, Advantage Database при локальном взаимодействии, PostgreSQL при локальном взаимодействии, Firebird Embeddedи Firebird при локальном взаимодействии
  7. Клиентская библиотека REST Client для упрощенного вызова REST-сервисов. Поддержка авторизации, включая Basic Authentication, Plan Authentication, OAuth1, OAuth2.
  8. Средства отладки REST для тестирование вызовов REST и их параметров

Delphi XE6

Год выпуска: 2014

15 апреля 2014 года Embarcadero выпустила RAD Studio XE6. Разработчики назвали его «качественным релизом», так как были исправлены сотни дизайн-ошибок и ошибки производительности.

Ключевые возможности Delphi XE6:

  • Компоненты для взаимодействия приложений (Application Tethering Components)
  • Взаимодействие с сервисами в облаках (BaaS), компоненты для Kinvey и Parse.
  • Новые стили VCL: Придание приложением обновленный вид под актуальные версии Windows или создание для них уникального дизайна. Включает стиль планшетной Windows. Поддерживает Windows 7 и
  • Компоненты VCL для работы с датчиками: Delphi-приложения могут использовать возможности датчиков положения, перемещения и других. Доступ к датчиками устройств из VCL-приложений для планшетов под управлением Windows.
  • Расширение ключевых возможностей FireDAC

По сути, Delphi XE6 — это «качественный релиз», т.к. в этой версии Delphi исправлено более 2000 ранее зарегистрированных ошибок.

Delphi XE7

Год выпуска: 2014

Из ключевых особенностей Delphi XE7 можно выделить добавление в RTL библиотеки для параллельных вычислений. По большому счёту, IDE осталась той же самой (в плане внешнего вида), хотя, как это водится, была проделана работа над ошибками. Также, начиная с Delphi XE7 прекращена поддержка устаревшей технологии BDE — теперь всем настоятельно рекомендуют использовать FireDAC. Также в Delphi XE7 была реализована поддержка работы с репозиториями Git.

Просмотр внешнего вида разрабатываемого приложения (с использованием FireMonkey)

Новые компоненты в VCL:

  • TTaskBar и TJumpList — компоненты позволяют управлять иконкой вашего приложения в панели задач Windows 7 и выше.

Delphi XE8

Год выпуска: 2015.

  • Появилась возможность разработки 64-битных приложений под iOS;
  • Delphi поддерживает новую систему контроля версий, интегрированную в IDE, для управления и отслеживания изменений в проектах: Mercurial Version Control System Integrated;
  • Позволяет создавать универсальные приложения для iOS с разной разрядностью — в одном исполняемом файле два кода: 32 бит и 64 бит (ARMv7 + arm64);
  • Добавлены два новых независящих от платформы типа данных: FixedInt и FixedUInt.
  • Добавлен новый HTTP Client API для отправки http-запросов к серверам и получения ответов.

На этой версии прекращается, так называемая, эпоха XE-версий. Следующая, по логике, версия Delphi XE9 никогда не выйдет, а вместо неё появится Delphi 10 Seattle.

Delphi 10 Seattle

Год выпуска: 2015

  • поддерживается iOS 8.4;
  • поддерживается Android 5.1.1;
  • поддержка служб Android;
  • поддержка модульного тестирования DUnitX для Android и iOS;
  • поддержка DirectX 12;
  • поддержка вызова API WinRT;
  • поддержка FireDAC для базы данных NoSQL MongoDB
  • новое поведение MultiView;
  • новые компоненты VCL;
  • новые компоненты для работы с Beacon;
  • улучшен механизм стилей;
  • улучшен диспетчер библиотек GetIt;
  • улучшены возможности IDE;

Заставка RAD Studio 10 Seattle:

Новые компоненты для Windows 10:


  1. TActivityIndicator — индикатор активности;
  2. TToggleSwitch — переключатель типа TCheckBox, имитирующий физический переключатель.
  3. TSearchBox — поле ввода для поиска
  4. TRelativePanel — это контейнерный элемент управления, который позволяет позиционировать дочерние элементы управления по различным критериям
  5. TSplitView — позволяет отображать или скрывать временный контент. Например, вы можете использовать его в качестве навигационного меню верхнего уровня, где навигационный контент скрыт и показывается на форме при необходимости

Delphi 10.1 Berlin

Год выпуска: 2020

Из нововведений в «Берлине» — поддержка Android 6.0. Платформа для мобильной разработки (FireMonkey — FM Platform — FMX) продолжает развиваться и улучшаться. Изменена работа с диалогами InputBox, InputQuery и т.д.

Заставка Delphi 10.1 Berlin:

IDE Delphi 10.1 Berlin

Delphi 10.2 Tokyo

Год выпуска: 2020

Основные новые возможности Delphi 10.2 Tokyo:

  • в состав Delphi включён компилятор приложений под Linux (Ubuntu Server (LTS 16.04) and RedHat Enterprise (V7));
  • включена поддержка СУБД MariaDB.

Заставка Delphi 10.2 Tokyo:

IDE Delphi 10.2 Tokyo:

  • TStackPanel — позволяет выравнивать элементы управления внутри себя по одинаковым значениям свойств, например, выровнять все компоненты по горизонтали и сделать между ними одинаковые отступы.
  • TCardPanel — позволяет отображать коллекцию панелей или страниц (элементы управления TPanel), которые отображаются пользователю по одной за раз.
  • TTimePicker и TDatePicker — позволяют выбирать значения времени и даты из раскрывающегося списка, как это делается, например в Andro >

Delphi 10.3 Rio

Год выпуска: 2020

Нововведения в Delphi 10.3 Rio:

  • усовершенствования VCL для High DPI дисплеев
  • поддержка Per Monitor V2
  • новые интерфейсы программирования приложений для Windows 10 и WinRT,
  • обновленная поддержка мобильных платформ (поддержка Android API26, соответствие требованиям Google Play Store в отношении новых приложений с августа 2020 года и обновления приложений с ноября 2020 года).
  • собственные элементы управления Android и стилизованные элементы управления FMX в одной и той же форме Android, включая тему материального дизайна для Android 5.0 или выше
  • поддержка iOS 12 (32- и 64-бит) для создания App Store и корпоративных приложений.
  • поддержка смайликов Юникод.

В этой версии Delphi впервые введена поддержка т.н. Inline Variable, в результате чего стало возможным определение переменных непосредственно в теле методов, например, так:

Взлом Борландии: изящная декомпиляция Delphi

Содержание статьи

Начинающие хакеры обычно испытывают большие трудности при взломе программ, написанных на Delphi и Builder, поскольку классические трюки, типа бряка на GetWindowTextA, не работают. И чтобы не пилить серпом по яйцам, требуется учитывать особенности библиотеки VCL, которая только с виду кажется неприступной, а в действительности ломается даже проще, чем чистые Си-программы! Не веришь? Убедись сам!

Для начала.

Два основных орудия хакера — это отладчик и дизассемблер, которые могут использоваться как по отдельности, так и совместно друг с другом. Первая (и самая сложная) фаза атаки — разведывательная. Прежде чем наносить основной удар по врагу, необходимо локализовать защитный механизм в мегабайтах мирного программного кода, после чего выстелить битхаком, поменяв JE на JNE, либо, разобравшись с алгоритмом процедуры регистрации, написать свой собственный генератор ключей/серийных номеров.

Ударная фаза практически не зависит от специфики ломаемого приложения и отрабатывается годами, представляя собой неромантичный кропотливый труд, а вот комплекс разведывательных мероприятий гораздо более интеллектуальное занятие, требующее хитрых мозгов и, конечно же, хвойно-новогодних опилок, которые мы будем настойчиво курить. И ожесточенно долбить. По клавиатуре! Ведь Новый год — семейный праздник, и всякий уважающий себя хакер проводит его наедине с самым близким ему существом — компьютером. Для создания атмосферы праздника нужно будет зажечь свечи (не те, что от геморроя), послать всех девушек в /dev/null, зарядить бурбулятор свежей порцией man’ов и начать маньячить. Ведь юзеры ждут
подарков, а лучшего подарка, чем новый кряк, для компьютерщика, пожалуй, и не придумаешь!

Короче, надо хачить. Поехали!

Осваиваем DeDe

DeDe – это такой декомпилятор программ, написанных на Delphi и Builder‘е. Бесплатный и очень мощный. Мы будем использовать менее процента от его возможностей. Кто там говорит, что это расточительство? Нет, расточительство — это выбрасывать елку в мусор после праздника. Полная декомпиляция в наши задачи не входит. Наша цель — локализация дислокации штаб-квартиры защитного механизма, то есть определение адресов процедур, проверяющих введенный пользователем регистрационный номер. Вот для этого нам и нужен DeDe, а все остальное можно сделать и руками. То есть дизассемблером. Вообще-то, в состав DeDe входит интегрированный дизассемблер в духе WIN32DASM, однако по своему качеству он значительно
уступает даже халявной версии IDA, не говоря уже о полном боекомплекте тяжелой артиллерии в виде IDA Pro + SoftICE. Это просто ужас какой-то! Это все равно что засунуть еловую ветку Стиву Б. в задницу, даже круче! Намного круче! ��

Последняя известная мне версия DeDe носит порядковый номер 3.50.02 и датируется серединой 2003 года. Похоже, что DaFixer полностью утратил интерес к своему детищу, решив похоронить DeDe на свалке истории. Полные исходные тексты версии 3.10b выложены в публичный доступ, однако желающих продолжить благородное дело что-то не наблюдается, и потому DeDe обречен на медленное и мучительное вымирание. Программы, собранные новыми компиляторами от Багдада, DeDe либо вообще не переваривает, либо декомпилирует неправильно (вот потому чуть позже мы рассмотрим, как ломать Борландию своими руками без посторонней помощи).

Архив DeDe.3.10b.realy.complete.src.zip (который, в частности, можно скачать с www.wasm.ru/baixado.php?mode=tool& >

В общем, значит, ставим мы DeDe и втыкаем в его философию. А философия эта такова, что декомпиляции подвергается не сам исполняемый файл, а образ запущенного процесса в памяти, за счет чего удается раздавить упаковщики, даже не почувствовав их присутствия. Впрочем, против крутых протекторов, шифрующих защищенную программу в памяти и динамически расшифровывающих ее по мере исполнения, DeDe оказывается бессилен, и вряд ли стоит объяснять почему. Однако крутые протекторы на практике встречаются не так уж часто, что очень радует.

Ладно, не будем впадать в депрессию. Ведь Новый год на дворе! И пока остальные рвут петарды, мы будем рвать себе задницу, декомпилируя интересные программы :). Все очень просто! Берем прогу, загружаем ее в DeDe, давим на кнопку «Процесс» и сидим себе в ожидании, пока DeDe распотрошит дамп памяти. Лучше всего это делать под VMware, а то среди защищенных программ есть всякие твари, начиненные AdWare и прочей малварью.

Честно говоря, я поубивал бы тех, кто придумал механизм идентификации типов в рантайме, благодаря которому названия классов не уничтожаются при компиляции (как в классическом Паскале и Си), а попадают непосредственно в исполняемый файл (как в Visual Basic’е). Взлом упрощается настолько, что ломать становится скучно. Никакого тебе интеллектуального поединка. Все равно что ломом добивать попавшую в капкан мышь.

Но мы же не садисты и не маньяки какие-нибудь. Оставим мышь любоваться праздничным салютом, а сами вернемся к DeDe. Самая левая (можно даже сказать: радикально левая) вкладка с именами классов не содержит для нас ничего интересного. Вкладки Units Info и Forms также отправляются в /dev/null или куда поглубже. А вот вкладка Procedures — это уже то, что нужно.

Открываем ее и смотрим. Ага, здесь перечислены юниты со всеми процедурами в них содержащимися. Причем и сами юниты, и имена классов, и названия событий (events) даны в символьном виде. То есть если в программе есть диалоговое окно регистрации, то DeDe покажет что-то типа: fRegister ? TfrmRegister ? bOKClick. Как нетрудно догадаться, bOKClick — это и есть имя процедуры, получающей управление при нажатии на кнопку ОК и занимающейся проверкой валидности введенного юзером серийного номера. Тут же в колонке RVA DeDe показывает ее относительный виртуальный адрес, по которому функцию легко найти в файле.

А можно и не искать! Двойной щелчок по имени функции открывает окно с интегрированным дизассемблером, перемещая наш хвост непосредственно на зловредный защищенный код, что особенно полезно при анализе упакованных файлов, которые бессмысленно загружать в Иду. DeDe дизассемблирует дамп памяти, и потому упаковщики идут лесом. Как вариант — можно заюзать SoftICE, установив по заданному адресу аппаратную точку останова (команда «BPM адрес X»). Необходимо только помнить, что RVA – это относительный виртуальный адрес, а SoftICE требует абсолютный. Чтобы перевести относительный виртуальный адрес в абсолютный, достаточно загрузить файл в hiew, нажать (header), посмотреть на базовый адрес
загрузки (base address) и сложить его с RVA-адресом, сообщенным DeDe.

Техника ручного взлома

Ураганный артиллерийский огонь декомпилятора DeDe накрывает практически весь Багдад, ставя моджахедов по стойке смирно, а всех несогласных отправляет на север, где они рубят пихтовый лес и гонят драп, чтобы у всех плановых жителей было по елке. В смысле ПО «Елки», программное обеспечение то есть :).

Недостатков у DeDe как минимум два. Первый: ломать автоматом — это не в кайф и вообще не по понятиям. Настоящие хакеры так не поступают, предпочитая во всем разбираться самостоятельно с помощью кедрового отвара из хрюнделя (в просторечии называемого hiew’ом) и топора. Второй: как уже говорилось, DeDe обречен на вымирание и скоро исчезнет с жестких дисков за ненадобностью, как в свое время исчезли динозавры и мамонты.

А потому во многих ситуациях ручной взлом оказывается намного предпочтительнее, а бывает так, что он становится вообще единственно возможным вариантом. Короче, кто как, а я сразу за демократию! Любовь и IDA Pro — во!

Берем, значит, Иду, переходим в начало сегмента данных (View\Open subviews\Segments или ) и прокручиваем его вниз до тех пор, пока не встретим текстовые названия элементов управления с прилегающими к ним ссылками. Дизассемблерный текст должен выглядеть так, как показано ниже.

Названия методов класса формы в исполняемом файле прямым текстом:

.data:0040E88B word_40E88B dw 0Bh ; DATA XREF: .data:0040E614^o
.data:0040E88D dw 11h
.data:0040E88F dd offset _TForm1_FormCreate
.data:0040E893 db 10,’FormCreate’
.data:0040E89E dw 12h
.data:0040E8A0 dd offset _TForm1_FormDestroy
.data:0040E8A4 db 11,’FormDestroy’
.data:0040E8B0 dw 17h
.data:0040E8B2 dd offset _TForm1_Comm1ReceiveData
.data:0040E8B6 db 16,’Comm1ReceiveData’
.data:0040E8C7 dw 13h
.data:0040E8C9 dd offset _TForm1_Button1Click
.data:0040E8CD db 12,’Button1Click’
.data:0040E8DA dw 13h
.data:0040E8DC dd offset _TForm1_Button4Click
.data:0040E8E0 db 12,’Button4Click’
.data:0040E8ED dw 13h
.data:0040E8EF dd offset _TForm1_Button2Click
.data:0040E8F3 db 12,’Button2Click’
.data:0040E900 dw 12h
.data:0040E902 dd offset _TForm1_Timer1Timer
.data:0040E906 db 11,’Timer1Timer’
.data:0040E912 dw 13h
.data:0040E914 dd offset _TForm1_Button3Click
.data:0040E918 db 12,’Button3Click’
.data:0040E925 dw 13h
.data:0040E927 dd offset _TForm1_Button5Click
.data:0040E92B db 12,’Button5Click’
.data:0040E938 dw 13h
.data:0040E93A dd offset _TForm1_Button6Click
.data:0040E93E db 12,’Button6Click’
.data:0040E94B dw 13h
.data:0040E94D dd offset _TForm1_Button7Click
.data:0040E951 db 12,’Button7Click’
.data:0040E95E aTform1 db 6,’TForm1′ ; DATA XREF: .data:0040E61C^o

Скажем сразу, это довольно сложный для взлома случай, поскольку программист использовал названия элементов по умолчанию, потому и получилось TForm1, Button1Click, Button2Click. Это не названия кнопок, это названия методов класса, отвечающих за обработку нажатий кнопок, а вот каким реально кнопкам они соответствуют, так сразу и не скажешь, поэтому придется хитрить.

Перемещаем курсор на название функции, автоматически назначенное Идой на основе текстовой строки (например, «_TForm1_Button3Click»), и нажимаем , переходя на ее тело, где мы видим) мы видим, что функция расположена по адресу, ну скажем, 040286Ch. Загружаем файл в hiew, нажимаем для перехода в шестнадцатеричный режим, давим (goto) и вводим адрес перехода (в данном случае «.040286C»). Точка в начале адреса сообщает hiew’у, что это действительно адрес, а не смещение (по умолчанию). Активируем режим редактирования по (Edit) и пишем CC – опкод точки останова, соответствующий машинной команде INT 03h. Сохраняем изменения по и выходим.

Запускаем программу, вызываем обозначенную форму и давим по очереди на все кнопки. Когда мы нажмем Button3, на экран выскочит системное сообщение о том, что у программы рвет крышу и она будет аварийно завершена в добровольно-принудительном порядке. Так и должно быть. В отсутствие отладчика команда INT 03h приводит к критической ошибке, что позволяет довольно быстро найти необходимые нам кнопки, после чего останется только хакнуть соответствующие им функции. Логично? Всенепременно!

Естественно, ручной просмотр секции данных непродуктивен и ненадежен. Так легко проглядеть нужные нам формы, особенно если программист обозвал методы классов короткими и невыразительными именами, особо не бросающимися в глаза, типа a, b, c. Как быть тогда? Очень просто! Указатель на вышеприведенную структуру передается библиотечной VCL-функции Forms::TApplication::CreateForm(System::TMetaClass *,void*) в качестве одного из аргументов. IDA распознает VCL-функции по сигнатурам, автоматически назначая им «неразмангленные» имена. Применительно к нашему случаю это будет @Forms@TApplication@CreateForm$qqrp17System@TMetaClasspv. Просто находим эту функцию и смотрим все перекрестные ссылки,
ведущие к местам ее вызова из программного кода. Ни одна форма не уйдет незамеченной!

Хорошо, а как быть, если в нашем распоряжении нету Иды, а есть только hiew? Первая мысль — идти топиться — отметается как идеологически неправильная. Топиться в Новый год — это по меньшей мере негуманно. У всех людей праздник, настроение соответствующие, и тут бац — дохлый труп с порезанными венами в ванной. Неэстетично! Таким путем мы приходим ко второй мысли: бедность — это не порок, а естественное студенческое состояние; и все, что нас не убивает, делает нас сильнее. Хорошо подумав головой, мы сумеем обойтись одним hiew’ом. Хотя почему бы на Новый год не подарить себе любимому лицензионную Иду?

Ладно, hiew так hiew. Это только с виду кажется, что hiew — беспонтовая программа. На самом деле это очень даже мощный зверь типа «гепард». Сильный и шустрый. К тому же компактный. Правда, увы, с некоторых пор далеко не бесплатный. Но найти hiew намного проще, чем Иду. Да и стоит hiew несоизмеримо дешевле, чем IDA Pro (это при его-то возможностях).

Короче, пока над нашими головами разрываются петарды и прочая реактивная китайская пиротехника, залетающая через открытую форточку, мы загружаем ломаемую программу прямо в hiew, нажимаем для перехода в шестнадцатеричный режим, давим (Header), говорим (Import) и в списке импортируемых функций находим __imp_@Forms@TApplication@CreateForm$qqrp17System@TMetaClasspv, поставляемую динамической библиотекой vclXX.bpl, где XX – номер версии, например 60. По переходим к таблице переходников на импортируемые функции, состоящей из множества команд jmp. Убедившись, что курсор стоит на функции __imp_@Forms@TApplication@CreateForm$qqrp17System@TMetaClasspv (что вовсе не факт,
поскольку тут у hiew’а глюк, и, чтобы его обойти, приходится выбирать соседнюю функцию, а потом поднимать курсор руками), нажимаем (Ref) для поиска перекрестных ссылок и видим код типа приведенного ниже. Соответственно, (NexRef) означает поиск следующей ссылки на процедуру создания формы. Вот мы и будем жать , пока не найдем все формы, какие только есть.

Поиск указателя на структуру формы в hiew’e:

.0040193A: 8B0DE01F4100 mov ecx,[00411FE0]
.00401940: 8B15FCE54000 mov edx,[0040E5FC]
.00401946: E8B9BF0000 call @Forms@TApplication@CreateForm$qqrp17System@TMeta
.0040194B: A134B65900 mov eax,@Forms@Application ;vcl60

Разумеется, это работает только с неупакованными программами, использующими статическую линковку, коих большинство. Если программа упакована, то, прежде чем мы доберемся до таблицы импорта, ее предстоит распаковать, а если разработчик задействовал динамическую компоновку, то один или несколько вызовов __imp_@Forms@TApplication@CreateForm$qqrp17System@TMetaClasspv останутся незамеченными (что плохо). В таких случаях выгоднее прибегнуть к отладчику, установив точку останова на __imp_@Forms@TApplication@CreateForm$qqrp17System@TMetaClasspv, но об этом мы скажем позже, а пока разберемся с аргументами.
Главным образом нас интересует аргумент, загружаемый в регистр EDX и указывающий на структуру, по смещению 18h от начала которой расположен указатель на уже знакомую тебе вложенную структуру.

Вокруг точек останова

Самые сложные случаи взлома — это упакованные программы, загружающие VCL-библиотеку на лету и не использующие никаких вразумительных имен в методах классов. Ломать такие защиты в дизассемблере — напрасно тратить время. Здесь лучше воспользоваться отладчиком, в роли которого может выступать не только тяжелая (SoftICE), но и легкая артиллерия в лице OllyDebbuger.

Остается только выбрать подходящие функции для бряканья. Краткий перечень наиболее важных из них (с точки зрения хакера) представлен ниже:

Праздничное заключение

Как видно, во взломе программ из Багдада ничего сложного нет, и они хакаются со скоростью пробки, вылетающей из бутылки шампанского. Даже еще быстрее! Так что подарок к Новому году обеспечен!

Полную версию статьи
читай в декабрьском номере Хакера! Последний релиз DeDe v. 3.50.02 ты можешь скачать с нашего сайта или взять на DVD

Borland delphi vcl faq

Если ваш компьютер работает под управлением операционной системы Windows, то вы не можете не знать о существовании динамических подсоединяемых библиотек (dynamic link libraries — DLL). Достаточно взглянуть на список файлов, расположенных в системном каталоге Windows — порой количество используемых операционной системой динамических библиотек достигает нескольких сотен. DLL являются неотъемлемой частью функционирования операционных систем семейства Microsoft Windows. Однако для вас может быть неочевидна необходимость использования динамических библиотек при разработке приложений. В рамках данной статьи мы поговорим о принципах функционирования DLL и их использования в процессе создания ваших собственных программ.

Для начала давайте выясним, что собой представляет динамическая подключаемая библиотека. Итак, DLL — это один или несколько логически законченных фрагментов кода, сохраненных в файле с расширением.dll. Этот код может быть запущен на выполнение в процессе функционирования какой-либо другой программы (такие приложения называются вызывающими по отношению к библиотеке), но сама DLL не является запускаемым файлом.

Существует два типа динамических библиотек — исполняемые и библиотеки ресурсов. Однако это не означает, что в одном файле не может находиться и код некоторой функции и какие-либо ресурсы. Просто иногда бывает удобно разнести реализацию исполняемых процедур и используемые приложением ресурсы в разные файлы.


Итак, процедуры и функции, содержащиеся в динамической библиотеке, можно разделить на два типа: те, которые могут быть вызваны из других приложений. Рассмотрим следующий пример:

LoadCursor — функция Windows API, которая вызывается приложением из динамической библиотеки User 32.dll. Кстати, примером хранимых в динамической библиотеке ресурсов могут являться такие стандартные диалоги Windows, как диалог открытия файла, диалог печати или настройки принтера. Эти диалоги находятся в файле Comctl32.dll. Однако многие прикладные разработчики используют функции вызова форм этих диалогов, совершенно не задумываясь, где хранится их описание.

Второй тип процедур — это те, которые используются только внутри самого файла библиотеки.

Аргументы в пользу использования DLL

Итак, прежде чем перейти к обсуждению структуры динамических библиотек, необходимо поговорить о тех преимуществах, которые предоставляет их использование разработчику. Во-первых, это повторное использование кода. Думаю, нет необходимости пояснять удобство использования один раз разработанных процедур и функций при создании нескольких приложений? Кроме того, в дальнейшем вы сможете продать некоторые из своих библиотек, не раскрывая исходных кодов. А чем тогда это лучше компонентов, спросите вы? А тем, что функции, хранящиеся в библиотеке, могут быть вызваны на выполнение из приложений, разработанных не на Object Pascal, а, например, с использованием C++Builder, Visual Basic, Visual C++ и т.д. Такой подход накладывает некоторые ограничения на принцип разработки библиотеки, но это возможно. Звучит заманчиво? Мне кажется, даже очень. Но это еще не все.

Во-вторых, использование DLL предоставляет возможность использования один загруженного в оперативную память кода несколькими приложениями. К примеру, если вы разрабатываете программное обеспечение для большого предприятия, то вполне возможно, что в различных созданных вами приложениях будут использоваться одни и те же функции, процедуры, формы и другие ресурсы. Естественно, что при выделении общих для нескольких приложений данных в DLL может привести к экономии как дискового пространства, так и оперативной памяти, иногда очень даже существенному.

В-третьих, следует поговорить вот о чем. Всего несколько лет назад при разработке программного обеспечения вы могли совершенно не волноваться относительно распространения ваших продуктов где-либо, кроме вашей страны. Я хочу сказать, что проблема перевода на другие языки текста на элементах управления (пункты меню, кнопки, выпадающие списки, подсказки), сообщений об ошибках и т.д. не стояла так остро, как сейчас. Однако, с повсеместным внедрением интернета у вас появилась возможность быстрой передачи готовых программных продуктов практически в любую точку мира. И что будут делать с вашей программой где-нибудь в Объединенных Арабских Эмиратах, если кроме как по-русски, она с пользователем общаться не умеет? Вы сами можете оценить этот эффект, если хоть раз на экране вашего компьютера вместо с детства знакомого русского языка появляется «арабская вязь» (например, из-за «сбоя» шрифтов). Итак, уже сейчас вы должны планировать возможность распространения ваших приложений в других странах (если, конечно, у вас есть желание получить как можно больше прибыли). Соответственно, встает вопрос быстрого перевода интерфейса вашей программы на другие языки. Одним из путей может являться создание ресурсов интерфейсов внутри DLL. К примеру, можно создать одно приложение, которое в зависимости от версии динамической библиотеки будет выводить сообщения на различных языках.

Естественно, выше приведены лишь некоторые из аргументов в пользу использования динамически подключаемых библиотек при разработке приложений. Итак, надеюсь, вы все еще заинтересованы в том, чтобы узнать, как, собственно, DLL создаются. Если так, то вперед.

Основы разработки DLL

Разработка динамических библиотек не представляет собой некий сверхсложный процесс, доступный лишь избранным. Если вы достаточно хорошо знакомы с разработкой приложений на Object Pascal, то вам не составит особого труда научиться работать с механизмом DLL. Итак, рассмотрим те особенности создания DLL, которые вам необходимо знать, а в завершении статьи разработаем свою собственную библиотеку.

Как и любой другой модуль, модуль динамической библиотеки имеет фиксированный формат. Взгляните на листинг, представленный ниже.

Первое, на что следует обратить внимание, это ключевое слово library, находящееся вверху страницы. Library определяет этот модуль как модуль библиотеки DLL. Далее идет название библиотеки. В нашем примере мы имеем дело с динамической библиотекой, содержащей единственную процедуру: HelloWorld. Причем обратите внимание, что данная процедура по структуре ничем не отличается от тех, которые вы помещаете в модули своих приложений. Ключевое слово exports сигнализирует компилятору о том, что перечисленные ниже функции и/или процедуры должны быть доступны из вызывающих приложений (т.е. они как бы «экспортируются» из библиотеки). Подробнее о механизме экспорта мы поговорим чуть позже.

И, наконец, в конце модуля можно увидеть ключевые слова begin и end. Внутри данного блока вы можете поместить код, который должен выполняться в процессе загрузки библиотеки. Достаточно часто этот блок остается пустым.

Как уже говорилось выше, все процедуры и функции, помещаемые в DLL, могут быть разделены на две группы: экспортируемые (вызываемые из других приложений) и локальные. Естественно, внутри библиотеки также могут быть описаны классы, которые в свою очередь содержат методы, но в рамках данной статьи я не буду на этом останавливаться.

Описание и реализация процедур и функций, вызываемых в пределах текущей DLL, ничем не отличаются от их аналогов в обычных проектах-приложениях. Их специфика заключается лишь в том, что вызывающая программа не будет иметь к ним доступа. Она просто не будет ничего знать об их существования, так же, как одни классы ничего не знают о тех методах, которые описаны в секции private других классов.

В дополнение к процедурам и функциям, DLL может содержать глобальные данные, доступ к которым разрешен для всех процедур и функций в библиотеке. Для 16-битных приложений эти данные существовали в единственном экземпляре независимо от количества загруженных в оперативную память программ, которые используют текущую библиотеку. Другими словами, если одна программа изменяет значение глобальной переменной a на 100, то для всех остальных приложений a будет значение 100. Для 32-битных приложений это не так. Теперь для каждого приложения создается отдельная копия глобальной области данных.

Экспорт функций из DLL

Как уже говорилось выше, для экспорта процедур и функций из DLL, необходимо использовать ключевое слово export. Еще раз обратите внимание на представленный выше листинг библиотеки MiFirstDll. Поскольку процедура HelloWorld определена как экспортируемая, то она может быть вызвана на выполнение из других библиотек или приложений. Существуют следующие способы экспорта процедур и функций: экспорт по имени и экспорт по порядковому номеру.

Наиболее распространенный способ экспорта — по имени. Взглянем на приведенный ниже текст:

Следует обратить внимание на то, что Delphi автоматически назначает порядковый номер каждой экспортируемой функции (процедуре) независимо от того, определяете вы его явно или нет. Явное определение индекса позволяет вам лично управлять порядковым номером экспортируемой функции или процедуры.

Для того, чтобы определить выполняется ли ваш кодек в DLL или в вызывающем приложении, можно воспользоваться глобальной переменной IsLibrary. Она принимает значение true в том случае, если код вызывается из библиотеки и false в случае выполнения процедуры или функции из вызывающего приложения.

Кроме этого, в поставку Delphi входит весьма полезная утилита tdump, которая предоставляет данные о том, какая информация экспортируется из указанной DLL.

Использование DLLProc

Выше я уже говорил о том, что код инициализации динамической библиотеки может быть помещен в блок begin. end. Однако кроме этого зачастую необходимо предусмотреть некоторые действия, выполняемые в процессе выгрузки DLL из оперативной памяти. В отличии от других типов модулей, модуль DLL не имеет ни секции initialization, ни секции finalization. К примеру, вы можете динамически выделить память в главном блоке, однако не понятно, где эта память должна быть освобождена. Для решения этой проблемы существует DLLProc — специальная процедура, вызываемая в определенные моменты функционирования DLL.

Для начала следует сказать о самой причине существования DLLProc. Динамическая библиотека получает сообщения от Windows в моменты своей загрузки и выгрузки из оперативной памяти, а также в тех случаях, когда какой-нибудь очередной процесс, использующий функции и/или ресурсы, хранящиеся в библиотеке, загружается в память. Такая ситуация возможно в том случае, когда библиотека необходима для функционирования нескольких приложений. А для того, чтобы вы имели возможность указывать, что именно должно происходить в такие моменты, необходимо описать специальную процедуру, которая и будет ответственна за такие действия. К примеру, она может выглядеть следующим образом:

Однако системе совершенно не очевидно, что именно процедура MyFirstDllProc ответственна за обработку рассмотренных выше ситуаций. Поэтому вы должны поставить в соответствие адрес нашей процедуры глобальной переменной DLLProc. Это необходимо сделать в блоке begin. end примерно так:

Ниже представлен код, демонстрирующий один из возможных вариантов применения DLLProc.

Как можно увидеть, в качестве признака того или иного события, в результате которого вызывается процедура MyFirstDll, является значение переменной Reason. Ниже приведены возможные значения этой переменной.

DLL_PROCESS_DETACH — библиотека выгружается из памяти; используется один раз;

DLL_THREAD_ATTACH — в оперативную память загружается новый процесс, использующий ресурсы и/или код из данной библиотеки;

DLL_THREAD_DETACH — один из процессов, использующих библиотеку, «выгружается» из памяти.

Загрузка DLL

Прежде чем начать использование какой-либо процедуры или функции, находящейся в динамической библиотеке, вам необходимо загрузить DLL в оперативную память. Загрузка библиотеки может быть осуществлена одним из двух способов: статическая загрузка и динамическая загрузка. Оба метода имеют как преимущества, так и недостатки.

Статическая загрузка означает, что динамическая библиотека загружается автоматически при запуске на выполнение использующего ее приложения. Для того чтобы использовать такой способ загрузки, вам необходимо воспользоваться ключевым словом external при описании экспортируемой из динамической библиотеки функции или процедуры. DLL автоматически загружается при старте программы, и Вы сможете использовать любые экспортируемые из нее подпрограммы точно так же, как если бы они были описаны внутри модулей приложения. Это наиболее легкий способ использования кода, помещенного в DLL. Недостаток метода заключается в том, что если файл библиотеки, на который имеется ссылка в приложении, отсутствует, программа откажется загружаться.

Смысл динамического метода заключается в том, что вы загружаете библиотеку не при старте приложения, а в тот момент, когда вам это действительно необходимо. Сами посудите, ведь если функция, описанная в динамической библиотеке, используется только при 10% запусков программы, то совершенно нет смысла использовать статический метод загрузки. Выгрузка библиотеки из памяти в данном случае также осуществляется под вашим контролем. Еще одно преимущества такого способа загрузки DLL — это уменьшение (по понятным причинам) времени старта вашего приложения. А какие же у этого способа имеются недостатки? Основной, как мне кажется, — это то, что использование данного метода является более хлопотным, чем рассмотренная выше статическая загрузка. Сначала вам необходимо воспользоваться функцией Windows API LoadLibrary. Для получения указателя на экспортируемой процедуры или функции должна использоваться функция GetProcAddress. После завершения использования библиотеки DLL должна быть выгружена с применением FreeLibrary.

Вызов процедур и функций, загруженных из DLL.

Способ вызова процедур и функций зависит от того, каким образом вы загрузили динамическую библиотеку, в которой эти подпрограммы находятся.

Вызов функций и процедур из статически загруженных DLL достаточно прост. Первоначально в приложении должно содержаться описание экспортируемой функции (процедуры). После этого вы можете их использовать точно так же, как если бы они были описаны в одном из модулей вашего приложения. Для импорта функции или процедуры, содержащейся в DLL, необходимо использовать модификатор external в их объявлении. К примеру, для рассмотренной нами выше процедуры HelloWorld в вызывающем приложении должна быть помещена следующая строка:

Ключевое слово external сообщает компилятору, что данная процедура может быть найдена в динамической библиотеке (в нашем случае — myfirstdll.dll). Далее вызов этой процедуры выглядит следующим образом:

При импорте функции и процедур будьте особенно внимательны при написании их имен и интерфейсов! Дело в том, что в процессе компиляции приложения не производится проверки на правильность имен объектов, экспортируемых из DLL, осуществляться не будет, и если вы неправильно описали какую-нибудь функцию, то исключение будет сгенерировано только на этапе выполнения приложения.

Импорт из DLL может проводиться по имени процедуры (функции), порядковому номеру или с присвоением другого имени.

В первом случае вы просто объявляете имя процедуры и библиотеку, из которой ее импортируете (мы это рассмотрели чуть выше). Импорт по порядковому номеру требует от вас указание этого самого номера:

В этом случае имя, которое вы даете процедуре при импорте не обязательно должно совпадать с тем, которое было указано для нее в самой DLL. Т.е. приведенная выше запись означает, что вы импортируете из динамической библиотеки myfirstdll.dll процедуру, которая в ней экспортировалась пятнадцатой, и при этом в рамках вашего приложения этой процедуре дается имя SayHello.

Если вы по каким-то причинам не применяете описанный выше способ импорта, но тем не менее хотите изменить имя импортируемой функции (процедуры), то можно воспользоваться третьим методом:

Здесь импортируемой процедуре CoolProcedure дается имя DoSomethingReallyCool. Вызов процедур и функций, импортируемых из динамически загружаемых библиотек несколько более сложен, чем рассмотренный нами выше способ. В данном случае требуется объявить указатель на функцию или процедуру, которую вы собираетесь использовать. Помните процедуру HelloWorld? Давайте посмотрим, что необходимо сделать для того, чтобы вызвать ее на выполнение в случае динамической загрузки DLL. Во-первых, вам необходимо объявить тип, который описывал бы эту процедуру:

Теперь вы должны загрузить динамическую библиотеку, с помощью GetProcAddress получить указатель на процедуру, вызвать эту процедуру на выполнение, и, наконец, выгрузить DLL из памяти. Ниже приведен код, демонстрирующий, как это можно сделать:

Как уже говорилось выше, одним из недостатков статической загрузки DLL является невозможность продолжения работы приложения при отсутствии одной или нескольких библиотек. В случае с динамической загрузкой у вас появляется возможность программно обрабатывать такие ситуации и не допускать, чтобы программа «вываливалась» самостоятельно. По возвращаемому функциями LoadLibrary и GetProcAddress значениям можно определить, успешно ли прошла загрузка библиотеки и найдена ли в ней необходимая приложению процедура. Приведенный ниже код демонстрирует это.

В DLL можно хранить не только код, но и формы. Причем создание и помещение форм в динамическую библиотеку не слишком сильно отличается от работы с формами в обычном проекте. Сначала мы рассмотрим, каким образом можно написать библиотеку, содержащую формы, а затем мы поговорим об использовании технологии MDI в DLL.

Разработку DLL, содержащую форму, я продемонстрирую на примере.

Итак, во-первых, создадим новый проект динамической библиотеки. Для этого выберем пункт меню File|New, а затем дважды щелкнем на иконку DLL. После этого вы увидите примерно следующий код:

Сохраните полученный проект. Назовем его DllForms.dpr.

Теперь следует создать новую форму. Это можно сделать по-разному. Например, выбрав пункт меню File|New Form. Добавьте на форму какие-нибудь компоненты. Назовем форму DllForm и сохраним получившийся модуль под именем DllFormUnit.pas.

Вернемся к главному модулю проекта и поместим в него функцию ShowForm, в задачу которой будет входить создание формы и ее вывод на экран. Используйте для этого приведенный ниже код.

Обращаю внимание, что для того, чтобы проект был скомпилирован без ошибок, необходимо добавить в секцию uses модуль Forms.

Экспортируем нашу функцию с использованием ключевого слова exports :

Компилируем проект и получаем файл dllforms.dll. Эти простые шаги — все, что необходимо сделать для создания динамической библиотеки, содержащей форму. Обратите внимание, что функция ShowForm объявлена с использованием ключевого слова stdcall. Оно сигнализирует компилятору использовать при экспорте функции соглашение по стандартному вызову (standard call calling convention). Экспорт функции таким образом создает возможность использования разработанной DLL не только в приложениях, созданных в Delphi.

Соглашение по вызову (Calling conventions) определяет, каким образом передаются аргументы при вызове функции. Существует пять основных соглашений: stdcall, cdecl, pascal, register и safecall. Подробнее об этом можно узнать, посмотрев раздел «Calling Conventions» в файле помощи Delphi.

Также обратите внимание, что значение, возвращаемое функцией ShowForm, соответствует значению ShowModal. Таким образом вы можете передавать некоторую информацию о состоянии формы вызывающему приложению.

Ниже представлено два листинга, первый из которых содержит полный код файла проекта DLL (модуль с формой здесь не приводится), а второй — модуль вызывающего приложения, в котором используется только что разработанная нами библиотека.

Прошу заметить, что при экспорте функции также было использовано ключевое слово stdcall.

Следует обратить особое внимание на работу с дочерними формами в DLL. Если, к примеру, в вызывающем приложении главная форма имеет значение свойства FormStyle, равным MDIForm, то при попытке вызова из DLL MDIChild-формы, на экране появится сообщение об ошибке, в котором будет говориться, что нет ни одной активной MDI-формы.

В тот момент, когда вы пытаетесь показать ваше дочернее окно, VCL проверяет корректность свойства FormStyle главной формы приложения. Однако в нашем случае все вроде бы верно. Так в чем же дело? Проблема в том, что при проведении такой проверки, рассматривается объект Application, принадлежащий не вызывающему приложению, а собственно динамической библиотеке. Ну, и естественно, поскольку в DLL нет главной формы, проверка выдает ошибку. Для того чтобы избежать такой ситуации, надо назначить объекту Application динамической библиотеки объект Application вызывающего приложения. Естественно, это заработает только в том случае, когда вызывающая программа — VCL-приложение. Кроме того, перед выгрузкой библиотеки из памяти необходимо вернуть значение объекта Application библиотеки в первоначальное состояние. Это позволит менеджеру памяти очистить оперативную память, занимаемую библиотекой. Следовательно, вам нужно сохранить указатель на «родной» для библиотеки объект Application в глобальной переменной, которая может быть использована при восстановлении его значения.

Итак, вернемся немного назад и перечислим шаги, необходимые нам для работы с помещенным в DLL MDIChild-формами.

  1. В динамической библиотеке создаем глобальную переменную типа TApplication.
  2. Сохраняем указатель на объект Application DLL в глобальной переменной.
  3. Объекту Application динамической библиотеки ставим в соответствие указатель на Application вызывающего приложения.
  4. Создаем MDIChild-форму и работаем с ней.
  5. Возвращаем в первоначальное состояние значение объекта Application динамической библиотеки и выгружаем DLL из памяти.

Первый шаг прост. Просто помещаем следующий код в верхней части модуля DLL:

Затем создаем процедуру, которая будет изменять значение объекта Application и создавать дочернюю форму. Процедура может выглядеть примерно так:

Все, что нам теперь необходимо сделать, — это предусмотреть возвращение значения объекта Application в исходное состояние. Делаем это с помощью процедуры MyDllProc:

Вместо заключения

Использование динамически подключаемых библиотек не так сложно, как это может показаться на первый взгляд. DLL предоставляют широчайшие возможности для оптимизации работы приложений, а также работы самих программистов. Используйте DLL и, возможно, ваша жизнь станет легче!

Илон Маск рекомендует:  Тег mark
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL