Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

MDI Windows needing separate values

Posted on 1998-10-10
3
Medium Priority
?
201 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 280 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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

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…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…

824 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