我使用Delphi XE8和FireDAC来加载一个大的SQLite数据库.为此,我使用Array DML执行技术一次有效地插入大量记录,如下所示:
FDQueryAddINDI.SQL.Text := 'insert into indi values ('
+ ':indikey, :hasdata, :gedcomnames, :sex, :birthdate, :died, '
+ ':deathdate, :changed, :eventlinesneedprocessing, :eventlines, '
+ ':famc, :fams, :linkinfo, :todo, :nextreportindi, :firstancestralloop'
+ ')';
FDQueryAddINDI.Params.Bindmode := pbByNumber; {more efficient than by name }
FDQueryAddINDI.Params.ArraySize := MaxParams; { large enough to load all of them }
NumParams := 0;
repeat
{ the code to determin IndiKey,... is not shown, but goes here }
FDQueryAddINDI.Params[0].AsStrings[NumParams] := IndiKey;
FDQueryAddINDI.Params[1].AsIntegers[NumParams] := HasData;
FDQueryAddINDI.Params[2].AsStrings[NumParams] := GedcomNames; …
Run Code Online (Sandbox Code Playgroud) 我需要了解制作组件生成和管理子组件背后的基础知识.我最初尝试通过创建一个TCollection
,并试图在每个上添加一个名称TCollectionItem
.但我知道这并不像我希望的那么容易.
所以现在我将再次从头开始这个项目,这次我想说得对.这些子组件不是可视组件,不应该有任何显示或窗口,只是基于TComponent
.保存这些子组件的主要组件也将基于TComponent
.所以这里没有什么是视觉的,我不希望在我的表格(设计时间)上为每个子组件添加一个小图标.
我希望能够以类似集合的方式维护和管理这些子组件.重要的是应该创建,命名这些子组件并将其添加到表单源,就像菜单项一样.这是这个想法的重点,如果它们不能被命名,那么整个想法就是kaput.
哦,另一个重要的事情:作为所有子组件的父组件的主要组件需要能够将这些子组件保存到DFM文件中.
例:
而不是访问其中一个子项,如:
MyForm.MyItems[1].DoSomething();
Run Code Online (Sandbox Code Playgroud)
我宁愿喜欢这样做:
MyForm.MyItem2.DoSomething();
Run Code Online (Sandbox Code Playgroud)
所以我不必依赖于知道每个子项的ID.
编辑:
我觉得有必要包含我的原始代码,以便可以看到原始集合的工作原理.这是从整个单元中剥离的服务器端集合和集合项:
// Command Collections
// Goal: Allow entering pre-set commands with unique Name and ID
// Each command has its own event which is triggered when command is received
// TODO: Name each collection item as a named component in owner form
//Determines how commands are displayed in collection editor in design-time
TJDCmdDisplay = (cdName, cdID, cdCaption, cdIDName, cdIDCaption);
TJDScktSvrCmdEvent = …
Run Code Online (Sandbox Code Playgroud) delphi delphi-7 tcollection custom-component tcollectionitem
我正在尝试实现MoveItemUp和MoveItemDown方法,这些方法在一个索引中向上或向下移动选定的行TCollection
.
以下代码添加到我的TCollection子类中不起作用:
procedure TMyCollection.MoveRowDown(index: Integer);
var
item:TCollectionItem;
begin
if index>=Count-1 then exit;
item := Self.Items[index];
Self.Delete(index); // whoops this destroys the item above.
Self.Insert(index+1);
Self.SetItem(index+1,item); // this actually does an assign from a destroyed object.
end;
Run Code Online (Sandbox Code Playgroud)
我很确定这必须在运行时可行,因为它在设计时由Delphi IDE本身完成,它提供了一种重新排序列表中的Collection项的方法.我希望通过简单地重新排序现有对象来实现这一点,而无需创建,销毁或分配任何对象.这可能来自Classes.pas TCollection的子类吗?(如果没有,我可能必须从源克隆创建我自己的TCollection)
Delphi是否提供了在TCollection中迭代TCollectionItems的好方法?
也许,某些事情......
for mycollectionitem in mycollection.Items do
mycollectionitem.setWhatever();
Run Code Online (Sandbox Code Playgroud)
但这不会编译
或者我真的没有什么比这更优雅了:
for num := 1 to mycollection.Count do
mycollection.Items[num-1].setWhatever();
Run Code Online (Sandbox Code Playgroud) 注意:其他问题的标题不同,这使其无法识别为匹配的标题.
System.Classes
TCollection = class(TPersistent)
protected
procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); virtual;
end;
Run Code Online (Sandbox Code Playgroud)
MyUnit
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
Vcl.ExtCtrls, DB, System.Generics.Collections;
TTextDisplayLineInfos = class(TCollection)
protected
procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); override; //Here "[dcc32 Error] MyUnit.pas(85): E2037 Declaration of 'Notify' differs from previous declaration"
end;
implementation
procedure TTextDisplayLineInfos.Notify(Item: TCollectionItem;
Action: TCollectionNotification);
begin
inherited; //Here "[dcc32 Error] MyUnit.pas(475): E2008 Incompatible types"
//..............
end;
Run Code Online (Sandbox Code Playgroud)
Notify方法的签名是通过复制粘贴进行的,因此不会出现任何错误;
错误
在界面部分:
[dcc32错误] MyUnit.pas(85):E2037"通知"声明与之前的声明不同
在实施部分:
[dcc32错误] MyUnit.pas(475):E2008不兼容的类型
题 …
我试图从dll函数返回我自己的对象(从TCollection派生).我使用FastMemoryManager,但没有成功......所以我试图返回一些对象的动态数组.
当前在dll函数中的数组的长度.它工作得很好,但是没有释放分配的内存.
(我用Windows tarsk经理测量).是否有可能如何释放动态数组?调用dll函数的过程在线程中,最后我有以下内容:
for i := 0 to length(MyObjectArray) - 1 do begin
if MyObjectArray[i] <> nil then
MyObjectArray[i].Free;
end;
Setlength(MyObjectArray, 0);
MyObjectArray := nil;
Run Code Online (Sandbox Code Playgroud)
如果我使用而不是Setlength(MyObjectArray,0)和MyObjectArray:= nil,则
引发FreeAndNil(MyObjectArray) 异常.
有什么建议吗?
使用delphi 7,我有一组TCollection / TCollectionItem后代。它们只能在设计时设置,决不能在运行时修改。我怎样才能做到这一点?设计时应始终允许进行任何需要的编辑,但是在运行时中,我不希望能够添加,删除或重新索引集合中的任何项目。每个项目的属性,是的,我确实希望启用它们。但是更改实际项目只能在设计时进行。
这与我提出的另一个问题的接受答案有关.在将我已经存在的集合转换为这个新的"命名集合项"结构(如前一个问题中所解释)的过程中,我遇到了编译器错误......
[Error] JDSockets.pas(818): Incompatible types: 'tagWNDCLASSA' and 'Class reference'
这是来自Register
第一行的程序RegisterClass(TSvrCommandComp);
TSvrCommandComp
是我TChildComponent
在上一个答案的TJDServerSocket
版本,是我的版本TParentComponent
.
现在在上一个答案中,实际上定义了2个单元.我跳过了这个概念并将它们构建到同一个单元中.这个单位非常庞大.在这里,我有尽可能多的无关紧要的东西...
unit JDSockets;
interface
uses
Classes, Windows, SysUtils, StrUtils, ScktComp, ExtCtrls,
DesignEditors, DesignIntf;
type
TSvrCommands = class;
TSvrCommand = class;
TSvrCommandComp = class;
TSvrCommandParentComp = class;
// ---------- CODE REMOVED HERE ------------
////////////////////////////////////////////////////////////////////////////////
// Command Collections
// Goal: Allow entering pre-set commands with unique Name and ID
// Each command has its own event which …
Run Code Online (Sandbox Code Playgroud)