![]() |
array of record sortieren
Bekomme es wieder nicht gebacken.
Delphi-Quellcode:
Ich möchte das Array so sortieren das der "StringList[j]" String gleich ist mit dem IdentStr.
procedure TSkinListView.SortItems(hListView: hWnd; ColumnIndex: Integer);
var i, j : Integer; hItemsInfo : TItemsInfo; StringList: TStringList; ItemCount: Integer; buf: array [0 .. 255] of Char; ItemText: PWideChar; begin ListView_SortItems(hListView, @CompareFunc, ColumnIndex); // Liste wird sortiert StringList := TStringList.Create; try ItemCount := ListView_GetItemCount(hListView); for i := 0 to ItemCount - 1 do begin ZeroMemory(@buf, sizeof(buf)); ListView_GetItemText(hListView, i, 1, buf, sizeof(buf)); ItemText := buf; StringList.Add(ItemText); // Stringliste anhand der Sortierung erstellen. end; for i := High(ItemsInfo) downto Low(ItemsInfo) do begin for j := 0 to (i - 1) do begin // Problem es wird nur der nächste mit dem vorherigen getauscht. if StringList[j] > ItemsInfo[j].IdentStr then begin hItemsInfo := ItemsInfo[j]; ItemsInfo[J] := ItemsInfo[j + 1]; ItemsInfo[J + 1] := hItemsInfo; end; end; end; finally StringList.Free; end; end; Kann wer helfen und sagen was falsch läuft. |
AW: array of record sortieren
Ich gehe mal davon aus, ItemsInfo ist dein "array of record", welches sortiert werden soll. Oder?
Wo wird denn Itemsinfo gefüllt? Wo und wie ist ItemsInfo deklariert? |
AW: array of record sortieren
Zitat:
Delphi-Quellcode:
TItemsInfo = record
Item: Integer; SubItem: Integer; ImgIcon: HICON; Extension: WideString; Path: WideString; Width: Integer; Height: Integer; IdentStr: WideString; end; TSkinListView = class(TInterfacedPersistent, ISkinListView) private ItemsInfo: array of TItemsInfo; //...
Delphi-Quellcode:
Ich sortiere die Liste
procedure TSkinListView.SetItemIcon(nItem, nSubItem: Integer;
ImgIdent: WideString; ImgPath: WideString); var lpImg: LONG_PTR; hbmReturn: HBitmap; ii: ICONINFO; hbmMask: HBitmap; bw, bh: single; begin if ImgPath <> '' then begin if FileExists(ImgPath) then begin if GdipLoadImageFromFile(PWideChar(ImgPath), lpImg) = OK then begin GdipCreateHBITMAPFromBitmap(lpImg, hbmReturn, 0); if hbmReturn <> 0 then begin GdiPGetImageDimension(lpImg, bw, bh); hbmMask := CreateCompatibleBitmap(GetDC(0), round(bw), round(bh)); ii.fIcon := TRUE; ii.hbmColor := hbmReturn; ii.hbmMask := hbmMask; hic := CreateIconIndirect(ii); DeleteObject(hbmMask); DeleteObject(hbmReturn); end; end; end; end; SetLength(ItemsInfo, nItem + 1); ItemsInfo[nItem].Item := nItem; ItemsInfo[nItem].SubItem := nSubItem; ItemsInfo[nItem].Width := round(bw); ItemsInfo[nItem].Height := round(bh); ItemsInfo[nItem].ImgIcon := hic; ItemsInfo[nItem].IdentStr := ImgIdent; end;
Delphi-Quellcode:
ListView_SortItems(hListView, @CompareFunc, ColumnIndex); // Liste wird sortiert
und fülle eine StringList mit den Aktuellen Daten so wie sie sortiert wurden. Alphabetisch positiv und negativ abhängig von der Sortier Richtung. Nun muss ich das Array of record ItemsInfo so sortieren das der IdentStr gleich ist den Index der StringList. Wenn ich das nicht tue werden die Icons an falscher Position gezeichnet. ItemsInfo[J] müsste dann gleich sein wie der Index der Stringlist der so verglichen wird
Delphi-Quellcode:
if StringList[j] > ItemsInfo[j].IdentStr then
|
AW: array of record sortieren
Ich bin zwar nue ein Anfänger,doch ein Senf kann ich dazugeben.
So habe ich es gemacht. Ist natürlich nur als Beispiel gedacht.
Delphi-Quellcode:
type
TRec = record Titel : string; Network : string; URL : string; end; type TArray = array of TRec; function Compare(const Data1, Data2: TRec): Integer; begin Result := CompareText(Data1.Titel, Data2.Titel); end; procedure Swap(var Data1, Data2: TRec); var Temp : TRec; begin Temp := Data1; Data1 := Data2; Data2 := Temp; end; procedure SortArray(var People: TArray); var Index : Integer; Laenge : Integer; Swapped : Boolean; begin Laenge := Length(People); repeat Swapped := False; for Index := 1 to Laenge - 1 do begin if Compare(People[Index - 1], People[Index]) > 0 then begin Swap(People[Index - 1], People[Index]); Swapped := True; end; end; Dec(Laenge); until not Swapped; end; procedure TForm1.Button1Click(Sender: TObject); var Index : Integer; Array_Rec : TArray; begin Index := 0; SetLength(Array_Rec, Memo1.Lines.Count - 1); while Index <= Memo1.Lines.Count - 1 do begin Array_Rec[Index].Titel := Memo1.Lines[Index]; Array_Rec[Index].Network := Memo1.Lines[Index + 1]; Array_Rec[Index].URL := Memo1.Lines[Index + 2]; Inc(Index, 3); end; SortArray(Array_Rec); for Index := 0 to Length(Array_Rec) - 1 do begin if Array_Rec[Index].Titel <> '' then begin Memo2.Lines.Add(Array_Rec[Index].Titel); Memo2.Lines.Add(Array_Rec[Index].Network); Memo2.Lines.Add(Array_Rec[Index].URL); end; end; end; |
AW: array of record sortieren
Danke werde mir das mal anschauen.
Dachte ich könnte das direkt in meine sortier Funktion mit übertragen. Nur weis ehrlich nicht wie.
Delphi-Quellcode:
function CompareFunc(lp1, lp2, SubItem: LParam): Integer; stdcall;
var buf1, buf2: WideString; a, b: Integer; begin SetLength(buf1, MAX_PATH); ZeroMemory(@buf1[1], MAX_PATH); SetLength(buf2, MAX_PATH); ZeroMemory(@buf2[2], MAX_PATH); ListView_GetItemText(LVHandle, lp1, SubItem, @buf1[1], MAX_PATH); ListView_GetItemText(LVHandle, lp2, SubItem, @buf2[1], MAX_PATH); case ColumnInfo[SubItem].SortType of // Dateigröße sortInt: begin // alles nach dem Leerzeichen entfernen (z.B. "12345 B") if (pos(#32, buf1) > 0) then delete(buf1, pos(#32, buf1), length(buf1)); if (pos(#32, buf2) > 0) then delete(buf2, pos(#32, buf2), length(buf2)); if UpDown then begin b := StrToIntDef(buf1, 0); a := StrToIntDef(buf2, 0); end else begin a := StrToIntDef(buf1, 0); b := StrToIntDef(buf2, 0); end; if (a > b) then Result := 1 else if (a < b) then Result := -1 else Result := 0; end // Name oder Typ else begin if UpDown then Result := lstrcmpi(@buf2[1], @buf1[1]) else Result := lstrcmpi(@buf1[1], @buf2[1]); end; end; end; |
AW: array of record sortieren
Deine Funktion gibt mir falsche werte zurück.
Delphi-Quellcode:
PItemsInfo = ^TItemsInfo;
TItemsInfo = record Item: Integer; SubItem: Integer; ImgIcon: HICON; Extension: WideString; Path: WideString; Width: Integer; Height: Integer; IdentStr: WideString; end;
Delphi-Quellcode:
type TArray = array of TItemsInfo;
Delphi-Quellcode:
procedure TSkinListView.Swap(var Data1, Data2: TItemsInfo);
var Temp : TItemsInfo; begin Temp := Data1; Data1 := Data2; Data2 := Temp; end; function TSkinListView.Compare(const Data1, Data2: TItemsInfo): Integer; begin Result := CompareText(Data1.IdentStr, Data2.IdentStr); end; procedure TSkinListView.SortArray(var ItemsInfo: TArray); var Index : Integer; Laenge : Integer; Swapped : Boolean; begin Laenge := Length(ItemsInfo); repeat Swapped := False; for Index := 1 to Laenge - 1 do begin if Compare(ItemsInfo[Index - 1], ItemsInfo[Index]) > 0 then begin Swap(ItemsInfo[Index - 1], ItemsInfo[Index]); Swapped := True; end; end; Dec(Laenge); until not Swapped; end;
Delphi-Quellcode:
var
ItemsArray: TArray; begin ItemCount := ListView_GetItemCount(hListView); SetLength(ItemsArray, ItemCount); i := 0; while i <= ItemCount - 1 do begin ItemsArray[i].IdentStr := ItemsInfo[i].IdentStr; ItemsArray[i].Item := ItemsInfo[i].Item; ItemsArray[i].SubItem := ItemsInfo[i].SubItem; ItemsArray[i].ImgIcon := ItemsInfo[i].ImgIcon; ItemsArray[i].Extension := ItemsInfo[i].Extension; ItemsArray[i].Path := ItemsInfo[i].Path; ItemsArray[i].Width := ItemsInfo[i].Width; ItemsArray[i].Height := ItemsInfo[i].Height; Inc(i); end; SortArray(ItemsArray); EDIT: Das hier
Delphi-Quellcode:
if Compare(ItemsInfo[Index - 1], ItemsInfo[Index]) > 0 then
Nicht jeder Eintrag hat ein Icon und wenn kein Icon existiert ist der IdentStr leer. muss zu
Delphi-Quellcode:
Compare(ItemsInfo[Index - 1], ItemsInfo[Index]);
geändert werden damit alles mitgenommen wird nicht nur die Strings. Hmm.. geht nur wenn ich numeric sortiere nicht mit string. ![]() Danke. |
AW: array of record sortieren
Das ist der Code aus deinem ersten Post. Habe ich mal umgemodelt. Einfach getippt. Nicht getestet.
Delphi-Quellcode:
procedure TSkinListView.SortItems(hListView: hWnd; ColumnIndex: Integer);
var i, j : Integer; lItemsInfoArray : array of TItemsInfo; StringList: TStringList; ItemCount: Integer; buf: array [0 .. 255] of Char; ItemText: PWideChar; begin ListView_SortItems(hListView, @CompareFunc, ColumnIndex); // Liste wird sortiert StringList := TStringList.Create; try ItemCount := ListView_GetItemCount(hListView); for i := 0 to ItemCount - 1 do begin ZeroMemory(@buf, sizeof(buf)); ListView_GetItemText(hListView, i, 1, buf, sizeof(buf)); ItemText := buf; StringList.Add(ItemText); // Stringliste anhand der Sortierung erstellen. end; //*************************************************************************************** // Das hier habe ich mal zugefügt ... SetLength(lItemsInfoArray,length(ItemsInfo)); for i := High(ItemsInfo) downto Low(ItemsInfo) do begin j := StringList.IndexOf(ItemsInfo[i].IdentStr); if j>=0 then begin lItemsInfoArray[j] := ItemsInfo[i]; StringList[j] := 'Irgend ein Text, damit das Item nicht mehr gefunden wird. Ist ja schon zugewiesen'; end else begin // Hier ne Fehlerbehandlung rein end; end; // in lItemsInfoArray haben wir jetzt die korrekte Reihenfolge. Nun wieder zurück kopieren. for i := High(lItemsInfoArray) downto Low(lItemsInfoArray) do ItemsInfo[i] := lItemsInfoArray[i]; // und zwar bis hier hin zugefügt //*************************************************************************************** finally StringList.Free; end; end; |
AW: array of record sortieren
Danke dir für deine mühe.. werde es testen und mich dann nochmal melden ob es erfolgreich war.
|
AW: array of record sortieren
many thanks ;)
Hätte ich so nicht hinbekommen du hast mir den Tag gerettet. Danke nochmals. Funktioniert 1a nummeric und mit strings |
AW: array of record sortieren
100% geht es immer noch nicht.
Habe da immer noch einen Denkfehler.
Delphi-Quellcode:
Die liste wird anhand des ColumnIndex sortiert also abhängig davon welche column geklickt wurde.
procedure TSkinListView.SortItems(hListView: hWnd; ColumnIndex: Integer);
begin ListView_SortItems(hListView, @CompareFunc, ColumnIndex); //.. for i := 0 to ItemCount - 1 do begin ZeroMemory(@buf, sizeof(buf)); ListView_GetItemText(hListView, i, 1, buf, sizeof(buf)); ItemText := buf; StringList.Add(ItemText); // Stringliste anhand der Sortierung erstellen. end; end;
Delphi-Quellcode:
ListView_GetItemText(hListView, i, 1, buf, sizeof(buf));
Ist aber Hart gecodet füge ich jetzt dort den ColumnIndex anstell von "1" ein dann funktioniert es nur wenn ich auch tatsächlich die 1 klicke wo der IdentStr mit übergeben worden ist. Meine CompareFunc Funktion macht es richtig die sortiert nach Integer oder string. Aber ich weis nicht wie ich da die Icons noch mit einbinden kann. Mein Problem ist also wie übergeben ich die Icons damit diese immer mitwandern unabhängig davon welcher ColumnHeader geklickt wurde. Hmmm... mal wieder besonders schwierig. :lol: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:33 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 by Thomas Breitkreuz