在Delphi XE中,我可以允许我的表单接受文件"拖放"但不必处理裸窗口消息吗?
TBytes变量的正确使用模式是什么?根据我的理解,TBytes不是一个类,而是一个"动态字节数组".我不确定在哪里释放内存,释放它时,哪个是从生产者传递给消费者的最佳方式.我希望我的生产者创建一个TBytes实例,然后将其传递给消费者.在这种情况发生之后,生产者想要重用其TBytes成员变量,知道消费者最终将内存返回给系统的内容.如果TBytes是一个对象,我不会有任何问题,但我不确定TBytes在这种情况下是如何工作的.
例如,在对象A中,我想将一些数据组装成一个TBytes数组,该数组是对象A的成员.完成后,我想将TBytes数组传递给另一个对象B,然后该对象成为该对象的所有者.数据.同时,回到对象A,我想开始组装更多数据,重用TBytes成员变量.
type
TClassA = class
private
FData: TBytes;
public
procedure AssembleInput(p: Pointer; n: Cardinal);
end;
TClassB = class
public
procedure ProcessData(d: TBytes);
end;
var
a: TClassA;
b: TClassB;
procedure TClassA.AssembleInput(p: Pointer; n: Cardinal);
begin
SetLength(FData, n);
Move(p^, FData, n); // Is this correct?
...
b.ProcessData(FData);
...
// Would it be legal to reuse FData now? Perhaps by copying new (different)
// data into it?
end;
procedure TClassB.ProcessData(d: TBytes);
begin
// B used the TBytes here. How does it free …Run Code Online (Sandbox Code Playgroud) 首先是问题:为什么删除const UnregisterNode()导致失败,而不是导致失败RegisterNode().
现在的背景:我正在使用Interfaces在Delphi XE中工作,我遇到了一个让我停顿一下的工件,我得出的结论是我真的不明白为什么.
不需要显式释放作为接口访问的对象.当最后一个引用超出范围时,它将被销毁.这似乎很简单.我编写了一个测试用例来显示按预期运行的变量和两个失败的变量.六个测试用例仅限于Register和Unregister方法的Node参数的变体.
按下表单上的单个按钮可创建容器和三个节点.对它们进行操作以演示该程序
该程序创建一些链接到简单容器的简单节点.问题发生在案例#1和#6中.在释放节点时,它会调用containers Unregister()方法.该方法删除指向TList中节点的指针的副本.当在两个失败的情况下离开该方法时,它以Destroy()递归方式再次启动该过程调用该节点的方法,直到发生堆栈溢出.
在有效的四种情况下,Destroy()方法恢复正常,程序将继续正常退出.
失败#1(案例1)
procedure RegisterNode(Node:INode);
procedure UnregisterNode(Node:INode);
Run Code Online (Sandbox Code Playgroud)
Unregister()从TNode.Destroy()方法调用节点似乎影响INode的引用计数导致多次调用Destroy(). 为什么这种情况发生我不明白.当我Register()具有相同样式的参数的节点时,它不会发生.
失败#2(案例6)
procedure RegisterNode(const Node:INode);
procedure UnregisterNode(Node:INode);
Run Code Online (Sandbox Code Playgroud)
这里发生了同样的失败模式.如案例5中那样将const添加到参数列表可防止递归调用Destroy().
代码:
unit fMain;
{
Case 1 - Fails when a node is freed, after unregistering,
TNode.Destroy is called again
Case 2 - Passes
case 3 - Passes
Case 4 - Passes
Case 5 - Passes
Case 6 - Fails the …Run Code Online (Sandbox Code Playgroud) 我该如何解析JSON字符串
{"data":{"results":[{"Branch":"ACCT590003"}]}}
Run Code Online (Sandbox Code Playgroud)
使用TJSONObject对象?我想ACCT590003从这个字符串中获取值.
我需要一个基类,TInterfacedObject但没有引用计数(所以一种TNonRefCountedInterfacedObject).
这实际上是第n次我需要这样一个课程,不知何故,我总是一次又一次地写作(阅读:复制和粘贴)我自己.我无法相信我没有可以使用的"官方"基类.
在RTL实现的某个地方是否存在基类,IInterface但没有引用计数,我可以从中派生我的类?
我需要访问一个严格的受保护属性,因为我需要创建一个验证(基于此属性的值)以避免错误.(我没有具有此属性的第三方类的源代码)只有我有类(接口)和dcu的定义(所以我无法更改属性可见性).问题是存在一种访问严格受保护财产的方法吗?(我真正读懂了Hallvard Vassbotn博客,但我不觉得这个特定主题参选.)
继这篇文章后,其接受的答案仍然非常神秘:
@Button1.OnClick := pPointer(Cardinal(pPointer( procedure (sender: tObject) begin ((sender as TButton).Owner as TForm).Caption := 'Freedom to anonymous methods!' end )^ ) + $0C)^;
Run Code Online (Sandbox Code Playgroud)
我想知道是否有可能设计出类似于以下的最简单和优雅的方式:
Button.OnClick :=
AnonProc2NotifyEvent (
procedure (Sender: TObject)
begin
((Sender as TButton).Owner as TForm).Caption := 'Freedom to anonymous methods!'
end
);
Run Code Online (Sandbox Code Playgroud)
以便达到相同的目的,并且AnonProc2NotifyEvent是具有以下签名的Button的所有者的方法:
TOwnerOfButton = class(TForm)
Button: TButton;
...
private
...
protected
function AnonProc2NotifyEvent(aProc: TProc<TObject>): TNotifyEvent;
public
...
end;
Run Code Online (Sandbox Code Playgroud)
这是可行的,如果可行,如何实施呢?
尝试刷新连接到SQL语句中具有联接表的数据集的ClientDataset上的记录时,TClientDataset.RefreshRecord不再生成SQL的表连接部分.
因此,调用此方法会导致SQL错误"无效列名称"为不在主表中的每个字段.
这在Delphi 2010及更早版本中不是问题.
连接到TClientDataset的DBX4或BDE组件都会发生错误,因此很可能是TClientDataset代码更改出现问题.
要复制此问题:
在Delphi XE中创建一个只有一个表单的新应用程序,并在其上删除所需的数据库组件(TSQLMonitor,TSQLConnection,TSQLQuery,TDatasetProvider,TClientDataset,TDatasource和TDBGrid)并将它们相互绑定.
使用表连接创建一个简单的SQL语句,并将其放在TSQLDataset.SQL属性中.
SQL语句只包含两个字段 - 主表的键字段和连接表中的字段 - 例如伪代码:
Select
MainTable.IntegerKeyField
, JoinedTable.JoinField
FROM MainTable
LEFT OUTER JOIN JoinedTable ON MainTable.LookupFieldID = JoinedTable.JoinKeyField
Run Code Online (Sandbox Code Playgroud)
将这两个字段添加为TSQLQuery和TClientDataset中的持久字段,其中包含pfInKey的关键字段的Provider Flag(如果不知道哪个字段是密钥,则RefreshRecord将不起作用,因此必须使用持久字段).
在表单上添加两个按钮 - 一个只打开Clientdataset,第二个按钮调用clientdataset.refreshrecord;
运行应用程序,按下按钮打开网格中的数据集和数据显示.
按"刷新记录"按钮,您将收到连接字段的SQL错误"无效列名称".
关闭应用程序,打开SQLMonitor日志并在Delphi生成的刷新记录SQL语句中,您将看到它没有包含表连接语句.
====
我真的很感激有关如何解决这个问题的任何想法.
FillRect不会TStringGrid在Delphi XE2中绘制完整的单元格.默认颜色左侧有3个像素的间隙(BiDiMode设置为bdLeftToRight).在我之前使用过的Delphi 6中不存在这个问题.
procedure TShapeline.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
Stringgrid1.Canvas.Brush.Color:=$00FF80FF;
StringGrid1.Canvas.FillRect(Rect);
end;
Run Code Online (Sandbox Code Playgroud)
我试图更改所有属性(包括DrawingStyle)和不同的画笔样式,绘制的矩形不会填充整个单元格.
作为测试,我决定使用Delphi 4,5,6,7,2005,2010和XE3在Delphi中创建一个简单的"Hello world"应用程序.该应用程序只不过是一个TForm,一个带有OnClick事件的TButton调用ShowMessage('Hello world').
以下是关闭调试的每个最终EXE的结果:

有人可以解释为什么XE3版本比之前版本的Delphi平均大26倍?
以下是我对XE3的项目设置:


delphi ×10
delphi-xe ×10
interface ×2
anonymous ×1
delphi-2010 ×1
delphi-7 ×1
delphi-xe2 ×1
delphi-xe3 ×1
json ×1
sql ×1
tstringgrid ×1