Solved

MDI form doesn't recognize Child forms from DLL

Posted on 1998-10-19
16
269 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Delphi TcxGrid group footer summary 3 358
Intraweb download file link ? 1 168
Delphi: making a BW image transparent 10 95
Can Live bindings change TGrid Cell Colour ? 1 35
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

730 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