Конференция "Основная" » Импорт MDIChild форм из DLL [D7, WinXP]
 
  • kas © (18.05.08 13:40) [0]
    Доброго времени суток!

    Такая проблема: необходимо хранить 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;

  • Сергей М. © (18.05.08 19:59) [1]

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


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

    Не следует передирать чужой код бездумно.
  • kas © (18.05.08 21:32) [2]
    Уважаемый Сергей М., Вы таким способом просто хотели поругать меня за код или все же помочь мне с проблемой? Если первое, то спасибо за критегу, если второе, то:


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


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


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



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


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


    а почему бы и нет? разве в данном случае это имеет значение? после вашего вопроса на всякий случай опробовал все способы - эффект то же.
  • Сергей М. © (18.05.08 22:43) [3]
    Ни первое и ни второе.

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

    Ты не ответил ни на один вопрос ..
  • Сергей М. © (18.05.08 22:47) [4]

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


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

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


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


    А зачем ?

    Это и наводит на мысль, что код был содран бездумно
  • Amoeba © (19.05.08 10:45) [5]

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

    Код замусориваешь.
  • kas © (19.05.08 20:59) [6]
    хм, интересное кино.


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


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


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


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

    Если Вы знаете, как это сделать правильно и чтоб это работало, то очень прошу вас сказать - как! А не "плясать с бубном" вокруг того кода, который я выложил в качестве примера. А если Вы не сталкивались с такой проблемой и не знаете как ее решить то зачем вообще разговоры разговаривать.
  • Leonid Troyanovsky © (19.05.08 21:13) [7]

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

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

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

    --
    Regards, LVT.
  • Сергей М. © (19.05.08 21:13) [8]

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


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

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

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

    Думай головой, а не причинным местом) ...
  • Сергей М. © (19.05.08 21:18) [9]

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


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

    Этот шматок кода с подобными же сопроводительными авторскими претензиями всплывает в форуме чуть ли не каждую неделю, уверяю тебя)
  • kas © (19.05.08 21:36) [10]
    Да я же и говорю что именно этот код я скопировал из одного из примеров, которых в нете куча! Т.к. то, что писал я сам не решало проблему до конца и всегда вылезали какие-то глюки, и я подумал, что это я такой тупой и этот код будет ближе к истине...

    Ладно, фих с ним. Раз более конкретного из вас не выпытать, пойду дальше курить маны)))
  • Leonid Troyanovsky © (19.05.08 21:47) [11]

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

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

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

    --
    Regards, LVT.
  • Германн © (20.05.08 03:27) [12]

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

    И всё равно мода диктует их туда пихать!
  • kas © (24.05.08 21:44) [13]

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


    спасибо, опробовал для этих целей пакеты - счастлив :)
 
Конференция "Основная" » Импорт MDIChild форм из DLL [D7, WinXP]
Есть новые Нет новых   [134491   +8][b:0][p:0.001]