Разработка программы для автоматизации работы кардиоцентра
Курсовой проект - Компьютеры, программирование
Другие курсовые по предмету Компьютеры, программирование
рмы в DLL:
procedure ShowNonModalForm(AppHandle:THandle); stdcall; export; .Handle:=AppHandle; TForm1.Create(Application) do Show;
end;
Как и при показе модальных форм, необходимо присвоить дескриптор окна главного приложения приложению, создаваемому в DLL, - иначе на панели задач будут показаны две иконки. Затем просто создается форма и вызывается ее метод Show. Такой способ показа немодальных форм приводит к тому, что из главного приложения можно неоднократно вызвать данный метод и тем самым создать несколько экземпляров форм. Зачастую это оправданно, поскольку одинаковые типы форм могут содержать, например, разные документы. Но при этом способе показа рекомендуется сделать обработчик события OnClose для TForm1 и присвоить параметру CloseAction значение caFree - в противном случае при закрытии форма будет спрятана [NE5][U6] на экране без освобождения системных ресурсов.
Для показа единственного экземпляра немодальной формы следует немного изменить код:
procedure ShowSingleNonModalForm(AppHandle:THandle); stdcall; export; .Handle:=AppHandle; Assigned(Form2) then Form2.Show else begin :=TForm2.Create(Application); .Show;
end; ;
Первоначально необходимо проверить, была ли создана форма ранее. Если была - просто вызывается ее метод Show; если нет - вызывается тот же метод после отработки конструктора. Вызов метода Show для уже созданного экземпляра формы имеет смысл, поскольку пользователь может обратиться к команде показа формы в тех случаях, когда уже имеющийся экземпляр перекрыт другими окнами и незаметен на экране, - использование команды Show приводит к всплытию формы. Переменная Form2 является глобальной переменной.
Оба описанных выше способа вызова немодальных форм не требуют создания специальной процедуры для их разрушения. Ресурсы будут корректно освобождены при закрытии приложения, так как приложение является владельцем форм. Код приложения для тестирования этих методов выглядит следующим образом:
procedure ShowNonModalForm(AppHandle:THandle); stdcall;NMStat.dll name ShowNonModalForm;ShowSingleNonModalForm(AppHandle:THandle); stdcall;NMStat.dll name ShowSingleNonModalForm;
TForm1.Button1Click(Sender: TObject); (Application.Handle); ;
TForm1.Button2Click(Sender: TObject); (Application.Handle); ;
Иногда возникает необходимость показа немодальных форм из динамически загружаемых DLL, например при редком использовании в приложении немодальных форм для экономии ресурсов. Если реализовать код так же, как и при показе модальных диалогов, то форма будет создана и, может быть, даже показана на экране. Но после этого произойдет выгрузка DLL, а затем немедленно последуют исключения, поскольку в памяти компьютера будет отсутствовать код для работы с элементами управления формы. Традиционное решение этой проблемы выглядит следующим образом: загружается динамическая библиотека, в качестве одного из параметров передается адрес метода главного приложения, который будет вызван при закрытии немодальной формы - обычно в обработчике события OnDestroy. Этот метод должен информировать главное приложение о необходимости выгрузки DLL из памяти компьютера, но DLL должна выгружаться после завершения его работы (и, следовательно, после завершения работы деструктора формы) - иначе возможно исключение из-за отсутствия кода в памяти компьютера. Выгрузка DLL после завершения работы приложения [U7] достигается с использованием асинхронной развязки - посылки сообщения методом PostMessage какому-либо окну приложения, обычно главной форме. Приведем код реализации данной технологии в DLL:
=procedure; stdcall;
TForm1 = class(TForm) : TMemo; FormDestroy(Sender: TObject); FormClose(Sender: TObject; var Action: TCloseAction);
{ Private declarations }
{ Public declarations } :TNotifyClose; ;
: TForm1;
{$R *.DFM}
TForm1.FormDestroy(Sender: TObject); Assigned(FNC) then FNC; ;
DynNonmodal(AppHandle:THandle; NC:pointer); stdcall; export; .Handle:=AppHandle; Assigned(Form1) then Form1.Show else begin :=TForm1.Create(Application); .FNC:=TNotifyClose(NC);
Form1.Show; ; ;
Приложение, использующее эту DLL, имеет следующий код (WM_DLLUNLOAD определена как константа в секции interface модуля):
type =procedure(AppHandle:THandle; NC:pointer); stdcall;
ReceiveCloseNotify; stdcall; .ProcessMessages; (Form1.Handle,WM_DLLUNLOAD,0,0); ;
HINSTANCE_ERRORthenFreeLibrary(FHLIB);:=0;(Libraryunloaded);;">TForm1.WMDLLUnload(var Message:TMessage); .ProcessMessages; FHLib>HINSTANCE_ERROR then FreeLibrary(FHLIB); :=0; (Library unloaded); ;
HInstance_Errorthenbegin:=GetProcAddress(FHLib,DynNonmodal);Assigned(DM)thenDM(Application.Handle,@ReceiveCloseNotify);">TForm1.Button3Click(Sender: TObject); :TDynNonmodal; FHLIBHInstance_Error then begin :=GetProcAddress(FHLib,DynNonmodal); Assigned(DM) then DM(Application.Handle,@ReceiveCloseNotify);
end; ;
Очевидно, что код получается довольно громоздким: в главном приложении необходимо реализовывать три метода вместо одного. Альтернативный вариант можно предложить исходя из того, что в DLL имеется объект TApplication, который может поддерживать цикл выборки сообщений. Но в DLL нельзя создать форму, используя метод TApplication. CreateForm, так как соответствующая закладка диалога Project/Options/Forms отсутствует в проектах Delphi 4 и 5 и неактивна в Delphi 3. Однако можно вызвать все методы объекта Tapplication, вручную дописав соответствующий код в DLL:
procedure ShowNMApplication; stdcall; export; Assigned(Form1) then begin .Show; ; else begin .Initialize; .CreateForm(TForm1, Form1); .Run; .Free; :=nil; ; ;
Следует обратить внимание, что дескриптор главного приложения не присваивается в данном проекте дескриптору TApplication в DLL. Это реально приводит к появлению двух пиктограмм на панели приложений. Правда, в некоторых случаях это полезно - так легче добраться до перекрытых окон. Интересно отметить, что в Delphi 3 после написания данного кода становятся доступными элементы управления диалога Project/Options/Forms, где можно определить автоматически создаваемые формы и главную форму приложения. Код главного приложения, использующий данную DLL, таков:
t