Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.149.239.110] |
|
Сообщ.
#1
,
|
|
|
Ситуация следующая...
В библиотеке (dll) существует функция function CreateComponent(const Owner: TWinControl; const xml: IXmlElement): TWinControl; export; begin Result := TEdit.CreateParented(Owner.Handle); Result.Parent := Owner; end; В основном приложении происходят операции: var component: TWinControl; f: function (const Owner: TWinControl; const xml: IXmlElement): TWinControl; ... begin ... lib := LoadLibrary('components\qcEdit\modEdit.dll'); @f := GetProcAddress(lib, 'CreateComponent'); ... if(@f<>nil)and(component=nil)then begin component := f(Self, tag); component.Top := 20; component.Left := 10; end; ... end; При вызове функции ошибка возникает на строке, где происходит привязка Parent := Owner... Текст ошибки следующий: Cannot assign a TFont to a TFont Если использовать родительскую привязку не по компоненту, а по окну... то компонент создается на форме, но: 1) не наследует свойств (шрифт, форма) от родителя 2) не обрабатывает никакие события (изменение, щелчек) и т.д. Как можно обойти эту проблему так, чтобы создаваемый из библиотеки компонент, мог спокойно обрабатывать стандартные события? Спасибо! |
Сообщ.
#2
,
|
|
|
Такое уже встрачалось вроде недавно. Поищи по форуму.
В-общем большинство решило, что надо использовать пакеты времени выполнения *.bpl. |
Сообщ.
#3
,
|
|
|
Ну мне интуиция подсказывала уже что надо попробовать... только вот я пока логического объяснения не нашел...
Если кто может, объясните пожалуйста почему так происходит? |
Сообщ.
#4
,
|
|
|
такой бок был когда я пытался фрейм из DLL выколупать:)
Цитата Technology @ Если кто может, объясните пожалуйста почему так происходит? лично я беспонятия:( |
Сообщ.
#5
,
|
|
|
.DeV!L как ты таки с фреймом решил?
|
Сообщ.
#6
,
|
|
|
Цитата Technology @ Если кто может, объясните пожалуйста почему так происходит? Разное адресное пространство классов. Хотя названия классов одинаковые, но для ДЛЛ и приложения они разные. При использовании BPL и компиляции программы с пакетами, адресное пространство кода классов одинаковое, поскольку классы загружаются только из BPL. |
Сообщ.
#7
,
|
|
|
Цитата s-mike @ Разное адресное пространство классов. Хотя названия классов одинаковые, но для ДЛЛ и приложения они разные. При использовании BPL и компиляции программы с пакетами, адресное пространство кода классов одинаковое, поскольку классы загружаются только из BPL. ... i chto? Problema ne imeyet resheniy? |
Сообщ.
#8
,
|
|
|
Цитата DeltaX @ ... i chto? Problema ne imeyet resheniy? Решение тебе написали . Но ты почему то его проигнорировал.. |
Сообщ.
#9
,
|
|
|
Держи пример.
library CreateControlInDLL; uses windows, Classes, Controls, Forms, Dialogs, StdCtrls; type TDummy=class private class procedure BtnClick(Sender: TObject); end; var onClick: TNotifyEvent; function CreateEdit(aParent: HWND): TEdit; begin Result := TEdit.Create(nil); Result.ParentWindow := aParent; end; procedure DeleteEdit(Edit: TEdit); begin Edit.Free; end; class procedure TDummy.BtnClick(Sender: TObject); begin ShowMessage('ok'); end; function CreateFormInDLL: TForm; var L: TButton; begin Result := TForm.Create(nil); Result.Position := poScreenCenter; Result.Width := 200; Result.Height := 180; OnClick := TDummy.BtnClick; L := TButton.Create(Result); L.OnClick := OnClick;; L.Parent := Result; L.Width := 60; L.Caption := 'ClickMe'; L.Left := (Result.Width-L.Width) div 2; L.Top := Result.Height-L.Height-30; end; procedure DeleteFormInDll(Form: TForm); begin Form.Free; end; exports CreateEdit, DeleteEdit, CreateFormInDLL, DeleteFormInDll; end. Пример использования: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; function CreateEdit(aParent: HWND): TEdit; external 'CreateControlInDLL.dll'; procedure DeleteEdit(Edit: TEdit); external 'CreateControlInDLL.dll'; function CreateFormInDLL: TForm; external 'CreateControlInDLL.dll'; procedure DeleteFormInDll(Form: TForm); external 'CreateControlInDLL.dll'; var Form1: TForm1; Ed: TEdit; f: TForm; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin Ed := CreateEdit(Form1.Handle); if not Assigned(f) then f := CreateFormInDLL; f.ShowModal; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin if Assigned(f) then DeleteFormInDll(f); end; procedure TForm1.Button2Click(Sender: TObject); begin if Assigned(f) then begin DeleteFormInDll(f); f := nil; end; if Assigned(Ed) then begin DeleteEdit(Ed); Ed := nil; end; end; end. |
Сообщ.
#10
,
|
|
|
То есть вот такой код отработает нормально?
MyForm := CreateFormInDLL; try MyForm.Font.Assign(MySuperFont); MyForm.ShowModal; finally DeleteFormInDll(MyForm); end; |
Сообщ.
#11
,
|
|
|
Цитата jack128 @ То есть вот такой код отработает нормально? Ненормально;) Вот рабочий пример. Собран © Тестировщица. Компиляция и ассимиляция текста про DLL © Тестировщица. Начало текстовки: ХРАНЕНИЕ ФОРМ В DLL Как правило, формы доступны с помощью специальных функций доступа. Функции доступа служат интерфейсом между загружающим процессом и библиотекой DLL. МОДАЛЬНОЕ ДИАЛОГОВОЕ ОКНО ПРИЛОЖЕНИЯ (FIRST.DLL, DYNAWIN.PAS) Модальная форма приложения создается динамически в функции доступа к форме. Затем форма показывается пользователю. После того, как пользователь нажал кнопку, форма уничтожается. Выбор пользователя возвращается в вызвавший процесс в виде целого числа. Модуль Access.pas: //ACCESS.PAS - метод доступа к модальному диалоговому окну, содержащий обработку //ошибок. unit Access; interface uses windows,sysutils, messages,dialogs, forms; // Создание, показ и удаление модальной формы function ExecuteModal(hWnd:THandle):integer;stdcall;export; //CreateNoModal- метод доступа возвращает значение false в случае неудачной попытки создания формы //Создает экземпляр немодальной формы //ShowNoModal - не требует параметров. Отображение немодальной формы //HideNoModal //FreeNoModal- метод доступа освобождает память, выделенную для формы //........................ Прикреплённый файлFormsInDll.zip (26.92 Кбайт, скачиваний: 204) |