Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Импорт MDIChild форм из DLL [D7, WinXP]


kas ©   (2008-05-18 13:40:00) 

Доброго времени суток!

Такая проблема: необходимо хранить MDIChild формы в DLL и по ходу работы программы их подключать. Перерыл кучу примеров решения этой задачи в нете, но у всех одна и та же проблема: когда портируемая из DLL-библиотеки MDIChild-форма встраивается в родительскую MDI-форму, то пропадает возможность переключения фокуса с помощью Tab'а между элементами встроенной MDIChild-формы. Т.е. когда фокус стоит на одном из элементов дочерней формы и нажимаешь Таб, то фокус перескакивает на элементы другой - родительской формы.

Был бы очень признателен, если бы кто-нибудь подсказал как с этим бороться?

вот основной код DLL:


uses
 SysUtils, Classes, Forms, Dialogs, Unit1 in 'Unit1.pas' {frmMyChildForm};

var
 DLLApp: TApplication;
 DLLScr: TScreen;

procedure InitPlugin(App, Scr: integer); StdCall;
begin
 DLLScr := Screen;
 Screen := TScreen(Scr);
 DLLApp := Application;
 Application := TApplication(App);
end;

procedure DonePlugin; StdCall;
begin
 Screen := DLLScr;
 Application := DLLApp;
end;

function CreateMDI: integer; StdCall;
begin
 Result := integer(TfrmMyChildForm.Create(Application.MainForm));
end;

exports
 InitPlugin, DonePlugin, CreateMDI;

begin
end.


вот вызывающий код в самом приложении


var
 Form1: TForm1;
 HLib: THandle;
 MDIForm: TForm;
 InitProc: procedure(app, scr: integer); stdcall;
 CreateMDIFunc: function: integer; stdcall;
 DonePluginProc: procedure; stdcall;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 HLib := LoadLibrary('..\dll\project1.dll');
 if HLib>HINSTANCE_ERROR then
 begin
   InitProc := GetProcAddress(HLib, 'InitPlugin');
   if Assigned(InitProc) then
   begin
     InitProc(integer(Application), integer(Screen));

     CreateMDIFunc := GetProcAddress(HLib, 'CreateMDI');
     If (Assigned(CreateMDIFunc)) then
       MDIForm := TForm(CreateMDIFunc);
   end;
 end
 else
   showmessage('Cannot load');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 if Assigned(MDIForm) then MDIForm.Free;
 DonePluginProc := GetProcAddress(HLib, 'DonePlugin');
 if (Assigned(DonePluginProc)) then DonePluginProc;
 FreeLibrary(HLib);
end;


kas   (2008-05-24 21:44:00) [1]


> Чем не угодило решение с пакетами времени выполнения ?


спасибо, опробовал для этих целей пакеты - счастлив :)


Германн   (2008-05-20 03:27:00) [2]


> Истина проста: формы в DLL - MD.

И всё равно мода диктует их туда пихать!


Leonid Troyanovsky   (2008-05-19 21:47:00) [3]


> kas ©   (19.05.08 21:36) [10]

>  пойду дальше курить маны)))

Да ты, видать, обкурился уж.
Истина проста: формы в DLL - MD.

--
Regards, LVT.


kas   (2008-05-19 21:36:00) [4]

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

Ладно, фих с ним. Раз более конкретного из вас не выпытать, пойду дальше курить маны)))


Сергей М.   (2008-05-19 21:18:00) [5]


> кода, который я выложил в качестве примера


Код ты содрал абсолютно бездумно.

Этот шматок кода с подобными же сопроводительными авторскими претензиями всплывает в форуме чуть ли не каждую неделю, уверяю тебя)


Leonid Troyanovsky   (2008-05-19 21:13:00) [6]


> kas ©   (19.05.08 20:59) [6]

> как ее решить то зачем вообще разговоры разговаривать.

Зачем вообще DLL & MDI в частности.
Неопытным первое, во-ще, заказано.

--
Regards, LVT.


Сергей М.   (2008-05-19 21:13:00) [7]


> в библиотеках только если они подключаются к приложениям
> Дельфи


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

А теперь шевели репой - приложения, разработанные НЕ в Делфи, знать не знаю ни по какие TApplication, TScreen и иже с ними VCL-объекты, но при этом "родным" соглашениям о вызовах для них вполне может являться то самое твое содранное откуда-то бездумно stdcall-соглашение.

Вопрос на засыпку - ЧТО эти приложения должны будут передавать в твою библиотеку в кач-ве параметров App и Scr ?

Думай головой, а не причинным местом) ...


kas   (2008-05-19 20:59:00) [8]

хм, интересное кино.


> > > И за каким лешим stdcall ?
> >
> >
> > а почему бы и нет? разве в данном случае это имеет значение?
>
> >
>
> Код замусориваешь.


Это что значит замусориваешь? Если не назначать способ передачи параметров, то автоматически используется тип register, а его используют в библиотеках только если они подключаются к приложениям Дельфи. А я всегда использую stdcall потому что он соответствует стандартной технологии передачи параметров Win32. При чем здесь замусориваешь???!!!


> А зачем их нужно было переназначать вообще ? И таким извращенным
> способом ?


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

Если Вы знаете, как это сделать правильно и чтоб это работало, то очень прошу вас сказать - как! А не "плясать с бубном" вокруг того кода, который я выложил в качестве примера. А если Вы не сталкивались с такой проблемой и не знаете как ее решить то зачем вообще разговоры разговаривать.


Amoeba   (2008-05-19 10:45:00) [9]


> > И за каким лешим stdcall ?
>
>
> а почему бы и нет? разве в данном случае это имеет значение?
>

Код замусориваешь.


Сергей М.   (2008-05-18 22:47:00) [10]


> я переназначал глобальные объекты так


А зачем их нужно было переназначать вообще ? И таким извращенным способом ?

Чем не угодило решение с пакетами времени выполнения ?


> а почему бы и нет?


А зачем?

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


Сергей М.   (2008-05-18 22:43:00) [11]

Ни первое и ни второе.

Хочу чтобы ты думал, логически размышлял, тогда и решение найдешь сам.

Ты не ответил ни на один вопрос ..


kas   (2008-05-18 21:32:00) [12]

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


> Это что еще за пляски с бубном вокуруг приведения типов ?


перед тем, как начал искать примеры в нете, я переназначал глобальные объекты так:


procedure InitPlugin(App: TApplication; Scr: TScreen); stdcall;
begin
 DLLScr := Screen;
 Screen := Scr;
 DLLApp := Application;
 Application := App;
end;


- эффект тот же.


> И за каким лешим stdcall ?


а почему бы и нет? разве в данном случае это имеет значение? после вашего вопроса на всякий случай опробовал все способы - эффект то же.


Сергей М.   (2008-05-18 19:59:00) [13]


> procedure InitPlugin(App, Scr: integer); StdCall;
> begin
>  DLLScr := Screen;
>  Screen := TScreen(Scr);
>  DLLApp := Application;
>  Application := TApplication(App);
> end;
>


Это что еще за пляски с бубном вокуруг приведения типов ?
И за каким лешим stdcall ?

Не следует передирать чужой код бездумно.


Наверх

Титульная страница Поиск, карта сайта Написать письмо