![]() |
SetLength mein problem
Hi
Wer kann mir mal richtig das verschieben Dimensionieren von Arrays in Delphi beibringen. Irgendwie komme ich mit der Materie nicht zurecht und gute Tutorials gibt es auch nicht. Ich möchte also lernen wie man mit arrays unter Delphi richtig umgeht. Würde mich über ein paar Beispiel mit genauer Beschreibung freuen. Nix copy/paste das bringt mir nichts. Also von Anfang an! Was mich zuerst Interessiert wären Dynamische Arrays in verbindung mit Records. Dimensionieren Redimensionieren New(.. in verbindung mit Arrays ReAllocMem GetMem Copy usw ... Halt die ganze palette welche ein vernünfiges(Stabiles) arbeiten mit arrays ermöglicht. Gruß |
Re: SetLength mein problem
Erstmal für den Unterschied statische / dynamische Arrays:
Delphi-Quellcode:
Ein dynamisches Array dimensionierst und realloziierst du einfach nur mit SetLength() und der neuen Länge. Da ist nix mit ReAllocMem oder ähnlichem.
Type
StaticArray = Array[0..2] Of RecordType; DynamicArray = Array Of RecordType; Mit den Funktionen Low() und High() bekommt man den untersten und oberen Index des Arrays raus - funktioniert mit dynamischen wie auch statischen Arrays. Durch den letzten Fakt ist Code welcher auf diesen Funktionen baut (und nicht fest von einem Index 0 ausgeht) auch immer leicht auf ein statisches Array umstellbar. Length() ermittelt die Anzahl der Elemente in einem Array (statisch wie auch dynamisch). Beachte hierbei den Unterschied zwischen Index und Anzahl der Elemente. Auch Length() ist auf beide Typen von Arrays anwendbar. Noch ein Hinweis zum Schluss: Wenn man ein statisches Array an eine Funktion übergibt, welche ein dynamisches Array als Parameter hat, dann wird das statische auf den Index 0 angepasst. Folgendes Beispiel:
Delphi-Quellcode:
Type
MyArray = Array[5..10] Of Integer; Procedure MySubFunc(Const A: Array Of Integer); Begin // ergibt von 0 bis 5 WriteLn('MySubFunc(): Array from ', Low(A),' to ', High(A)); End; Procedure CallIt; Var lArr : MyArray; Begin // ergibt 5 bis 10 WriteLn('CallIt(): Array from ', Low(lArr),' to ', High(lArr)); MySubFunc(lArr); End; |
Re: SetLength mein problem
Erst mal danke für die ausfühliche Beschreibung.
Zitat:
Was mir auffällt der wechsel vom Statisch zum dynamischen array in einer Function kommt ja einen 2 Dimensionalen array gleich oder sehe ich das verkehrt? Array [0..5, 5..10]. Oder? Könnte man ja dann auch direkt so auslegen. Oder macht das einen unterschied. Ein Beispiel: Neue Frage.
Delphi-Quellcode:
Was ich nun nicht verstehe ist folgendes!
Type
PWindowDescr = ^TWindowDescr; TWindowDescr = Packed record hWnd : DWORD; ProcessID : Pointer; Title : String; Klass : String; ExeName : String; End; Var DynamicArray : array of PWindowDescr; Wenn ich nun ein DynamicArray in einer Function einsetze ..
Delphi-Quellcode:
Warum kann ich dann nicht einfach bei SetLength ..
Function GetWindowList(DynamicArray : array of PWindowDescr): DWORD;
Delphi-Quellcode:
eingeben ?
SetLength(DynamicArray, 100)
Theoretisch müßte doch dann das Array um 100 einträge Redimensioniert werden. Woran liegt es nun das es auf diese weise nicht geht. Der Fehler welcher angezeigt wird ist 'incompatible types' Es ist aber doch ein dynamisches Array. Ich habe festgestellt das dies nur geht wenn man eine extra Type declariert
Delphi-Quellcode:
und dann mit SetLength(DynamicArray2, 100) eine neue größe zuweist.
DynamicArray2 = array of PWindowDescr;
Warum geht es also nur auf dieser art Ich möchte ja die Länge von DynamicArray ändern und nicht die von DynamicArray2 Das sind so die kleinen Probleme wo ich nicht so recht bescheid weis. Gruß |
Re: SetLength mein problem
Hallo,
Zitat:
im obigen Beispiel wird das statische Array in der Funktion so behandelt, als wäre es ein dynamisches. Der Aufbau der beiden Typen ist ja grundsätzlich der selbe. Zitat:
Zitat:
Wenn Du irgendwo ein "array of Irgenwas" übergibst, ist das immer ein eigener Typ und gänzlich unterschiedlich zu einem anderen "array of irgendwas". Also;
Delphi-Quellcode:
Beide Funktionen verwenden den gleichen Array-Aufbau, aber der Typ (und damit die Signatur der Funktion) ist immer einzigartig. Delphi erschafft quasi implizit einen neuen Typen.
function X(Value: array of Integer): Boolean;
begin // Tu was end; function Y(Value: array of Integer): Boolean; begin // Tu was end; Gruß xaromz |
Re: SetLength mein problem
Zitat:
Ist sicherlich ne Überlegung wert, sich damit zu befassen. |
Re: SetLength mein problem
Hallo,
Zitat:
Gruß xaromz |
Re: SetLength mein problem
Zitat:
|
Re: SetLength mein problem
Zitat:
Ich hoffe das jetzt richtig verstanden zu haben. Hier die änderung.
Delphi-Quellcode:
Es läuft alles einträge werden richtig eingelesen und zugewiesen.
PWindowDescr = ^TWindowDescr;
TWindowDescr = record hWnd : HWND; ProcessID : Pointer; Title : String; Klass : String; ExeName : String; End; AWindowDescr = array of PWindowDescr; Var wDescr : AWindowDescr; // Alle offene Fenster suchen. Function GetWindowList(var wDescr: AWindowDescr): DWORD; Var IntI : Integer; // Zähler füt die Fenster Handle h_wnd : HWND; // Fenster Handle Index : Integer; Begin // Zähler initialisieren IntI := 0; h_wnd := GetTopWindow(0); // Zuweisen von 100 Array Elementen of PWindowDescr // Zum einlesen der Fenster Handle Index := 100; SetLength(wDescr, Succ(index)); New(wDescr[index]); ZeroMemory(wDescr[index], SizeOf(wDescr[index]^)); Repeat // Zähler um 1 erhöhen inc(IntI); // Wenn mehr als High Fenster Handle gefunden If IntI > High(wDescr) Then // Array um 10 erhöhen SetLength(wDescr, High(wDescr) + 10); // Fenster Handle ermitteln h_wnd := GetWindow(h_wnd, GW_HWNDNEXT); // Fenster Handle gefunden If h_wnd <> 0 Then begin New(wDescr[IntI]); ZeroMemory(wDescr[IntI], SizeOf(wDescr[IntI]^)); // Wert zuweisen wDescr[IntI].hWnd := h_wnd; // Window Informationen einlesen GetWindowInfo(wDescr[IntI]); end; // Schleife durchlaufen bis kein Fenster Handle mehr existiert until h_wnd = 0; // Array Redimensionieren Fenster-Handle Count SetLength(wDescr, IntI); // Ergebnis übergeben Result := IntI; End; Wäre nicht schlecht wenn mir jemand fehler meldet wenn ersichtlich ! Gruß |
Re: SetLength mein problem
Zitat:
gruß |
Re: SetLength mein problem
Ich gebe deinen Quellcode mal wieder mit ein paar Anmerkungen als Kommentar
Delphi-Quellcode:
Ich hoffe das hilft und löst nicht wieder Beleidigungen aus...
PWindowDescr = ^TWindowDescr;
TWindowDescr = record hWnd : HWND; ProcessID : Pointer; Title : String; Klass : String; ExeName : String; End; AWindowDescr = array of PWindowDescr; // Warum ein Array von Zeigern auf den Record anstatt eines Arrays of Records? Var wDescr : AWindowDescr; // Alle offene Fenster suchen. Function GetWindowList(var wDescr: AWindowDescr): DWORD; Var IntI : Integer; // Zähler füt die Fenster Handle h_wnd : HWND; // Fenster Handle Index : Integer; Begin // Zähler initialisieren IntI := 0; h_wnd := GetTopWindow(0); // Zuweisen von 100 Array Elementen of PWindowDescr // Zum einlesen der Fenster Handle Index := 100; SetLength(wDescr, Succ(index)); // also werden hier 101 Elemente angelegt, Zugreifbar mit Index 0 bis 100 New(wDescr[index]); // warum holst du dir den Speicher für nur einen Record (den an Index 100)? Was ist der Sinn? ZeroMemory(wDescr[index], SizeOf(wDescr[index]^)); // warum initialisierst du den Record bei Index 100? // Ich glaube der erste Parameter müsste noch ein ^ bekommen, weil sonst // schreibt ZeroMemory die Array-Pointer-Liste mit 0'en voll anstatt des Records Repeat // Zähler um 1 erhöhen // warum? Willst du Index 0 nicht nutzen? Wenn vor dem Until ein Inc(IntI) inc(IntI); // Wenn mehr als High Fenster Handle gefunden If IntI > High(wDescr) Then // Array um 10 erhöhen SetLength(wDescr, High(wDescr) + 10); // High() gibt dir den höchsten Index an, aber nicht die Anzahl der Elemente. SetLength() will die Anzahl der neuen Elemente, also Anzahl der Elemente bisher + 10, sprich: SetLength(wDescr, Length(wDescr) + 10); // Fenster Handle ermitteln h_wnd := GetWindow(h_wnd, GW_HWNDNEXT); // Fenster Handle gefunden If h_wnd <> 0 Then begin New(wDescr[IntI]); // beachte hier: es ist der Index 100 schon initialisiert! ZeroMemory(wDescr[IntI], SizeOf(wDescr[IntI]^)); // siehe oben: 1. Parameter sollte noch ein ^ bekommen // Wert zuweisen wDescr[IntI].hWnd := h_wnd; // Window Informationen einlesen GetWindowInfo(wDescr[IntI]); end; // Schleife durchlaufen bis kein Fenster Handle mehr existiert until h_wnd = 0; // Array Redimensionieren Fenster-Handle Count SetLength(wDescr, IntI); // wenn du oben das mit dem Inc(IntI) änderst, dann hier Succ(IntI) als höchstes Element setzen // Ergebnis übergeben Result := IntI; End; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:46 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