Solved

MDI form doesn't recognize Child forms from DLL

Posted on 1998-10-19
16
264 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
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
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: …

708 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

18 Experts available now in Live!

Get 1:1 Help Now