Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Was muss ich einbinden? (https://www.delphipraxis.net/84936-muss-ich-einbinden.html)

schuetzejanett 23. Jan 2007 19:35


Was muss ich einbinden?
 
Hallo,

wollte eine Klasse um eine Liste von Regionen zu verwalten, damit ich später bei Klick auf eine Grafik überprüfen kann auf welchen Teil der grafik ich geklickt habe.
Nun wollte ich wissen was ich unter uses alles einbinden muss um regionen deklarieren zu können. habe zurzeit nur Classes, SysUtils, Dialogs eingebunden. Was brauch ich noch, damit der Tip HRGN nicht undefiniert ist?

Muetze1 23. Jan 2007 19:36

Re: Was muss ich einbinden?
 
Unit Windows

schuetzejanett 23. Jan 2007 19:43

Re: Was muss ich einbinden?
 
Danke und wie mache ich es jetzt das ich in einer liste nur diese regionen speichern kann habe mir jetzt einen Typ dartBoardField deklariert in dem eine region und der zugehörige name gespeichert ist will ich diesen jetzt allerdings der Liste hinzufügen erhalte ich die nachricht
Inkompatible Typen Dartfield und Pointer

Delphi-Quellcode:
unit DartBoard;

interface

uses
  Classes, SysUtils, Dialogs, Windows;

  type DartField = record
       Region : HRGN;
       Field  : String
       end;

  type TDartBoard = class(TList)

  private

  public

   procedure Add(Item: Dartfield);
  end;

implementation

{ TDartBoard }

procedure TDartBoard.Add(Item: DartField);
begin
inherited Add(Item);
end;
end.

Muetze1 24. Jan 2007 08:50

Re: Was muss ich einbinden?
 
TList ist eine Klasse zum Verwalten von Zeigern. Daher müsst du einen Zeiger auf den Record einfügen. Der Record selber geht nicht, sonst müsste TList rausbekommen wie gross die Elemente sind. Da sie das nicht kann, verwaltet sie einfach nur Zeiger auf die Elemente und die Daten an sich interessieren sie nicht - da zeigt ja der Zeiger hin.

Um einen Zeiger auf den Record einzufügen, musst du erstmal einen festen Speicherplatz für den Record erstellen. Ein einfacher @-Operator hilft nicht viel, da dies nur ein temporärer Zeiger wäre, da der Record dann nur eine lokale Veriable wäre, welche bei verlassen der Procedure seine Gültigkeit verliert.

Delphi-Quellcode:
unit DartBoard;

interface

uses
  Classes, SysUtils, Dialogs, Windows;

type
  TDartField = record
    Region : HRGN;
    Field  : String
  end;
  PDartField = ^TDartField;  // Zeiger auf Record als PDartField definieren

  TDartBoard = class(TList)
  private

  protected
    procedure Notify(Ptr: Pointer; Action: TListNotification); override;

  public

    procedure Add(Item: TDartfield);
  end;

implementation

{ TDartBoard }

procedure TDartBoard.Add(Item: TDartField);
Var
  lEntry: PDartField;
begin
  New(lEntry);           // neuen Record Speicherplatz besorgen
  lEntry^ = Item;        // Inhalt kopieren
  inherited Add(Item);   // Zeiger einreihen
end;

procedure TDartBoard.Notify(Ptr: Pointer; Action: TListNotification);
Begin
  If Action = lnDeleted Then
    Dispose(PDartField(Ptr));

  Inherited;
End;

end.
Die Funktion Notify wird von TList deklariert und von TList aufgerufen, wenn die Items verarbeitet werden. Dabei kann man gut die Aufrufe vom Entfernen eines Eintrages nutzen, um den alloziierten Speicherplatz wieder freizugeben. Die Funktion wird von Delete, Clear, Extract etc aufgerufen und so muss man nur hier ansetzen um das zentral zu erledigen.

Thorben_K 24. Jan 2007 10:51

Re: Was muss ich einbinden?
 
sry wenn ich doof frage, aber warum geht es so den nicht? ich weiss oben steht es, aber deine ausführung ist mir nicht ganz schlüssig...

Delphi-Quellcode:
unit DartBoard;

interface

uses
  Classes, SysUtils, Dialogs, Windows;

  type DartField = record
       Region : HRGN;
       Field  : String
       end;

  type TDartBoard = class(TList)

  private

  public

   procedure Add(Item: Dartfield);
  end;

implementation

{ TDartBoard } 

procedure TDartBoard.Add(Item: DartField);
var
  p : Pointer;
begin
p := @Item;
inherited Add(p);
end;
end.

SirThornberry 24. Jan 2007 11:42

Re: Was muss ich einbinden?
 
das geht nicht weil Item auf dem Stack liegt und nach dem verlassen der Procedure somit ungültig wird wenn der Stack wieder abgeräumt wird. Somit hast du einen Pointer der auf den Stack zeigt wo aber jederzeit dann was anderes liegen kann was später auf den Stack kommt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz