Solved

MDI form doesn't recognize Child forms from DLL

Posted on 1998-10-19
16
266 Views
Last Modified: 2010-04-06
Using the technique(s) presented in my earlier question about forms in DLLs, I am indeed able to make the form come up, as an MDIChild, on my main form.  HOWEVER, the main form does NOT recognize the child form AS A CHILD!!  It neither lists the form in the Window menu item, nor does it increment the MDIChildCount variable.  Since the form comes up okay, this doesn't make sense to me.

I need a way to be able to tell >if< an instance of a particular child form is already up.  If I can't access a handle for it, and the program doesn't recognize that it's there, what can I do?!?!

Any & all guidance much appreciated!
0
Comment
Question by:Raven1155
  • 7
  • 3
  • 3
  • +3
16 Comments
 

Author Comment

by:Raven1155
ID: 1343406
Oops!  Forgot to clarify that I do indeed declare the main form as fsMDIForm and the child as an fsMDIChild!
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 1343407
Is the parent of the MDI child form being set to be your main form when you create it in the DLL?

Cheers,

Raymond.
0
 

Author Comment

by:Raven1155
ID: 1343408
I'm not sure I understand the question...

The CHILD form is created in the DLL.  {I don't BELIEVE that I'm setting it as a Main form (though I'll check that one).}  Therefore I'm confused, since I don't do anything to the parent form of the MDI child except use it when creating the child-
 Child:=TChildForm.Create(Application.MainForm);
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 1343409
The application object in the DLL won't be the same as the application object in the EXE. The parent of the child form needs to be given the .EXE's Application.MainForm.

0
 

Author Comment

by:Raven1155
ID: 1343410
RWilson- we're STILL not communicating!  The parent of the child form IS the .EXE's Application.Mainform because "Application" in the DLL is set to the MainApp's Application value via the procedure call.

Reading other people's comments about other questions along this line, I don't think there currently IS a way to get the Main App. MDIForm to recognize the MDIChild forms created outside the Main App. code...
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 1343411
I think you may be right :-(
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1343412
raven1155,

 if all you need to know if the child is already created, why then don't you use a sort of list which contains all already created childs? When you create a child, add a reference to the list.

Zif.
0
 

Author Comment

by:Raven1155
ID: 1343413
Two comments, actually-
First, I've figured out a way to know if the child exists... by setting the Tag property of the main form when the child is created, and resetting it when the child is closed.  Not sophisticated, but that does work.

Second, to answer Zif's comment/question- the DLL creates the child window, but I do not have the child window's handle to add to any list (which I >think< is what you were saying).  Do you think there is a way to pass this back to the main program?  {I thought there wasn't...}
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 2

Expert Comment

by:Hagen040798
ID: 1343414
Hi

When You compile the Application and DLL with Packages, then used the Application and all Delphi-DLL's the same TApplication-Object and the same Application.MainForm. (All DLL's have Access to Variables in the Packages -> Application is in VCL30.dpl - this is the Trick from the Packages).

When You not compiled with the Package-Option's all DLL's and the Mainprogram used different TApplication-Objects. Now you must
change the Application-Variable from the DLL to the Application from the Mainprogram. (I think this is not good !).


Hagen

0
 

Author Comment

by:Raven1155
ID: 1343415
Hagen,

I'll have to read up more (probably a LOT more) on "packages" to truly understand your comment, but I thank you for it anyway!


Thanks!
 Jim 8^}
0
 
LVL 1

Accepted Solution

by:
Romanian earned 150 total points
ID: 1343416
You need something like this:
<-----Start ------->
library child;

uses
  SysUtils,
  Classes,
  Forms,
  Windows,
  Unit1 in 'Unit1.pas' {Form1};

var
 DLLApp : TApplication;
procedure ChildProc(Reason: Integer);
begin
 if Reason = DLL_PROCESS_DETACH then
   if Assigned(DllApp) then
     Application := DllApp;
end;

procedure CreateMDIChild(A : TApplication);
begin
 if not Assigned(DllApp) then begin
  DllApp := Application;
  Application := A;
 end;
 CF :=TChildForm.Create(Application.MainForm);
end;
exports
 CreateMDIChild index 1;
begin
 DllApp := nil;
 DLLProc := @ChildProc;
end.
<----continue---->
unit Mainform;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Menus;

type
  TForm1 = class(TForm)
    MainMenu1: TMainMenu;
    Win1: TMenuItem;
    Open1: TMenuItem;
    procedure Open1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

procedure CreateMDIChild(App: TApplication);external 'child.dll' index 1;

implementation

{$R *.DFM}

procedure TForm1.Open1Click(Sender: TObject);
begin
  CreateMDIChild(Application);
end;

end.
<----end-------->
0
 
LVL 1

Expert Comment

by:Romanian
ID: 1343417
When you create form with FormStyle = fsMDIChild Create procedure look in Application.MainForm for formstyle = fsMDIForm and this condition false - it don't create this form.
And .dll have its own Application variable so you must re-assign this variable.

Hint: I think this don't work with multiple application and you must make somesting more.(For example array of Appliction variables and call dll function with parameter App. After that if new application call you form you must reassign DLL Application property for proper work you child form in all application)
0
 

Author Comment

by:Raven1155
ID: 1343418
I'm grading the answer mostly just to close out the question.  My thanks to ALL for your comments!

Romanian,
 The poor grade is because 1) your code is on how to create the child form from a DLL, which I already knew and was not the question, and 2) because you didn't tell me anything that any of the others hadn't ALREADY told me in their comments.  Nonetheless, I thank you for your input!

J. Sky
0
 
LVL 1

Expert Comment

by:Romanian
ID: 1343419
Sorry I have not read whole question:)

You want create child form once and make it visible when you try to create it again?
In this case you must add code in create procedure
  for I := Application.ComponentCount - 1 downto 0 do
  begin
    if Application.Components[I] is TChildForm then
    begin
       (Temp as TChildForm).SetFocus;
    end;
  end;

May be you could make function {result := assigned(CF)} and you'll have information about this form.




0
 

Expert Comment

by:rbroz
ID: 1343420
Just today I tested and re-tested the claim in Delphi 4.02 Help that says that you must
assign main app MainForm.Handle to DLL application.handle. That simply doesn't work.
By endless combining  and surfing thru piles of news messages and WWW pages I found
technique that works 100%:
- save DLL's Application and Screen variables
- send values of Application and Screen variables from MAIN APP to DLL and set those
values to DLL's Application and Screen
- make a DLL's child windows - fsMdiChild
- create it with something like MyDLLChildForm.Create(nil) - this will make it a true child
of main app - it will appear on window menu too
- before quiting main app close all child windows in mainform.onclose event
- before freeing DLL set saved values of Application and Screen to it's original values

Good luck. And I sincerely hope Broland (Inprise) will once and for all make this problem clear in some future release of thi wonderful tool (Delphi)
0
 

Author Comment

by:Raven1155
ID: 1343421
Rboz, thanks for the input!
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

929 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now