Pergunta

I'm trying to use a class in my program.

TStack = Class
Public
  constructor Create; Overload;
  Procedure Add(Frm:TForm);
  Procedure Remove();
  Procedure Do_Close;

 Private
  List  : Array[1..Max_Forms] of Rec;
  Count : Byte;
End;

Constructor:

constructor TStack.Create;
begin
  Self.Count := 0;
end;

Procedure TStack.Add(Frm:TForm);
begin
  Inc(Self.Count);
  List[Count].Form     := @Frm;
  List[Count].Width    := Frm.Width;
  List[Count].Height   := Frm.Height;
  List[Count].left     := Frm.Left;
  List[Count].Top      := Frm.Top;
end;

I can't change value of Count variable! It cause Run-Time error : Access violation....Write of address 000001E4

What's the problem?!

FOR MORE INFORMATION:

I'm trying to store a pointer to each form in a structure like this :

  Rec = Record
      Form      : ^TForm;
      Maximized : Boolean;
      Width,
      Height,
      left,
      Top       : Integer;
    End;

And then

Procedure TStack.Do_Close;
var
  i      : integer;
  MyForm : TForm;
begin
 i := .....some code here.......;
 MyForm := @List[i].Form;
 ShowMessage('I will close '+MyForm.Caption);
 MyForm.Close;
end;

AND call constructor like this to initialize 'Count':

Stack.Create;
Foi útil?

Solução

As described in comments you are attempting to create the object like this:

var
  Stack: TStack;
....
Stack.Create;

This is a classic mistake, and one that we've all made. You are calling a method on an uninitialized instance variable.

In order to instantiate a class you need to write this:

Stack := TStack.Create;

On top of that I have the following comments:

  1. Use zero-based indexing for arrays. That's the convention everywhere in Delphi apart from anachronistic strings. And even that is changing in newer versions.
  2. Don't use static arrays for a stack unless you have a good reason for doing so. You'll just run the risk of running out of space. Or allocating more memory than you need. Use a dynamic array.
  3. Rather than a dynamic array, you could use TList<T>.
  4. Even so, one wonders why you are making your own stack class when there is the perfectly good TStack<T>.
  5. You store the address of a local variable in your stack. In TStack.Add you add @Frm into the container. As soon as TStack.Add returns, @Frm is meaningless. That's because Frm is a local variable whose life ends when the function that owns it returns. I think you want to take a copy of Frm.

Picking up item 5 in more detail, your record is declared like this:

Rec = Record
  Form      : ^TForm;
  Maximized : Boolean;
  Width,
  Height,
  left,
  Top       : Integer;
End;

It is a mistake to use ^TForm. That is a pointer to a variable holding a pointer to an object. That's two levels of indirection, one too many. You must declare the Form field to be of type TForm. I suggest you revise the way Delphi object reference variables work. Delphi classes are what is known as reference types. A variable of type TMyClass where TMyClass is class(...) is already a pointer. The language automatically de-references the pointer when you use the . operator to access members.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top