[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 203
  • Last Modified:

MDI Windows needing separate values


I have an MDI application.  On the menu, one of the buttons is to open a window where
the user can enter SQL.  I WANT TO ALLOW MULTIPLE COPIES OF THIS WINDOW TO BE OPEN.
Here's the code:

-------------------------------------------------------------
procedure TMainForm.SQLWindow1Click(Sender: TObject);
var
  Child: TSQL_F;
begin
  { create a new MDI child window }
    Child := TSQL_F.Create(Application);
end;

// THIS CODE APPEARS TO WORK FINE.  IT OPENS A NEW WINDOW EACH TIME I CLICK THE MENU

--------------------------------------------------------------

The SQL Window can have one of three different datamodule attached to it.  I do this
with pointers.

Here is the various code fragments:
---------------------------------------------------------------
unit SQL_Form;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ...


type
  TSQL_F = class(TForm)
    ExecuteBtn: TBitBtn;
    ...
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


var {Global Variables }
  SQL_F          : TSQL_F;
  Row            : Integer;

implementation


uses Delete_Explain_Form, Oracle_DataMod1, Main, DataModStuff;

Var {Local Variables }
 
 First_Time : Boolean;
 ThisWindow : TSQL_F;
 ActiveDataMod: ^TDataModule;  // Pointer to the datamodule that this window is using



{$R *.DFM}

-----------------------------------------------------------------------

The problem that I am having is that the pointer to the datamodule works if I only
have ONE window.  I can open one window and close one window, everything is fine.
Here's the problem scenario:  

Open first copy of window
Open second copy of window
Close one of these windows
Close the second window - APP BLOWS UP HERE

-- Let me walk you through the process of how I create the pointer

-----------   in the ONCREATE ROUTINE

// Now Create the Pointer to the Active Data Module;
// This simply allocates memory for the pointer
New(ActiveDataMod);



-----------   In the ONACTIVATE ROUTINE

{if this is the FIRST TIME THIS ROUTINE IS RUN}

If New_Connection_No = 1 then
      ActiveDataMod^ := Oracle_DM1;   //Oracle_DM1 is a data module that is already created

If New_Connection_No = 2 then
      ActiveDataMod^ := Oracle_DM2;

If New_Connection_No = 3 then
      ActiveDataMod^ := Oracle_DM3;


// Set up the Direct Oracle Access parameters
ThisWindow.OraclewwDataSet1.Session := (ActiveDataMod^ as TOracle_DM1).OracleSession1;
ThisWindow.OracleQuery1.Session := (ActiveDataMod^ as TOracle_DM1).OracleSession1;


// THIS CODE APPEARS TO WORK FINE.  I CAN CHANGE CONNECTIONS AS NEEDED

-------------------------------------------------------------------------------


// HERE IS WHERE I HAVE PROBLEMS

procedure TSQL_F.FormClose(Sender: TObject; var Action: TCloseAction);
begin

// Now Free the Pointer to the Active Data Module;
// This simply de-allocates memory for the pointer
Dispose(ActiveDataMod);  // THIS IS WHERE IT BLOWS UP IF I HAVE MULTIPLE COPIES

// Needed to close an MDI Window
Action := caFree;
end;

----------------------------------------------------------------------------


It seems like I only have one ActiveDataMod^.  When debugging, and I close the first window,
ActiveDataMod^ = $F3938C.  I close the window.  When I close the second window, the
ActiveDataMod^ has the same value.  That value, i.e location, i.e pointer, no longer
exists.  This leads me back to the first statement, it seems like I only have one
ActiveDataMod pointer that is SHARED between copied of the MDI window.  But shouldn't each copy of this MDI window have it's OWN variables, specifically the same variables, but each window having it's own SEPARATE, different values for those windows?

What am I doing wrong? Do I have something wrong with scoping.  What I think are local variables are really global variables???

Thanks
George Spears
0
gspears060598
Asked:
gspears060598
1 Solution
 
interCommented:
Hi, I think the confusion is that you have a pointer to an object which you allocate. No need to to this since you have already created data modules. So add
ActiveDataMod : TDataModule;
to your protected fields of TSQL_F. And do not create it. It already creates one instance for each of your MDI child windows. So remove all the pointer dereferencing ^ symbols and run-do not dispose it either-
regards, igor
0
 
dwwangCommented:
I bet you are a C/C++ programmer before -- since I had made such
kind of mistakes and I am a C++ programmer before :)

In Delphi/Object Pascal, components such as TDatamodule are
already POINTERS, so you should never declare pointer of them and
use as in C/C++.

You should do like this:

1. ActiveDataMod: TDataModule;
   (in replace of your: ActiveDataMod: ^TDataModule)

and

2. If New_Connection_No = 1 then
          ActiveDataMod := Oracle_DM1;
(inreplace of you :
              If New_Connection_No = 1 then
                     ActiveDataMod^ := Oracle_DM1; )

3. You never need new() and dispose of those objects.
0
 
gspears060598Author Commented:
That did the trick...  and you're right <sheepish grin> I am a non-professional C programmer...

Thanks

0

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now