Как сделать регистрацию в делфи

Добавил пользователь Валентин П.
Обновлено: 05.10.2024

Компания Embarcadero в 2018 году представила Delphi Community Edition — бесплатную версию легендарной среды разработки Delphi. Использовать её могут студенты, стартаперы, небольшие команды, некоммерческие организации. Условия использования: ​лицензия на использование продолжает действовать до тех пор, пока прибыль физического лица или компании от приложений Delphi не достигнет 5 000 долларов США, или штат команды разработчиков не превысит 5 человек.

Мы ставим Delphi в учебных целях, поэтому ее можно использовать бесплатно. А после заработка первых 5 тысяч долларов её можно приобрести: цены начинаются от 98 999 руб. (почти $1600).

С помощью Delphi Community Edition можно разрабатывать мультиплатформенные приложения на Windows, Android, iOS и macOS. В этой статье мы пошагово пройдём процесс установки среды и напишем тестовое приложение под Windows. Delphi всегда был инструментом для быстрого старта в разработке под Windows на языке Pascal, это мы сегодня и проверим.

Примерное время установки: около 40-60 минут.

1. Скачивание бесплатной версии Delphi

На почту вам придёт письмо с ключом — его лучше сохранить. После отправки формы начнётся процесс загрузки. Если загрузка не начнётся, ссылка будет также в письме. Письмо вам необходимо — если оно не пришло, проверяйте спам. Если вообще не пришло, регистрируйтесь заново на другой ящик. Я регистрировался дважды на разные email — один на доменную почту, второй на Gmail. Оба раза всё было ок. Вот как выглядит письмо:

2. Установка Delphi Community Edition

Установка Delphi

На этом экране я нажал кнопку Оptions — открылось окно, где можно изменить каталог установки и настройки: ярлык на рабочем столе и установка для всех пользователей. Эти опции я оставил включёнными, вы можете убрать. Каталог установки можно оставить этот.

Установка Delphi - шаг 2

Начнётся установка, через несколько минут появилось окно для ввода данных регистрации (серийного номера):

Ввод серийного номера при установке бесплатной версии Delphi Community Edition

Введите Serial number из письма в почте и нажмите Register.

Проблемы при установке Delphi

Cистема предложит пройти на web-регистрацию. Соглашаемся — жмём Yes (или копируем предложенный URL в браузер). Откроется окно регистрации через сайт. Жмёте Download, чтобы скачать файл с лицензией в формате txt.

Его нужно будет использовать: в диалоге Product Registration нажать Advanced. Затем Import в следующем окне и импортировать файл лицензии. Надеюсь, у вас всё получится.

3. Выбор платформ для установки

Выбор плафторм для установки в среде Delphi: Windows и Android

В рамках наших ближайших статей мы будем рассматривать разработку под Windows и Android, поэтому я выбрал только их. Для работы с экосистемой Apple вам понадобится платный ключ разработчика, поэтому ставить iOS и macOS имеет смысл, если вы действительно планируете этим заниматься. В любом случае можно будет доустановить недостающие компоненты позже.

Установка Delphi

Установка завершена. Можно приступать к разработке

4. Первичная настройка среды разработки Delphi

Окно Delphi

Первое окно при загрузке Delphi

Жмём Next, на следующем экране можно подключить систему контроля версий (пока можно пропустить), включить автосохранение файлов и оформления темы (рекомендую поставить эту галку), а также выбрать папку для сохранения проектов по умолчанию. Я рекомендую создать какую-либо папку в корне, например C:\work

Первичная настройка среды разработки Delphi

5. Создание проекта программы на Delphi под Windows

Откроется Welcome Page, на ней нажмите Create Windows VCL Application, чтобы создать простое приложение под Windows. (Также можно это сделать с помощью верхнего меню File → New → Windows VCL Application — Delphi)

Создать Windows приложение

Главная форма приложения на Delphi

Сохранение проекта

В рабочем каталоге создайте папку HelloWorld, зайдите в неё. Сохраните файл Unit1.pas (это единственный модуль вашего приложения. Рекомендуется давать им более осмысленные названия, но сейчас мы этот шаг пропустим).

Затем сохраните файл проекта, назвав его HelloWorld.dproj (так будет называться ваше приложение, в том числе запускаемый exe-файл).

Сохранение проекта в Delphi

Название исполняемого файла (exe) соответствует имени проекта

6. Создание интерфейса приложения

Изменение заголовка формы на Delphi

Добавим кнопку на форму. Найдите в правом нижнем углу экрана палитру компонентов и нажмите на Standart — вам откроется набор популярных компонентов. Два раза щёлкните на компоненте TButton — кнопка появится в самом центре формы.

Выбрать кнопку в палитре компонентов Delphi

Вы можете изменить её размеры, ухватив за уголок и протянув в нужном направлении. Зажав левую кнопку мыши на элементе Button1 вы можете перетащить его на любой место формы. Поэкспериментируйте с этим, сделав кнопку покрупнее.

В инспекторе объектов (по аналогии с изменением заголовка Form1) поменяйте Caption кнопки на «Нажми меня!«. Окно проекта в Delphi будет выглядеть примерно так:

Изменение заголовка кнопки в Delphi

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

7. Написание кода и запуск приложения в среде Delphi

Самое время написать свою первую строку кода. Щёлкните два раза на кнопку Button1 (Button1 — имя объекта, на самой кнопке уже написано «Нажми меня!«). Откроется редактор кода. Delphi автоматически создало событие, которое произойдёт после щелчка по кнопке TForm1.Button1Click.

Отображение окна ввода пароля перед запуском главной формы

MainForm приложения Delphi - форма, которая создается первой в главном теле приложения.

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

MainForm Delphi

Когда создается новый проект Delphi, Form1 автоматически становится MainForm (глобальный объект Application). Чтобы назначить другую форму для свойства MainForm, используйте вкладку Формы диалогового окна Project | Options во время проектирования.

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

Диалоговое Окно Ввода Пароля

Давайте сначала создадим Главную форму приложения. Создайте новый проект Delphi, который содержит одну форму. Эта форма в соответствии с проектом - Главная форма.

Если Вы измените имя формы на TMainForm и сохраните модуль как main.pas, исходный текст будет таким (проект был сохранен как PasswordApp):

Теперь добавим вторую форму в проект.

В соответствии с проектом, когда вторая форма будет добавлена, она будет присутствовать в списке Auto-Create Forms в диалоговом окне Project Options.

Назовите вторую форму как TLoginForm и удалите ее из списка автоматически создаваемых форм. Сохраните этот модуль под именем login.pas.

Добавьте компоненты Label, Edit и Button на форму.

Добавьте метод класса для создания, отображения и закрытия диалогового окна ввода пароля. Метод Execute возвращает True, если Пользователь ввел правильный пароль в окне ввода пароля.

Вот полный исходный код:

Метод Execute динамически создает экземпляр TLoginForm и модально отображает его, используя метод ShowModal.

ShowModal не возвращается, пока форма не будет закрыта. Когда форма закрывается, она возвращает свойство ModalResult.

Обработчик события OnClick для LogInButton назначает mrOk свойству ModalResult, если Пользователь ввел правильный пароль (delphi в вышеупомянутом примере). Если Пользователь ввел неправильный пароль, ModalResult устанавливается в mrAbort (или что-нибудь вроде mrNone).

Установив значение ModalResult, форма закрывается. Execute возвращает True, если ModalResult равен mrOk, т.е. Пользователь ввел правильный пароль.

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

Исходный код проекта выглядит так:

Обратите внимание на использование, чтобы определить, была ли главная форма создана. Если Execute возвращает False, MainForm не создается, а приложение закрывается, даже не запустившись.

Пытаюсь добавить программно компонент на форму, зная только его имя класса в виде строки, в данном примере "TPanel". (Получаю из SomeObject.ClassName).

Так вот, как мне избавиться от ручного прописывания регистрации классов в блоке инициализации?
Создавать буду только стандартные визуальные компоненты, и вроде прописав строку "Controls" в uses классы должны были автоматом все зарегистрироваться.
Пытался делать так: RegisterClass(FindClass(stClassName));
Но видимо что-то не понимаю.

Может кто покажет и объяснит что да как?

procedure TForm1.Button1Click(Sender: TObject);
var
stClassName: String;
tContClass : TControlClass;
Control: TControl;
begin
stClassName := 'TPanel';
RegisterClass(FindClass(stClassName));
tContClass := TControlClass(FindClass(stClassName));
Control := tContClass.Create(self);
Control.Parent := self;
Control.Name := 'test';
Control.Show;
end;



Если не указывать в initiakization регистрацию класса - даёт ошибку, Class TPanel not found.
Если указываю - код работает.

Нужно избавиться от ручного приписывания всех классов компонент которые вздумается создать, при условии что они стандартные и уже включены - Tedit, Tbutton, Tmemo и т.д.

Tpanel отобразится, с 0 позициями и с шириной/высотой по caption, который автоматом берётся из name


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

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

ZZ, но по вашему коду такая реакция вполне объяснима.
по шагам:
1. Регистрируете класс TPanel (initialization)
2. задаете строку с именем класса
3. ищите класс и регистрируете его по-новой
4. TControlClass - для меня загадка, может от жизни отстал
5. создаете экземпляр класса-загадки (НЕ TPanel!)

уберите строку RegisterClass(FindClass(stClassName)); и код должен работать. Initialization - всего-лишь секция в которой код выполниться в первую очередь (относительно unit-a)
А вообще к чему такое? Могу предположить, что-то вроде конструктора пишешь?


Цитата:
procedure TForm1.Button1Click(Sender: TObject);
var
stClassName: String;
tContClass : TControlClass;
Control: TControl;
begin
stClassName := 'TPanel';
RegisterClass(FindClass(stClassName)); - строка ровным счетом ничего не делает, забыл убрать.
tContClass := TControlClass(FindClass(stClassName));
Control := tContClass.Create(self);
Control.Parent := self;
Control.Name := 'test';
Control.Show;
end;

Это будет сериализация и десериализация объектов по шаблону. С помощью TMemoryStream, методами WriteComponent, ReadComponent.

Т.е. я на форме размещаю TPanel, на него кидаю TLabel, TEdit и прчие контролы. Прописываю им свойства позиционирования, стили и прочее.
Дальше, я хочу плодить N-ое количество таких вот TPanel, меняя свойства Caption и иногда Color.
Шаблон будет преобразовываться в удобочитаемый вид и храниться в текстовом файле, что бы менять его без IDE. Поэтому, я не могу наверняка знать какие классы будут использоваться, что бы прописывать их в initialization.

Клонирование на уровней одного объекта (пустой панели) работает, если не начать пытаться копировать дочерние. Сейчас вот я и пытаюсь сделать это для дочек. Т.к. что бы применить считаные параметры и свойства к объекту, нужно его создать, а что бы создать - нужен указатель (?) на его класс,а указатель на его класс я могу только получив в виде строки, пробежавшись по всем дочерним компонентам и получив ClassName.

Модель COM предоставляет возможность создания многократно используемых компонентов, независимых от языка программирования. Такие компоненты называются COM-серверами и представляют собой исполняемые файлы (EXE) или динамические библиотеки (DLL), специальным образом оформленные для обеспечения возможности их универсального вызова из любой программы, написанной на поддерживающем COM языке программирования. При этом COM-сервер может выполняться как в адресном пространстве вызывающей программы (In-Process-сервер), так и в виде самостоятельного процесса (Out-Of-Process-сервер) или даже на другом компьютере (Distributed COM). COM автоматически разрешает вопросы, связанные с передачей параметров (Marshalling) и согласованием потоковых моделей клиента и сервера.

Далее будут рассмотрены некоторые архитектурные вопросы, знание которых необходимо для работы с COM.

COM-сервер
Сервер в виде DLL

Такой сервер всегда выполняется в адресном пространстве активизировавшего его приложения (In-Process). За счет этого, как правило, снижаются накладные расходы на вызов методов сервера. В то же время такой сервер менее надежен, поскольку его память не защищена от ошибок в вызывающем приложении. Кроме того, он не может выполняться на удаленной машине без исполнимого модуля-посредника, способного создать процесс, в который может быть загружена DLL. Примером такого модуля может служить Microsoft Transaction Server.

Сервер в виде исполнимого файла

Этот сервер представляет собой обычный исполнимый файл Windows, в котором реализована возможность создания COM-объектов по запросу других приложений. Примером такого сервера может служить пакет Microsoft Office, приложения которого являются COM-серверами.

Серверы в виде исполняемых файлов автоматически регистрируются при первом запуске программы на компьютере. Для регистрации серверов DLL служит программа Regsvr32, поставляемая в составе Windows, либо TRegSvr из поставки DELPHI.

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

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

Недостатки STA напрямую вытекают из ее реализации:

  1. Дополнительные (и иногда излишние) затраты на синхронизацию при вызове методов.
  2. Невозможность отклика на вызов метода, пока не исполнен предыдущий. Например, если в настоящее время выполняется метод, требующий одну минуту на исполнение, то до его завершения COM-объект будет недоступен.

Тем не менее STA, как правило, является наиболее подходящим выбором для реализации COM-сервера. Использовать MTA есть смысл только в том случае, если STA не подходит для конкретного сервера.

Передача интерфейсов и параметров
  1. Реализовать на сервере интерфейс IMarshal и, при необходимости, — proxy-DLL, которая будет загружена на клиенте для реализации proxy. Подробности реализации описаны в документации COM и MSDN.
  2. Описать интерфейс на языке IDL (Interface Definition Language) и при помощи компилятора MIDL фирмы Microsoft сгенерировать proxy-stub-DLL.
  3. Сделать сервер совместимым с OLE Automation. В этом случае COM сам создаст proxy, используя описание сервера из его библиотеки типов — специального двоичного ресурса, описывающего COM-интерфейс. При этом в интерфейсе можно использовать только типы данных, совместимые с OДУ Automation.
Инициализация COM

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

Каждый вызов CoInitializeEx должен иметь соответствующий вызов CoUninitialize, то есть, используя COM в приложении, необходимо вызвать CoInitializeEx до первого использования функций COM и CoUninitialize перед завершением работы приложения. VCL реализует автоматическую инициализацию COM при использовании модуля ComObj. По умолчанию создается STA. При желании необходимость использовать другую потоковую модель следует установить флаг инициализации COM до оператора Application.Initialize:

Если COM используется в потоке, то эти функции должны быть вызваны в методе Execute:

Инициализация COM необходима и для вызова любых функций Windows API, связанных с COM, за исключением CoGetMalloc, CoTaskMemAlloc, CoTaskMemFree и CoTaskMemReAlloc.

Параметр ThreadingModel может принимать следующие значения:

Если этот параметр не задан, сервер имеет потоковую модель Single. В этом случае он создается в Primary STA (то есть в STA потока, который первым вызвал CoInitialize), даже если создание сервера запрошено из потока, имеющего свою отдельную STA.

Активация сервера

Для активации COM-сервера клиент должен вызвать функцию CreateComObject, описанную в модуле ComObj.pas:

Функция получает в качестве параметра CLSID требуемого объекта и возвращает ссылку на его интерфейс IUnknown. Далее клиент может запросить требуемый интерфейс и работать с ним:

Что же делает COM при запросе на создание сервера?

По завершении работы с COM-объектом клиент освобождает ссылку на него (что приводит к вызову метода Release). В этот момент COM-сервер проверяет, есть ли еще ссылки на созданные им объекты. Если все объекты освобождены, то COM-сервер завершает свою работу. В случае если он реализован в виде DLL, он должен экспортировать функцию DllCanUnloadNow, которая вызывается COM по таймеру или при вызове функции API CoFreeUnusedLibraries. Если все объекты из этой DLL освобождены, она выгружается из памяти.

Создание COM-сервера

Для создания COM-сервера Delphi предоставляет широкий набор мастеров, автоматизирующих выполнение рутинных задач и позволяющих программисту сконцентрироваться на реализации функциональности. Мастера доступны при помощи команды меню File->New, на закладке ActiveX.

Чтобы сделать COM-сервером EXE-файл, необходимо просто добавить в него модуль с COM-объектом. Для создания COM-сервера в виде DLL потребуется сначала создать библиотеку, оформленную с учетом требований COM. Это делается при помощи мастера ActiveX Library. При его выборе будет создан новый проект, реализующий DLL, и сгенерирован следующий код:

Созданная DLL экспортирует функции, необходимые для работы COM, при этом можно не отвлекаться на рутинную работу и сразу приступить к реализации COM-сервера.

От заполнения полей этой формы зависит реализация создаваемого COM-объекта:

Для поддержки OleAutomation-маршалинга необходимо:

  • чтобы сервер был унаследован от TTypedComObject (реализация IDispatch не обязательна);
  • все методы интерфейса были объявлены как safecall. Если вы создаете интерфейс, унаследованный от IUnknown, то по умолчанию все его методы объявляются как stdcall. Чтобы создать safecall-методы, необходимо в диалоге Tools>Environment Options на закладке Type Library установить переключатель Safecall function mapping в значение All v-table interfaces.
Сервер без библиотеки типов

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

Для реализации сервера требуется написать интерфейсный модуль с описанием реализуемого интерфейса. Кроме того, вынесем в него описание константы Class_Test и добавим его в строку uses модуля Unit1:

Этот модуль содержит всю необходимую информацию для работы сервера и должен использоваться при компиляции клиента.

Дополним код COM-объекта реализацией методов реализуемого интерфейса:

Откомпилировав проект, мы получим файл Project1.dll.

Последним шагом является регистрация COM-сервера.

Теперь можно приступать к написанию клиента. Для этого создадим новый проект, добавим в модуль с его главной формой строку uses TestInterface и напишем следующий код:

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

Сервер с библиотекой типов

Библиотека типов — это специальный двоичный ресурс, описывающий интерфейсы и методы, реализуемые COM-сервером. Кроме наличия библиотеки типов сервер должен поддерживать интерфейс IProvideClassInfo. В Delphi такой сервер реализуется путем наследования его от TTypedComObject. Для этого оставьте флажок Include Type Library в мастере создания COM-объекта включенным.

Создадим COM-сервер в виде EXE (разумеется, он может быть также создан и виде DLL).

Сначала создадим новый проект — File-New Application, а затем добавим в него COM-объект.

Если не отключать флажок Include Type Library, то мастер создаст уже не один, а два модуля. Первый из них напоминает созданный ранее.

Наиболее интересна строка: uses … Project1_TLB. Это автоматически сгенерированный интерфейсный модуль к нашему COM-объекту (аналогично TestInterface.pas в предыдущем примере). Он содержит описание всех необходимых для работы с сервером интерфейсов. В отличие от предыдущего примера, вам не придется редактировать его вручную. Для этого Delphi откроет редактор библиотеки типов:

Добавим описание нового метода. Для этого щелкнем правой кнопкой мыши на интерфейсе ITest и выберем из контекстного меню опцию New->Method. Введем имя метода — ShowIt.

А в модуле Unit1:

Нам остается лишь написать реализацию метода:

Для регистрации сервера достаточно один раз запустить его на компьютере клиента.

Перейдем к написанию приложения-клиента. При наличии модуля Project_TLB оно ничем не будет отличаться от предыдущего примера. Более интересен случай, когда мы имеем только исполняемый файл с сервером. Зарегистрируем этот сервер и выберем в меню Delphi IDE команду Project -> Import Type Library.

В открывшемся окне найдем строку с описанием библиотеки типов требуемого сервера.

Если включен флажок Generate Component Wrappers, то в импортированный модуль будет добавлен код для создания компонента Delphi, который можно поместить на форму — и он автоматически создаст требуемый COM-сервер и позволит обращаться к его методам. В противном случае будет сгенерирован модуль, содержащий описание всех имеющихся в библиотеке типов интерфейсов.

Далее необходимо определить, что вы собираетесь сделать с выбранной библиотекой:

Таким образом, для распространения и использования сервера не требуется ничего, кроме его исполнимого модуля. Но это не самое главное. Гораздо более важно, что вы можете импортировать и использовать в своей программе любой из имеющихся на компьютере COM-серверов. Естественно, что при передаче своей программы клиенту вы должны установить на его компьютере соответствующий COM-сервер.

Для примера используем в своем приложении процессор регулярных выражений VBScript. Импортируем библиотеку типов Microsoft VBScript Regular Expressions.

При этом будет создан файл VBScript_RegExp_TLB.pas.

Создадим форму и добавим следующий код для проверки вхождения текста, содержащегося в компоненте Edit1, в текст, содержащийся в компоненте Edit2:

Это все! Мы получили в своем приложении поддержку регулярных выражений — такую же, как и та, что включена в скриптовые языки Microsoft (VBScript и JScript).

Создание Plug-In в виде COM-сервера

Обратите внимание, что метод ILoadFilter.Init больше не получает ссылки на внутренний API программы — он будет реализован в виде COM-объекта.

Создадим DLL c COM-сервером, реализующим ILoadFilter. Для этого создадим новую ActiveX-библиотекуи добавим в нее COM-объект TLoadFilter. Установим ThreadingModel в Single, поскольку использование сервера в потоках не предусмотрено. После этого реализуем методы интерфейса ILoadFilter:

Деструктор и метод GetNextLine аналогичны предыдущему примеру:

Метод Init имеет существенное различие — теперь ссылку на внутренний API программы мы получаем при помощи COM. Это освобождает нас от необходимости передавать ссылку в модуль расширения.

В конце модуля находится код, автоматически сгенерированный Delphi для создания фабрики объектов:

Компилируем DLL и регистрируем ее при помощи regsvr32.

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

Параметром строки служит CLSID сервера, реализующего фильтр. В нашем случае это содержание константы Class_LoadFilter. Для подключения дополнительных фильтров необходимо создать DLL с сервером, реализующим ILoadFilter, зарегистрировать ее в системе и добавить CLSID сервера в INI-файл.

Теперь можно приступить к написанию программы-клиента. Она аналогична используемой в предыдущем примере. Добавим в нее COM-сервер, реализующий внутренний API.

За исключением кода, сгенерированного COM, этот объект полностью аналогичен объекту, приведенному ранее. Константу Class_TAPI вынесем в модуль PluginInterface, чтобы сделать ее доступной для модулей расширения:

Теперь все готово к реализации функциональности клиента. В целях экономии места приведем лишь метод LoadData:

Очевидно, что код метода стал гораздо более коротким и читабельным. COM взял на себя всю черновую работу по поиску, загрузке и и выгрузке DLL, поиску и созданию объектов.

Внимание! Поскольку в EXE и DLL используются длинные строки, не забудьте включить в список uses обоих проектов модуль ShareMem.

Автоматическая регистрация серверов из своей программы

Удобно в своей программе автоматически регистрировать все необходимые серверы. Это можно сделать при помощи следующей процедуры:

Читайте также: