I am trying to create an application that allows one to browse a .MDB file to add/edit/delete basic personal information for fraternity alumni. It is something that I have been casually doing in my free time with little trouble, however, I have run into a snag recently.

I have a few classes in this application.
*TRhoAddress is subclass of TGroupBox with TEdits and TLabels placed on it. I use TRhoInfo.Create(AOwner) to create a new one of these. They are placed in a scrollbox/flowpanel for viewing, as our records often show multiple addresses for our alumni.
*TRhoInfo is a subclass of TCustomForm with TEdits/TLabels/TButtons and the afformentioned TFlowPanel in a TScrollBox. I had problems using a .create style constructor, and various forums advised using a .createnew constructor.

I intended the above classes to be used as components. I have a main form and a data module that I use coordinate the application. The main form contains a TDBGrid and some TEdits. As users fill out various parameters, the form pulls appropriate data from the MDB and puts it in the TDBGrid. When a cell in the TDBGrid is double clicked, the application should (a) open a TRhoInfo window (b) populate the fields from the database (c) add an entry into the TMenuBar of the main form for refocusing windows ala the Window Menu of most office applications.

I have two problems with my application right now. The first is that the TRhoInfo's that I create do not appear in the TaskBar. This is a minor annoyance that I planned on remedying with the Window menu. The second (more serious) is that upon calling TRhoInfo.Create, every previously create TRhoInfo seems to be erased.

var
  Contain:Array of TRhoInfo;
  i:integer;

for i:=0 to 10 do
begin
  SetLength(Contain, Length(Contain) + 1);                        {open up an extra space}
  Contain[High(Contain)] := TRhoInfo.CreateNew(Self,InttoStr(i)); {dump a new object in}
end;                                                              {repeat}

// This is the result....
// Contain[0].Name = '10';
// Contain[1].Name = '10';
// Contain[2].Name = '10';
// Contain[3].Name = '10';
// Contain[4].Name = '10';
// Contain[5].Name = '10';
// Contain[6].Name = '10';
// Contain[7].Name = '10';
// Contain[8].Name = '10';
// Contain[9].Name = '10';

It is as if I can only have one instance of TRhoInfo. I assume this means that I am only dealing with references, and I can only further assume that it has to do with the fact that I'm using CreateNew rather than Create.

To be honest, I'm stumped. I'm a competent programmer, but I only have 8 weeks experience in Delphi. Any help is appreciated.

Thanks,
TeejMonster

*Edit -- Forgot to post a link to my source. http://tinyurl.com/m4q9db

What it do TeejMonster!

As far as I know about arrays (which I use alot), I know that first of all an array is like a chain, meaning that you can set the length of the chain by using SetLength(yourarray, lengthofyourarray);

What I see on your code is that you are FOR looping it to set the length of you array to be the length of your array, plus 1.
No need to do that.

Just make a SetLength to your array ONCE, then for loop it to create whatever your array consist of.

In your case the code should be following:

Procedure
var
Contain:Array of TRhoInfo;
i:integer;

begin

SetLength(Contain, 10);

for i:=0 to 10 do
begin
Contain := TRhoInfo.CreateNew(Self,InttoStr(i));
end;

end;


However I dont know what the last parameter of CreateNew is.
But thats the way you should do it.

That is:
1. Set length of array BEFORE loop processing it
2. Only loop process what it is that you want to do with your array.

And some extra, if you're using an arrayed array, that is array of array of, THEN you can use SetLength to set the length of the array within the array. Example maybe?

Procedure
var
Contain:Array of array of string;
i,y:integer;

begin

SetLength(Contain, 10);

for i:=0 to 10 do
begin

SetLength(Contain, 5);

for y:=0 to 5 do
begin

Contain[i,y]:='Array (i): '+inttostr(i)+' | Array (y): '+inttostr(y);

end;

end;

end;

Hope this helps!

Holler anytime you need help!

Bye!

As far as I know about arrays (which I use alot), I know that first of all an array is like a chain, meaning that you can set the length of the chain by using SetLength(yourarray, lengthofyourarray);

What I see on your code is that you are FOR looping it to set the length of you array to be the length of your array, plus 1.
No need to do that.

Just make a SetLength to your array ONCE, then for loop it to create whatever your array consist of.

That doesn't quite address my problem (unless I am grossly mistaken). Even before the execution of that loop, the problem that occurs is that if I run CreateNew twice, each time storing a separate TRhoInfo variable, both variable will contain the same object.

I've posted a less cluttered example. I wish I knew what about the code was causing this. As near as I can tell, it was the switch from a normal Create constructor to a CreateNew constructor. I don't care which I use in the end, but I can't get this to run normally with any combination.

Oh, I see.

Well have you tried my suggestion?

I think the problem might be in the RhoInfo.pas unit or the RhoAddress.pas unit.

Have you made those two on your own?

The problem is definitely in the RhoInfo.pas unit. RhoAddress works fine, and uses a perfectly normal Create constructor. When I tried to do this with RhoInfo (a subclass of TCustomForm) the unit would not compile. The only way I have been able to get a clean compile is by creating the class as shown, however, it's functionality is deeply impaired. A single instance works fine, but I want to have multiple independent instances, not multiple clones.

This article has been dead for over six months. Start a new discussion instead.