Solved

MDI Windows needing separate values

Posted on 1998-10-10
3
195 Views
Last Modified: 2010-04-03

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
Comment
Question by:gspears060598
3 Comments
 
LVL 5

Expert Comment

by:inter
ID: 1342455
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
 
LVL 4

Accepted Solution

by:
dwwang earned 70 total points
ID: 1342456
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
 

Author Comment

by:gspears060598
ID: 1342457
That did the trick...  and you're right <sheepish grin> I am a non-professional C programmer...

Thanks

0

Featured Post

Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

Question has a verified solution.

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

Suggested Solutions

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…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.

809 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