本篇文章给大家谈谈delphi–如何在TList中存储动态数组?,以及delphitlist用法的知识点,同时本文还将给你拓展Delphi4的动态数组、DelphiTListView(TListBox
本篇文章给大家谈谈delphi – 如何在TList中存储动态数组?,以及delphi tlist用法的知识点,同时本文还将给你拓展Delphi 4 的动态数组、Delphi TListView(TListBox+图标显示)、Delphi XE8在TList中的错误,需要解决方法、delphi – 在TListView中就地编辑子项等相关知识,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:- delphi – 如何在TList中存储动态数组?(delphi tlist用法)
- Delphi 4 的动态数组
- Delphi TListView(TListBox+图标显示)
- Delphi XE8在TList中的错误,需要解决方法
- delphi – 在TListView中就地编辑子项
delphi – 如何在TList中存储动态数组?(delphi tlist用法)
这是我的’小组’:
TGroup= array of Integer; <------ dynamic array (as you can see) :)
我想用TList来保持我的团队.我的想法是,我可能希望稍后访问这些组并向其添加更多项目.
我有这个代码,但我不能让它工作:
TYPE TGroup= array of Integer; // Each group has x items (x can be from 1 to 10000) procedure TForm1.FormCreate(Sender: TObject); VAR CurGroup: TGroup; grp,item: Integer; Groups: TList; // can contain up to 1 million groups begin Groups:= TList.Create; { Init } for grp:= 1 to 4 DO // Put a dummy item in TList begin SetLength(CurGroup,1); // Create new group Groups.Add(@CurGroup); // Store it end; CurGroup:= NIL; // Prepare for next use for grp:= 1 to 4 DO // We create 4 groups. Each group has 3 items begin CurGroup:= Groups[Groups.Count-1]; // We retrieve the current group from list in order to add more items to it { We add few items } for item:= 0 to 2 DO begin SetLength(CurGroup,Length(CurGroup)+1); // reserve space for each new item added CurGroup[item]:= Item; end; Groups[Groups.Count-1]:= @CurGroup; // We put the group back into the list end; { Verify } CurGroup:= NIL; CurGroup:= Groups[0]; Assert(Length(CurGroup)> 0); // FAIL if (CurGroup[0]= 0) AND (CurGroup[1]= 1) AND (CurGroup[2]= 2) then Application.ProcessMessages; FreeAndNil(Groups); end;
注意:代码已完成.您可以将其粘贴到Delphi(7)中进行试用.
解决方法
这只是初稿,但它的灵感来自你的问题,以及TList方法缺失的事实.
type TGroup: array of integer; var Group: TGroup; GroupA: TDynArray; i,v: integer; begin GroupA.Init(TypeInfo(TGroup),Group); // associate GroupA with Group for i := 0 to 1000 do begin v := i+1000; // need argument passed as a const variable GroupA.Add(v); end; v := 1500; if GroupA.IndexOf(v)<0 then // search by content ShowMessage('Error: 1500 not found!'); for i := GroupA.Count-1 downto 0 do if i and 3=0 then GroupA.Delete(i); // delete integer at index i end;
这个TDynArray包装器也可以用于字符串数组或记录数组…记录只需要打包并且只有引用计数字段(byte,integer,double …)或字符串引用计数字段(没有变量也没有接口内).
IndexOf()方法将按内容进行搜索.那是例如对于记录数组,所有记录字段(包括字符串)必须匹配.
请参阅源代码存储库中的the SynCommons.pas unit中的TDynArray.适用于Delphi 6到XE,并处理Unicode字符串.
TTestLowLevelCommon._TDynArray方法是与此包装器关联的自动单一测试.您将在此处找到记录数组和更高级功能的示例.
我目前正在实现SavetoStream和LoadToStream方法……
也许是在所有Delphi版本中使用类通用特性的新方法.
编辑:
我在TDynArray记录/对象中添加了一些新方法:
>现在,您可以将动态数组内容保存到字符串或从字符串加载(使用LoadFromStream / SavetoStream或LoadFrom / Saveto方法) – 它将使用专有但非常快速的二进制流布局;
>并且您可以通过两种方式对动态数组内容进行排序:就地(即交换数组元素内容)或通过外部整数索引查找数组(使用CreateOrderedindex方法 – 在这种情况下,您可以有几个订单到同一数据);
>您可以指定任何自定义比较函数,并且有一个新的Find方法可以使用快速二进制搜索(如果可用).
以下是这些新方法的工作原理:
var Test: RawByteString; ... Test := GroupA.Saveto; GroupA.Clear; GroupA.LoadFrom(Test); GroupA.Compare := SortDynArrayInteger; GroupA.sort; for i := 1 to GroupA.Count-1 do if Group[i]<Group[i-1] then ShowMessage('Error: unsorted!'); v := 1500; if GroupA.Find(v)<0 then // fast binary search ShowMessage('Error: 1500 not found!');
更接近通用范例,更快,对于Delphi 6到XE …
Delphi 4 的动态数组
总结
以上是小编为你收集整理的Delphi 4 的动态数组全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
Delphi TListView(TListBox+图标显示)
unit Unit1; interface uses Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,System.ImageList,Vcl.ImgList,Vcl.StdCtrls,Vcl.ComCtrls; type TForm1 = class(TForm) lv1: TListView; 添加: TButton; il1: timageList; btn删除选中: TButton; 清空: TButton; btnDelete_select: TButton; procedure 添加Click(Sender: TObject); procedure btn删除选中Click(Sender: TObject); procedure btnDelete_selectClick(Sender: TObject); procedure 清空Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.添加Click(Sender: TObject); begin if lv1.Columns.Count = 0 then lv1.Columns.Add.Caption := ‘111‘; lv1.Column[0].width := 200; with lv1.Items.Add do begin StateIndex := 2; Caption := ‘Item‘ + IntToStr(lv1.Items.Count); end; end; procedure TForm1.清空Click(Sender: TObject); begin lv1.Clear; end; procedure TForm1.btnDelete_selectClick(Sender: TObject); begin lv1.Items[1].Delete; end; procedure TForm1.btn删除选中Click(Sender: TObject); begin lv1.Selected.Delete; end; end.
Delphi XE8在TList中的错误,需要解决方法
program XE8Bug1; {$APPTYPE CONSOLE} uses System.SysUtils,Generics.Collections; type TRecord = record A: Integer; B: Int64; end; var FRecord: TRecord; FList: TList<TRecord>; begin FList := TList<TRecord>.Create; FRecord.A := 1; FList.Insert(0,FRecord); FRecord.A := 3; FList.Insert(1,FRecord); FRecord.A := 2; FList.Insert(1,FRecord); Writeln(IntToStr(FList[0].A) + IntToStr(FList[1].A) + IntToStr(FList[2].A)); end.
此代码在XE7和之前(应该是)打印“123”,但在XE8中打印“120”。
也许有人知道一个quickfix这个?
更新:非官方修订是here
解决方法
procedure TListHelper.InternalInsertN(AIndex: Integer; const Value); var ElemSize: Integer; begin CheckInsertRange(AIndex); InternalGrowCheck(FCount + 1); ElemSize := ElSize; if AIndex <> FCount then Move(PByte(FItems^)[AIndex * ElemSize],PByte(FItems^)[(AIndex * ElemSize) + 1],(FCount - AIndex) * ElemSize); Move(Value,PByte(FItems^)[AIndex * ElemSize],ElemSize); Inc(FCount); FNotify(Value,cnAdded); end;
我看到第一个Move调用中的问题。目标应为:
PByte(FItems^)[(AIndex + 1) * ElemSize]
不
PByte(FItems^)[(AIndex * ElemSize) + 1]
Aaargh!
最后,我在我的项目中使用了来自Delphi XE7的System.Generics.Defaults.pas和System.Generics.Collections.pas单元,现在所有的工作都如预期的那样。
更新:如我所见,RTL不受影响,因为它不使用TList&T。为SizeOf&T插入T。 8(或者我可能错过了什么?)
delphi – 在TListView中就地编辑子项
解决方法
试试这个样本
Const USER_EDITLISTVIEW = WM_USER + 666; type TForm1 = class(TForm) ListView1: TListView; procedure FormCreate(Sender: TObject); procedure ListView1Click(Sender: TObject); private ListViewEditor: TEdit; LItem: TListitem; procedure UserEditListView( Var Message: TMessage ); message USER_EDITLISTVIEW; procedure ListViewEditorExit(Sender: TObject); public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} uses CommCtrl; const EDIT_COLUMN = 2; //Index of the column to Edit procedure TForm1.FormCreate(Sender: TObject); Var I : Integer; Item : TListItem; begin for I := 0 to 9 do begin Item:=ListView1.Items.Add; Item.Caption:=Format('%d.%d',[i,1]); Item.SubItems.Add(Format('%d.%d',2])); Item.SubItems.Add(Format('%d.%d',3])); end; //create the TEdit and assign the OnExit event ListViewEditor:=TEdit.Create(Self); ListViewEditor.Parent:=ListView1; ListViewEditor.OnExit:=ListViewEditorExit; ListViewEditor.Visible:=False; end; procedure TForm1.ListView1Click(Sender: TObject); var LPoint: TPoint; LVHitTestInfo: TLVHitTestInfo; begin LPoint:= listview1.ScreenToClient(Mouse.CursorPos); ZeroMemory( @LVHitTestInfo,SizeOf(LVHitTestInfo)); LVHitTestInfo.pt := LPoint; //Check if the click was made in the column to edit If (ListView1.perform( LVM_SUBITEMHITTEST,LParaM(@LVHitTestInfo))<>-1) and ( LVHitTestInfo.iSubItem = EDIT_COLUMN ) Then PostMessage( self.Handle,USER_EDITLISTVIEW,LVHitTestInfo.iItem,0 ) else ListViewEditor.Visible:=False; //hide the TEdit end; procedure TForm1.ListViewEditorExit(Sender: TObject); begin If Assigned(LItem) Then Begin //assign the vslue of the TEdit to the Subitem LItem.SubItems[ EDIT_COLUMN-1 ] := ListViewEditor.Text; LItem := nil; End; end; procedure TForm1.UserEditListView(var Message: TMessage); var LRect: TRect; begin LRect.Top := EDIT_COLUMN; LRect.Left:= LVIR_BOUNDS; listview1.Perform( LVM_GETSUBITEMRECT,Message.wparam,LParaM(@LRect) ); MapWindowPoints( listview1.Handle,ListViewEditor.Parent.Handle,LRect,2 ); //get the current Item to edit LItem := listview1.Items[ Message.wparam ]; //set the text of the Edit ListViewEditor.Text := LItem.Subitems[ EDIT_COLUMN-1]; //set the bounds of the TEdit ListViewEditor.BoundsRect := LRect; //Show the TEdit ListViewEditor.Visible:=True; end;
关于delphi – 如何在TList中存储动态数组?和delphi tlist用法的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于Delphi 4 的动态数组、Delphi TListView(TListBox+图标显示)、Delphi XE8在TList中的错误,需要解决方法、delphi – 在TListView中就地编辑子项等相关内容,可以在本站寻找。
本文标签: