Немодальный окна в динамических библиотеках
3.1. Прибавить одну экспортную процедуру FreeAbout с индексом П. Теперь будут экспортироваться две процедуры:
exports ShowAbout index 10;
exports FreeAbout index 11;
3.2. Перейти в модуль unitl, где находится форма динамической библиотеки. Процедуру ShowAbout превратить в функцию, которая будет возвращать значение типа Longint. Как значение, которое возвращается будет идентификатор окна, за которым потом будем его закрывать.
3.3. Прибавить процедуру FreeAbout с одним параметром типа Longint.
function ShowAbout (Handle: THandle) : Longlnt; export; stdcall;
procedure FreeAbout (FormRef: Longint); export; stdcall;
Динамические библиотеки не могут хранить переменных, потому после создания окна необходимо повернуть идентификатор основной программы, чтобы она сохранила эту переменную. Когда нужно будет закрыть окно, передадим этот идентификатор библиотеке, и она освободит память, выделенную под окно.
3.4. Реализация функции Showabout :
function ShowAbout (Handle: THandle) : Longint;
begin
Application.Handle: = Handle;
Forml: = TForml.Create (Application);
Forml.Show;
Result: = LongInt (Forml);
end;
Здесь все осталось так же, за исключением последней строки. Если раньше мы освобождали память, то сейчас возвращаем окно Forml, приведенное к типу integer. Если бы мы здесь вызывали метод Free, то окно сразу же после появления закрылось бы.
3.5. Реализация функции Freeabout :
procedure FreeAbout (FormRef: Longint);
begin
if FormRef> 0 then
TForml (FormRef). Free;
end;
В этой процедуре сначала проверяется, если переменчивая FormRef (идентификатор окна) больше нуля, то окно можно уничтожать, иначе оно могло быть уже уничтожено. Во второй строке вызываем метод Free окна. Так как переменчивая FormRef - это числовая переменная и у нее нет методов, то необходимо перевести ее обратно к объекту TForml (FormRef).
3.6. Изменить объявление процедур библиотеки. Перед разделом type написать следующее:
function ShowAbout (Handle: THandle) : Longint; stdcall;
procedure FreeAbout (FormRef: Longint); export; stdcall
В разделе var написать следующее:
function ShowAbout; external 'ProjectDLL.DLL' index 10;
procedure FreeAbout; external 'ProjectDLL.DLL' index 11;
3.7. В разделе private объекта главной формы прибавить переменную f типа LongInt.
3.8. Прибавить на форму еще одну кнопку. При нажатии первый будем показывать окно:
procedure TForml.ButtonlClick (Sender: TObj ect);
begin
f: = ShowAbout (Handle);
end;
Здесь вызываем функцию показа окна и храним результат в переменной.
3.9. При нажатии кнопки второе вызывать процедуру освобождения памяти (событие Onclick) :
procedure TForml.Button2Click (Sender: TObject);
begin
FreeAbout (f);
end;
3.10. Запустите пример и убедитесь, что все работает корректно. Самое сложное здесь - определить, когда пользователь самостоятельно закрыл окно (например, кнопкой Закрыть в нашем окне О программе), чтобы мы вызывали процедуру FreeAbout. Для решения такой проблемы можно посоветовать следующее. При старте программы надо присваивать переменной f значения 0. В этом случае будем застрахованы от попадания у нее случайного числа. Перед созданием окна вызывать FreeAbout. В этом случае сначала будет происходить проверка переменной f на 0. Если переменная больше 0, то окно уже создавалось, но память не освободилась. Вот обновленный код нажатия кнопки показа диалогового окна :
procedure TForml.ButtonlClick (Sender: TObject);
begin
if f> 0 then
FreeAbout (f);
f: = ShowAbout (Handle);
end;
Здесь идет проверка, если f больше нуля, то надо освободить память от старого окна, а потом пытаться создавать новое. За события OnClose для главной формы тоже не помешает вызывать процедуру освобождения памяти. Если программа закрывается, то окно из библиотеки уже точно уже не понадобится, значит, переменную f можно проверять на 0, и если там большее значение, то освобождать память.
Дата добавления: 2016-02-27; просмотров: 560;