-
Задачка такова, необходимо разработать MDI приложение, все формы хранятся в dll. Не получается вызов формы как Child формы, как сделать? Привожу кусочек из DLL var DLLForm : TDLLForm; CallForm : THandle; implementation
{$R *.DFM} //****************************************************************************** function ShowModalForm: Integer; //Modal Call begin DllForm := TDllForm.Create(Application); Result := DLLForm.ShowModal; DLLForm.Free; end; //****************************************************************************** procedure ShowForm(Appl, Form: THandle); //NonModal Call begin Application.Handle := Appl; DllForm := TDllForm.Create(Application); DLLForm.FormStyle := fsMDIChild; DLLForm.Color := clMoneyGreen; CallForm := Form; DLLForm.Show; end; //******************************************************************************
и кусочек из приложения procedure TTestMain.Button1Click(Sender: TObject); // Модальный вызов begin Button2.Enabled := False; label1.Caption := 'ModalResult = '+IntToStr(ShowModalForm); label1.Show; // Показываем результат вызова Button2.Enabled := True end;
procedure TTestMain.Button2Click(Sender: TObject); // Немодальный вызов begin Button1.Enabled := False; Button2.Enabled := False; Button3.Enabled := True; label1.Hide; ShowForm(Application.Handle, Self.Handle) ; end;
-
> IntruderLab (11.03.08 15:32)
> формы хранятся в dll. Не получается вызов формы как Child > формы, как сделать?
Не хранить формы в dll.
-- Regards, LVT.
-
> Не получается вызов формы как Child формы, как сделать?
If the form is the main form of an MDI application, its FormStyle property must be set to fsMDIForm.
-
> If the form is the main form of an MDI application, its > FormStyle property must be set to fsMDIForm.
Это я естественно указываю - не работает
-
> > IntruderLab (11.03.08 15:32) > > > формы хранятся в dll. Не получается вызов формы как Child > > формы, как сделать? > > Не хранить формы в dll. > > -- > Regards, LVT.
Суть такова - что именно в dll и именно не модельные формы для MDI приложения нужны :(
-
У твоей dll св-во MainForm объекта Application равно nil. Удивись, почеши репу, сделай выводы)
-
> У твоей dll св-во MainForm объекта Application равно nil. > > Удивись, почеши репу, сделай выводы)
Удивился, но мне делфа пишет, то это ридонли свойство, что делать - репа болит от чеса :)
-
Ну делать ?)
Для начала распрощаться с мыслью об использовании в кач-ве хост-приложения для твоих dll приложений, разработанных не в Делфи или в Делфи иных версий.
Подтверди готовность)
-
> [6] IntruderLab (11.03.08 16:42)
а почему не экспортировать из DLL фреймы? А mdi-дети пусть себе живут в экзе
-
> Сергей М. © (11.03.08 16:45) [7] > > Ну делать ?) > > Для начала распрощаться с мыслью об использовании в кач- > ве хост-приложения для твоих dll приложений, разработанных > не в Делфи или в Делфи иных версий. > > Подтверди готовность)
Готовность подтверждаю :) Сейчас сделал вот что: Передал в dll помимо Application.Handle еще MainForm.Handle и вызвал Child с помощью ParentWindow, форма открылась - но ессно не все что надо....
-
> Готовность подтверждаю
Ну тогда убирай нафих все эти "передачи")
Все что нужно - собрать взаимодействующие проекты с установленной опцией использования пакетов времени выполнения (см. Project Options -> Packages -> Build With Run-Time Packages)
Вуаля !)
-
если имеется ввиду bpl то не подходит.... надо именно dll
-
Хотя уже согласен и на bpl
-
> IntruderLab (11.03.08 17:31) [12]
> Хотя уже согласен и на bpl
Соглашайся на монолитный экзешник, и можешь спокойно идти по паре пива.
-- Regards, LVT.
-
Может тогда согласишься и на отказ от внешних модулей? ))
-
> Leonid Troyanovsky ©
Опередили
-
> если имеется ввиду bpl
Касаемо твоей вожделенной "dll с формой" - нет, не имеется)
Форма твоя как родилась в твоей dll, так там и будет жить, не волнуйся)
-
-
-
> Amoeba © (12.03.08 01:23) [17] > > О загрузке дочерней формы (MDIChild) из DLL: > http://www.delphikingdom.com/asp/viewitem.asp?catalogid=276 >
Плохое распределение памяти, глубина вложений форм не более одного, а у меня дочерняя форма может вызывать до 3 модальных (линейных) формы. Так что видимо придется работать с BPL
-
> Сергей М. © (11.03.08 19:25) [16] > > > > если имеется ввиду bpl > > > Касаемо твоей вожделенной "dll с формой" - нет, не имеется) > > Форма твоя как родилась в твоей dll, так там и будет жить, > не волнуйся)
Жду руководящих действий или ссылок на то как :)
-
> Жду руководящих действий
Уже даны в достаточном объеме в [10]
-
> Сергей М. © (12.03.08 16:18) [21] > > > > Жду руководящих действий > > > Уже даны в достаточном объеме в [10]
Есть вводная информация как с этим работать? Или лучше элементарные примерчики?
-
> как с этим работать?
С чем ?
Сказано же - простейшее решение проблемы состоит из двух простейших же пунктов:
1. В исх.кодах своих exe- и dll-проектов убираешь все касаемое параметра Appl, т.е. передача этого параметра не нужна вообще.
2. Во всех своих проектах устанавливаешь крыжик Project->Options..->Packages->Build With Run-Time Packages и после этого полностью ребилдишь эти проекты.
Все !! Больше никаких телодвижений делать не нужно.
Что еще не понятно ?)
-
Попробую
-
Сергей М. © (13.03.08 09:06) [23]
> как с этим работать?
С чем ?
Сказано же - простейшее решение проблемы состоит из двух простейших же пунктов:
1. В исх.кодах своих exe- и dll-проектов убираешь все касаемое параметра Appl, т.е. передача этого параметра не нужна вообще.
2. Во всех своих проектах устанавливаешь крыжик Project->Options..->Packages->Build With Run-Time Packages и после этого полностью ребилдишь эти проекты.
Все !! Больше никаких телодвижений делать не нужно.
Что еще не понятно ?)
Вобщем - то сделал.... как мне теперь реализовать MDI?
-
> как мне теперь реализовать MDI?
Ты его уже реализовал - Application.MainForm у тебя fsMDIForm, что и является осн.условием для создания MDI-приложения при поддержке VCL.
-
Вобщем все перебьюлдил, все работает, теперь что делать?
-
Как мне указать для форм, находящихся в dll что exe форма является для них материнской?
-
> IntruderLab (13.03.08 12:38) [28]
Зачем ? Все уже указано и все работает, ты сам же это сказал в [27].
-
дак млин не в MDi режиме работает
-
> не в MDi режиме работает >
Убедись, что Application.MainForm.FormStyle = fsMDIForm
-
> Сергей М. © (13.03.08 13:38) [31] > > > > не в MDi режиме работает > > > > > Убедись, что Application.MainForm.FormStyle = fsMDIForm
это exe? а как указать в dll?
-
В свойствах формы: FormStyle ставишь MDiForm. А как делается если все находится в экзэ? точно также и тут.
-
> это exe? а как указать в dll?
Сказка про белого бычка)
Говорили-говорили про единый объект Application - и все впустую)
Ты пойми, что при BwRTP-опции объект Application и, соотв-но, объект Application.MainForm и в ехе и в длл - это один и тот же объект !
-
То есть в этом случае уже не надо в dll передавать хендлы Application и Screen?
-
> Сергей М. © (13.03.08 14:06) [34] > > > > это exe? а как указать в dll? > > > Сказка про белого бычка) > > Говорили-говорили про единый объект Application - и все > впустую) > > Ты пойми, что при BwRTP-опции объект Application и, соотв- > но, объект Application.MainForm и в ехе и в длл - это один > и тот же объект !
Сергей, сорри... просто привык к одной системе - очень сложно представить как в MDI просто это переделать - вот и куча вопросов из -за этого... Сейчас попробую
-
Не понимаю, пишет - Нет возможности создать форму, ни одна MDI форма не является активной, все таки хоче указания Application
-
Хелп, ничего не понимаю. Напишите просто тупо как вызвать форму из DLL чтобы она стала Child для mdi у меня в exe frmMain.FormStyle := fsMDIForm; в dll frmTest.FormStyle := fsMDIChild; функция вызова формы frmTest из dll function ShowTest:LongInt;StdCall; var frmTest : TfrmTest; begin Result := LongInt(TfrmTest.Create(Application); --навреное тут не так, как сделать не знаю end; в exe: var LibHandle : THandle; **** LibHandle := LoadLibrary('iHercules.dll'); if LibHandle <> 0 then begin @ShowTest := GetProcessAddress(LibHandle,'ShowTest); ShowTest; end; FreeLibrary(LibHandle);
Что я не так делаю.... в не MDI приложении с модальным вызовом форм все работет, не могу понять как это реализуется в MDI
-
Чему равно
Application.MainForm
непосредственно перед вызовом
TfrmTest.Create(Application)
?
-
Мне параметром ему хендл главной формы присваивать?
-
О боже)... Ты в состоянии средствами отладчика отсановиться на строчке Result := LongInt(TfrmTest.Create(Application); и посмотреть, чему равно значения Application.MainForm, Application.MainForm.Visible, Application.MainForm.FormStyle ?
-
В состоянии :) Application = nil так что я думаю, что все остальное тоже nil
-
> Application = nil
Да быть того не может ! Что угодно, но только не nil там должно быть.
Если, конечно же, над этим не потрудились твои очумелые ручки)
-
Вот ShowMessage(Application.MainForm.Name) у меня frmMain, то есть как и должно быть
-
Ну ?!
А говоришь nil)
> то есть как и должно быть
Еще должно быть Application.MainForm.FormStyle = fsMDIForm - давай, проверяй ...
-
В вызове написал if Application.MainForm.FormStyle = fsMDIForm then ShowMessage('1'); выскочило access violation
-
Все нормально! теперь fsMdiForm
-
Что дальше?
-
А с чего ты взял, что причиной AV явилось именно Application=nil ?
Ты давай уже не мудри, а воспользуйся для проверки отладчиком) А кустарщину с ShowMessage оставь для иных случаев)
-
> Все нормально! теперь fsMdiForm
Ну раз fsMdiForm, то пробуй так:
Application.CreateForm('TfrmTest', frmTest);
-
я такого не говорил, сейчас все нормально, Application.MainForm := frmMain; Application.MainForm.FormStyle := fsMDIForm; Теперь как мне форму вызвать чтобы она стала дочерней, делаю как ранее: frmTest := TfrmTest.Create(Application); frmTest.FormStyle := fsMDIChild; frmTest.Show; он не ругается - но подвисает
-
> frmTest.FormStyle := fsMDIChild;
Что мешает выставить FormStyle=fsMDIChild у формы прямо в дизайн-тайм ?
-
Application.CreateForm(TfrmTest,frmTest); - программа просто висит - никаких реакций
-
> frmTest.Show;
Это лишнее.
При создании MDIChild-формы она автоматически станет видимой
-
Пробуй:
try Application.CreateForm(TfrmTest,frmTest); except on e:exception do ShowMessage(e.Classname + ' ' + e.Message); end;
Что видишь ?
-
никаких реакций, что я не так делаю :(
-
> что я не так делаю
Приводи уже полный текст тестового dll-проекта ..
-
После отлова exception вывалил debugger fault notification а перед этим висел :(
-
почту или аську мож дашь чтобы не светить - можешь прислать на intruderlab@mail.ru
-
Тебе что, сложно выложить тестовый проект здесь ?
Там всего-то два-три десятка строчек)
-
не проблема :) выкладываю unit UfrmMain;
interface
uses ShareMem, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, Menus, ADODB, DB, DBTables, SConnect, Sockets, DBClient, MConnect, StdCtrls, ImgList, jpeg, ExtCtrls, Registry, Buttons, OleCtrls, SHDocVw, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdMessageClient, IdSMTP, JvExStdCtrls, JvMemo, JvDotNetControls, JvExControls, JvComponent, JvEditorCommon, JvUnicodeEditor, JvUnicodeHLEditor, JvaScrollText, JvCheckBox, IdAntiFreezeBase, IdAntiFreeze, JvRichEdit, Consts, ConvUtils, Math, SyncObjs, ComObj, UfrmAbout, StrUtils, URemoteReadNews, URemoteKKMSettings, IdFTP, IniFiles, frxClass, JvEdit, ToolWin, DBCtrls, JvDBDotNetControls, JvScrollMax, JvExExtCtrls, Grids, JvListBox, ShellAPI, ActnList, Tabs;
type TfrmMain = class(TForm) status: TStatusBar; menu: TMainMenu; frmReg: TMenuItem; mnuLogOn: TMenuItem; mnuVvod: TMenuItem; mnuNotes: TMenuItem; mnuReports: TMenuItem; mnuOSV: TMenuItem; mnuNumerators: TMenuItem; mnuhLIST_FACTORY_FILIAL: TMenuItem; mnuhLIST_TYPE_DOCUMENTS: TMenuItem; mnuhLIST_DOCUMENT_NUMERATOR: TMenuItem; mnuhLIST_ROLE: TMenuItem; mnuWorkers: TMenuItem; iList: TImageList; mnuClientShow: TMenuItem; mnuTourOperators: TMenuItem; mnuShowDocuments: TMenuItem; mnuSettings: TMenuItem; mnuKKMServer: TMenuItem; mnuXReport: TMenuItem; mnuZReport: TMenuItem; tcp: TTcpClient; IdAntiFreeze1: TIdAntiFreeze; N6: TMenuItem; mnuCloseSeans: TMenuItem; N1: TMenuItem; ftp: TIdFTP; mnuTourOperatorList: TMenuItem; mnuUserNotes: TMenuItem; mnuLIST_COUNTRY: TMenuItem; mnuLIST_CITY: TMenuItem; N8: TMenuItem; mnuLIST_HOTELS: TMenuItem; mnuAnalitica: TMenuItem; frmKKMFunction: TMenuItem; N5: TMenuItem; mnuChangeOrderClient: TMenuItem; mnuInsertPay: TMenuItem; mnuGetPay: TMenuItem; N2: TMenuItem; aList: TActionList; aEsc: TAction; Panel1: TPanel; N3: TMenuItem; ts: TTabSet; sm1: TJvScrollMax; JvScrollMaxBand2: TJvScrollMaxBand; lblKKMHost: TLabel; lblKKMPort: TLabel; JvScrollMaxBand3: TJvScrollMaxBand; lblGetLocalIP: TLabel; lblClientHostName: TLabel; JvScrollMaxBand5: TJvScrollMaxBand; Label1: TLabel; Label2: TLabel; dtpBegin: TDateTimePicker; dtpEnd: TDateTimePicker; smTypeDocuments: TJvScrollMaxBand; ckOrders: TCheckBox; ckInvoice: TCheckBox; ckAnnulOrders: TCheckBox; ckPays: TCheckBox; ckTours: TCheckBox; ckSortDate: TCheckBox; mnuDocumentsNM: TMenuItem; mnuProgramParameters: TMenuItem; ckUpdates: TCheckBox; ckNews: TCheckBox; Panel2: TPanel; txtNews: TMemo; procedure mnuDocumentsNMClick(Sender: TObject); private
public //Наборы данных подключения к серверу и пользовательских параметров slServer : TStringList; slUser : TStringList; //Параметры удаленного сервера sServerAddress : String; sServerName : String; sServerPort : String; sServerGUID : String; sInterceptGUID : String; sServerBegin : String; sServerEnd : String; //Параметры ККМ sKKMCode : String; //Даты текущего периода sBegin, sEnd : String; //Параметры фильтрации документов sOrders, sInvoice, sAnnulOrders, sTours, sPays, sDateSort, sDogTour, sZayavkaTour, sUpdates, sNews : String; //Поток считывания версий системы coRemoteKKMSettings : TRemoteKKMSettings; //Параметры локального компьютера sHost : String; //Параметры пользователя sUSER_ID : String; sUSER_NICKNAME : String; sUSER_PASSWORD : String; sUSER_FULLNAME : String; sUSER_FILIAL_ID : String; sUSER_KKM_USE : String; sUSER_IS_ADMIN : String; sUSER_FILIAL_NAME : String; sUSER_ROLE_ID : String; sUSER_DOVERENNOST : String; sUSER_TOURS : String; sSESSION : String; end;
function AddLog(sText:String):Longint;StdCall;external'events.dll';
var frmMain: TfrmMain;
implementation
{$R *.dfm}
//****************************************************************************** procedure TfrmMain.mnuDocumentsNMClick(Sender: TObject); var LibHandle : THandle; ShowDocumentsNM : function (slServer,slUsers:TStringList):Integer;StdCall; begin LibHandle := LoadLibrary('iHercules.dll'); if LibHandle <> 0 then begin @ShowDocumentsNM := GetProcAddress(LibHandle,'ShowDocumentsNM'); ShowDocumentsNM(slServer,slUser); end; FreeLibrary(LibHandle); end; //****************************************************************************** end.
dll library iHercules;
uses ShareMem, ActiveX, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, Menus, ADODB, DB, DBTables, SConnect, Sockets, DBClient, MConnect, Registry, DateUtils, Math, UfrmShowDocuments in 'UfrmShowDocuments.pas' {frmShowDocuments};
{$R *.res}
//****************************************************************************** function ShowDocumentsNM(slServer,slUsers:TStringList):Integer;StdCall; var frmShowDocuments : TfrmShowDocuments; begin try Application.CreateForm(TfrmShowDocuments,frmShowDocuments); except on E:Exception do ShowMessage(E.ClassName + ' ' + E.Message); end; end; //****************************************************************************** exports ShowDocumentsNM; //****************************************************************************** begin end. //******************************************************************************
-
Это, ты считаешь, тестовый проект, да ?)
И я во всем этом хламе должен разбираться ?)
Убирай нафих из всех форм все ! И никаких лишних юнитов в проектах не должно быть, только действительно необходимые для теста ! Формы должны быть девственно чистыми !
ShareMem убрать к лешему везде ! Мало того , что не знаешь зачем оно надо, да еще и влупил его в хост-проекте совсем не туда, куда требует документация.
-
unit UfrmMain;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Menus;
type TfrmMain = class(TForm) menu: TMainMenu; mnuTest: TMenuItem; procedure mnuTestClick(Sender: TObject); private { Private declarations } public { Public declarations } end;
var frmMain: TfrmMain;
implementation
{$R *.dfm} //****************************************************************************** procedure TfrmMain.mnuTestClick(Sender: TObject); var LibHandle : THandle; ShowChild:function :Longint;StdCall; begin LibHandle := LoadLibrary('dll.dll'); if LibHandle <> 0 then begin @ShowChild := GetProcAddress(LibHandle,'ShowChild'); ShowChild; end; FreeLibrary(LibHandle); end; //****************************************************************************** end.
library dll; uses ShareMem, Windows, Messages, SysUtils, Variants, Classes, Controls, Forms, Dialogs, UfrmChild in 'UfrmChild.pas' {frmChild};
{$R *.res} //****************************************************************************** function ShowChild:Longint;StdCall; var frmChild:TfrmChild; begin try Application.CreateForm(TfrmChild,frmChild); except on E:Exception do ShowMessage(E.ClassName + ' ' + E.Message); end; Result := 1; end; //****************************************************************************** exports ShowChild; //****************************************************************************** begin end.
Сейчас форма реально появилась на экране - но приложение подвисло!
-
на главной форме при запуске дочки caption исчезает
-
> IntruderLab (13.03.08 17:24) [63]
> library dll; > uses > ShareMem,
Ты вообще-то русский ?)
-
ты знаешь нет, я башкир :). Убираю
-
Я тоже "русскостью", увы, "похвастать" не вправе)
Но .. надо же быть внимательным, когда это в твоих интересах)
-
извини,просто запарил,сейчас убиру и попробую запустить.
-
Вобщем то для тех кому интересно - решилось простым не прописыванием FreeLibrary(LibHandle);
-
> решилось простым не прописыванием > FreeLibrary
Тогда библиотека останется в памяти процесса до конца работы приложения, даже если форма, реализованная в ней, будет уничтожена и никогда более не создана вплоть до окончания работы приложения.
Тебе оно надо ?
Если надо, то дело хозяйское)
-
Я завершаю работу формы из самой дочерней формы, и вроде как она уничтожается
-
> завершаю работу формы из самой дочерней формы
Причем здесь форма ?
Я тебе про саму dll говорю - ты убрал LoadLibrary, значит ты не выгружаешь dll из памяти процесса.
> вроде как она уничтожается
Это она тебе сама сказала ?)
-
И вот еще что : везде stdcall понатыкано - это "щоб було" или как ?)
-
> Вобщем то для тех кому интересно - решилось простым не прописыванием > > FreeLibrary(LibHandle);
Логично. Ты создавал в библиотеке дочернюю форму и тут же выгружал эту библиотеку а вместе с нею и код всех обработчиков, которые наверняка присутствовали у дочерней формы. А представляешь, каково это - обработчики без кода! :)
-
Представляю :) Спасибо всем!!!
|