![]() |
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? |
Re: Was muss ich einbinden?
Unit Windows
|
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. |
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:
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.
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. |
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. |
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 00:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz