Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Вызов формы из dll


Автор: morpheyushka 28.5.2008, 10:00
 Помогите разобраться при вызове формы из dll вылетает ошибка "Invalid window handle". Гугл лопатил - ничего толкового не нашол smile ...может кто сталкивался с подобной ситуацией и знает как с этим бороться.

Код отображения формы:
Код

procedure BetMessageShow(App1: THandle);
begin
  Application.Handle := App1;
  BetMessage := TBetMessage.Create(Application);
  BetMessage.ShowModal;
  BetMessage.Free;
end;



Обработчик кнопочки (тестовый), который должен вызывать окно:
Код

procedure TForm2.Button3Click(Sender: TObject);
begin
  BetMessageShow(Application.Handle);
end;

Автор: Rennigth 28.5.2008, 10:54
Цитата(morpheyushka @  28.5.2008,  10:00 Найти цитируемый пост)
Application.Handle := App1;

а это зачем?

На какой операции вылетает ексепшен?

Автор: morpheyushka 28.5.2008, 11:03
щас попробую посмотреть на какой команде вылетает

Добавлено через 8 минут и 11 секунд
Посмотреть на какой именно команде вылетает не могу так как ошибка возникает когда я пытаюсь вызвать процедуру из длл.


А усли не выполнить следующий код:
Код

Application.Handle := App1;


то возникает ошибка - "CoInitialize has not been called"
 smile 

Автор: Rennigth 28.5.2008, 11:17
Цитата(morpheyushka @  28.5.2008,  11:03 Найти цитируемый пост)
то возникает ошибка - "CoInitialize has not been called"

Вызывай ручками. Находиться вроде в ActiveX.
Код

CoInitialize(0)

Цитата(morpheyushka @  28.5.2008,  11:03 Найти цитируемый пост)
Посмотреть на какой именно команде вылетает не могу так как ошибка возникает когда я пытаюсь вызвать процедуру из длл.

На сколько я помню достаточно dll включить в группу проекта, и все будет нормально отлаживаться.

Автор: morpheyushka 28.5.2008, 11:23
Цитата

На сколько я помню достаточно dll включить в группу проекта, и все будет нормально отлаживаться. 

Нет, всё равно при попытки вызова процедуры вылетает ошибка - в тело не заходит.

А куда вставить CoInitialize(0)?

Автор: Rennigth 28.5.2008, 11:25
Цитата(morpheyushka @  28.5.2008,  11:23 Найти цитируемый пост)
А куда вставить CoInitialize(0)? 

в принципе куда угодно, лишь бы до востребованости. Вставляй в сеуцию initialization, не прогадаешь  smile 

Автор: morpheyushka 28.5.2008, 11:34
Нет, увы не тут копать нужно - не помогает

Какие ещё идеи есть?

Автор: Rennigth 28.5.2008, 11:36
morpheyushka, 
ну тады выкладывай весь код dll smile попробуем разобраться.

Автор: morpheyushka 28.5.2008, 11:38
Код

library BMsg;

uses
  SysUtils,
  Classes,
  BetMessageU in 'BetMessageU.pas',
  AddAddressU in 'AddAddressU.pas',
  CreateMessageU in 'CreateMessageU.pas';

{$R *.res}

exports
  BetMessageShow,
  AddAddressShowModal,
  CrtMessShowModal;
begin
end.

Автор: cemick 28.5.2008, 11:47
У dll свой апликайшен, попробуй присваивать не Handle, а TApplication. Сделай в dll в вот так:
Код

var DllApp: TApplication;
//    DllScr: TScreen;
    
procedure InitFRViewer(Appl:TApplication; AScreen:TScreen);
begin
{Подмена указателей на данные объекты необходима для корректного создания фрейма
в основном приложении,  так как у dll  свой Application и как правило равный nil}
 // DllScr := Screen;
//  Screen := AScreen;
  DllApp := Application;
  Application := Appl;
end;

procedure btkDLLProc(Reason: Integer);
begin
{Возращаем на место ссылку на апликатион перед выгрузкой dll}
   if Reason = DLL_PROCESS_DETACH then
   begin
     { DLL is выгружается. Восстанавливаем значение указателя Application}
     if (Assigned(DllApp)) {and (Assigned(DllScr))} then
     begin
       Application := DllApp;
 //      Screen := DllScr;
     end;
   end;
end;

exports
   BetMessageShow,
  AddAddressShowModal,
  CrtMessShowModal;
  InitFRViewer;



begin
  DllApp := nil;
  DLLProc := @btkDLLProc;
end.



 И вызывай Init перед созданием своей формы

Автор: Rennigth 28.5.2008, 11:49
morpheyushka, маловато будет.  smile 

Автор: morpheyushka 28.5.2008, 12:08
Код

unit ComInitU;

interface

uses
  ActiveX;

implementation

initialization
  CoInitializeEx(nil,COINIT_MULTITHREADED);
finalization
  CoUninitialize;
end.]


а вот так в отдельном модуле я провожу инициализацию....

Код главного модуля проекта:
Код

program Message;

uses
  ComInitU in 'ComInitU.pas',
  Forms,
  BetMessageU in 'BetMessageU.pas' {BetMessage},
  CreateMessageU in 'CreateMessageU.pas' {CrtMess},
  AddAddressU in 'AddAddressU.pas' {AddAddress};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TBetMessage, BetMessage);
  Application.CreateForm(TCrtMess, CrtMess);
  Application.CreateForm(TAddAddress, AddAddress);
  Application.Run;
end.


Добавлено через 10 минут и 5 секунд
ой...не заметил пост cemick'a...щас попробую и отпишу smile 

Автор: Rennigth 28.5.2008, 12:29
Цитата(morpheyushka @  28.5.2008,  12:08 Найти цитируемый пост)
program Message;

так, погодь. так dll или exe у тя?
Цитата(morpheyushka @  28.5.2008,  12:08 Найти цитируемый пост)
program Message;

 smile 

Автор: morpheyushka 28.5.2008, 12:30
2  cemick, а как вызывать форму? smile

Добавлено через 7 минут и 53 секунды
Цитата(Rennigth @ 28.5.2008,  12:29)
так, погодь. так dll или exe у тя?

 Ща разъесню...я сделал проект и там всё классно работает. Но мне потом сказали чтобы я зафигарил всё это в dll. Ну вот я и создал dll и давай туда пихать свой проект что бы не переделывать всё заново. Ну естественно фигня выходит полная.

Самое интересное, что вторая часть программы, которая запускается на клиентской машине нормально запихнулась в dll и всё работает. Сделано всё идентично. Просто в серверной части я использовал ADO и по этому, как я понял, мне сначало выбивало ошибку "CoInitialize has not been called". Когда я сделал инициализацию - начало ругаться на кривой хэндл окна ну и вот я со своей проблемой тут!

Автор: morpheyushka 28.5.2008, 13:20
Так ничего и не помогает при переборе всех вышеперечисленных вариантов получаю две ошибки:
  • "CoInitialize has not been called"
  • "Invalid window handle"
А времени не так много осталось

Автор: X-Vlad 29.5.2008, 09:11
DLL
Код

procedure  ShowMyForm(aApplication: TApplication); stdcall;
begin
  Application := aApplication;
  aForm := TTestForm.Create(aAppliation)
...
end;


EXE
Код

type
  procedure  ShowMyForm(aApplication: TApplication); stdcall;
...

procedure btn1.onclick(Sender:TObject);
begin
  ShowMyForm(Application);
end;

Автор: morpheyushka 3.6.2008, 10:54
О...получилось - спасибо) smile  smile  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)