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

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

И снова форма в dll : инициализация [D7, WinXP]


Страницы:   1 2

parovoZZ ©   (2006-05-23 00:36:00) 

Здарова

У меня в dll две формы - одна рабочая (с визуальными компонентами), а вторая DataModule. Вот её то и не получается инициализировать (рабочая с компонентами в данный момент не нужна). Т.е. нужны компоненты ADOcommand, ADOConnection и ADODataSet. Делаю следующее:
unit DF;

interface

uses
 Windows, Classes, DB, ADODB, Forms;

type
 TDMd = class(TDataModule)
   ADOConnection: TADOConnection;
   ADOCmd: TADOCommand;
   ADODS: TADODataSet;
 private

 public
   { Public declarations }
 end;

//procedure DllEntryPoint (Reason : DWord);
procedure InitData; stdcall;

var
 DMd: TDMd;

implementation

{$R *.dfm}

procedure InitData; stdcall
begin

 DMd := TDMd.Create (Application);

end;

{
initialization
//if (DllProc = nil) then
 begin
  DllProc := @DllEntryPoint;
  DllEntryPoint (DLL_PROCESS_ATTACH);
 end;
finalization    }

exports
InitData name 'InitData';

end.


Так вот на строчке   DMd := TDMd.Create (Application); возникает ошибка EOleSysError with message "Не был произведён вызов CoInitialize". Чего я такого не сделал?
Да, вызывающий exe написан на апях.


parovoZZ   (2006-05-27 21:31:00) [1]

Да не, проблема WebBrowser + PageControl в dll. Всё коннектится, грузится, но при открытии вкладки с WebBrowser вылетает ошибка типа Could not ole window handle. Всё тоже самое сделал в exe - без ошибок.


Ярослав   (2006-05-27 21:00:00) [2]

Так если у вас есть дата модуль так где вы его подключаете в длл?


Ярослав   (2006-05-27 20:50:00) [3]

Смотри пример  как это делаю я

Вот дллка :
library INFO;

{ Important note about DLL memory management: ShareMem must be the
 first unit in your library's USES clause AND your project's (select
 Project-View Source) USES clause if your DLL exports any procedures or
 functions that pass strings as parameters or function results. This
 applies to all strings passed to and from your DLL--even those that
 are nested in records and classes. ShareMem is the interface unit to
 the BORLNDMM.DLL shared memory manager, which must be deployed along
 with your DLL. To avoid using BORLNDMM.DLL, pass string information
 using PChar or ShortString parameters. }

uses
 SysUtils,
 Classes,
 Forms ,
 system,
 infomy in 'infomy.pas'{imy},
 infouser in 'infouser.pas'{usr},
 infouserb in 'infouserb.pas'{usb},
 bvlogo in 'bvlogo.pas'{logo};
 {$R *.RES}

        function infoform : integer; stdcall ;
        var
        inf: Tmyinfo ;
        begin
        inf:=tmyinfo.Create(Application);
        Result:=inf.ShowModal ;
        inf.Free ;
        end ;
        function userform: integer ;stdcall ;
        var
        infuser:Tuserinfo ;
        begin
        infuser:=Tuserinfo.Create(Application) ;
        result:=infuser.ShowModal ;
        infuser.Free ;
        end ;
        function userformb: integer ;stdcall ;
        var
        infuserb:Tuserinfob ;
        begin
        infuserb:=Tuserinfob.create(Application) ;
        result:=infuserb.showmodal ;
        infuserb.free ;
        end;
        function startbvlogo: integer ; stdcall ;
        var
        logostart:tlogo ;
        begin
        logostart:=Tlogo.create(Application);
        result:=logostart.showmodal ;
        logostart.free ;
        end ;
  exports
  infoform,
  Userform ,
  userformb,
  startbvlogo;

begin
end.

Вызов из главной формы


var
 Main_Form: TMain_Form;
  {------------------------------------}
   function infoform : integer; stdcall ;
  external 'INFO.dll' ;
  function userform: integer ; stdcall ;
  external 'INFO.dll' ;
  function userformb:integer; stdcall ;
  external 'INFO.dll' ;
  Function startbvlogo:integer; stdcall ;
  external 'info.dll'  ;
  {=====================}

procedure TMain_Form.N18Click(Sender: TObject);
begin
  startbvlogo;
end;

procedure TMain_Form.N22Click(Sender: TObject);
begin
userformb;
end;

procedure TMain_Form.N20Click(Sender: TObject);
begin
infoform;
end;

У меня все работает ..
Кроме MDI форм


parovoZZ   (2006-05-26 22:20:00) [4]

Ладно, в задницу все эти dll с формами. Генератор глюков вышел вместо проги. Всё равно по скорости ничего не получил - dll статически грузится столько же, сколько и exe. А динамически - голова съедет.


GrayFace   (2006-05-26 12:31:00) [5]

По поводу [1] - Укажи ComObj в dpr где-нибудь по раньше - тогда точно должен будет проинициализироваться.

DrPass ©   (23.05.06 23:51) [11]
> > А смысл заменять у Application Handle?
>
> Ровным счетом никакого. Сообщения-то все равно будут приходить
> в оконную функцию, объявленную в основной программе, а не
> в Application.
> А в том Application, которое объявлено в DLL, вообще не
> создается ни оконная функция, ни дескриптор (это тоже фича,
>  начиная с D6)

Есть. Почти такой же как у Form.ParentWindow:=...


parovoZZ   (2006-05-26 09:44:00) [6]

Так ведь без PageControl всё работает.

А как быть с манифестом ХР? и почему он в dll не подхватывается?
Попробую в секцию 24 запихнуть.


isasa   (2006-05-26 08:05:00) [7]

WebBrowser - это COM(скорее всего), значит надо делать  CoInitializeEx и в EXE.
Только тип модели должен быть аналогичен, усьановленному в DLL.
Тип потоковой модели "на ходу" не меняется.


parovoZZ   (2006-05-26 01:31:00) [8]

А куда мне её ещё деть? У меня exe написан на АПЯХ!!!

Кароче! Убрал WebBrowser с формы - пропала ошибка с OLE.

Заккомил строчку {$R DelphiXP.res} - прекратились ошибки при завершении проги. А жаль. Всё так красиво.

А почему WebBrowser не дружит с PageControl???? Создал ту же форму в ехе - ошибка осталась. Фигня. Мне без броузера низзя.


isasa   (2006-05-26 00:40:00) [9]

Немного оклемался. :)
Для VCL, это

 Application.Initialize;
 Application.CreateForm(TmainForm, mainForm);
 Application.Run;

как Библия, остальные пихай в DLL, если есть желание решать проблемы(решаеиые).


isasa   (2006-05-26 00:25:00) [10]

Ну главную форму запихать в DLL, это круто.
Тут помочь не могу. Я такого еще не встречал. :)
Фанатизм приводит к травмам!


parovoZZ   (2006-05-26 00:06:00) [11]


> В общем, идея такая, Application.Handle в DLL, заполняется
> ручками ...

В таком случае окно становится модальным, сворачивается не в таскбар, а над пуском, к тому же висит ещё какое-то маленькое окно, с которым ничего сделать нельзя, только подвигать.

Что-то на строчке

MainForm := TMainForm.Create (nil);

выпадает ошибка в духе  'Could not ole window handle'. А бывает не выпадает.

Короче, ну его... Форма в dll это такой гемор  брррр. Да и при выходе ругань Access Vioalatin.

Только весь проект изгадил.


DrPass   (2006-05-25 00:26:00) [12]


> parovoZZ ©   (24.05.06 21:33) [19]

Да не надо ничего формировать, я совсем про другое писал. Библиотека получит свой DLL_PROCESS_DETACH, куда она денется :)


parovoZZ   (2006-05-24 21:33:00) [13]


> Т.е. если приложение и так завершает работу (если, конечно,
>  DLL_PROCESS_DETACH не следствие FreeLibrary),

Т.е. DLL_PROCESS_DETACH тоже надо формировать ручками? А почему нельзя автоматом при FreeLibrary?


DrPass   (2006-05-24 01:06:00) [14]


> isasa ©   (24.05.06 00:38) [17]

А здесь вообще Application.Terminate не нужно. Application.Terminate по умолчанию никаких ресурсов не высвобождает, это же не деструктор. Она просто посылает главному потоку приложения сообщение WM_QUIT - поэтому не важно, обрабатывается ли очередь главного потока в Application или какой-то другой оконной функции, все равно обработается корректно. Т.е. если приложение и так завершает работу (если, конечно, DLL_PROCESS_DETACH не следствие FreeLibrary), лишний раз ему напоминать об этом не к чему (хотя и не повредит).
Вообще, полезно ознакомиться с первоисточником (сиречь исходниками VCL) - тогда бы эти непонятки отпали бы сами собой


isasa   (2006-05-24 00:38:00) [15]

Наверно непонятно написал.
Имел ввиду следующее. Освобождаем ресурсы проще?

procedure DLLEntryPoint(Reason: Integer); // stdcall;
begin
case Reason of
  DLL_PROCESS_DETACH: //= 0;
    CoUninitialize;
    Application.Terminate;


isasa   (2006-05-24 00:33:00) [16]

Тоесть, для DLL корректно
Application.Terminate
?


DrPass   (2006-05-24 00:05:00) [17]


> isasa ©   (24.05.06 00:01) [14]

А он абсолютно непроблемный. В том же и смысл отсутствия оконной функции и дескриптора в Application в DLL, чтобы их корректно разруливать. Кстати, в версиях D5 и более старых действительно нужно было их синхронизировать... только более жесткими методами - DLL_Application:= EXE_Application. В данном же случае единственный смысл этого объекта - общий родитель для форм и модулей в DLL.


isasa   (2006-05-24 00:01:00) [18]

DrPass ©   (23.05.06 23:52) [12]
И причем тут дескриптор Application?


А хорошо ли, в качестве родителя, указывать проблемный объект?


isasa   (2006-05-23 23:54:00) [19]

На сон.
Если не морочить голову с Application и освобождать ресурс ручками
DMd.Free
пиши
DMd := TDMd.Create (nil);


DrPass   (2006-05-23 23:52:00) [20]


> isasa ©   (23.05.06 23:42) [10]
> А подумать?
>
> ...
> DMd := TDMd.Create (Application);

И причем тут дескриптор Application?


Страницы:   1 2

Наверх

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