标签: delphi-xe

如何在不处理Windows消息的情况下允许表单接受文件丢弃?

在Delphi XE中,我可以允许我的表单接受文件"拖放"但不必处理裸窗口消息吗?

delphi drag-and-drop delphi-xe

17
推荐指数
2
解决办法
7170
查看次数

Delphi XE TBytes正确用法

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)

delphi delphi-xe

17
推荐指数
2
解决办法
1万
查看次数

在Delphi中,为什么传递一个Interface变量有时需要它是一个const参数?

首先是问题:为什么删除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)

delphi interface delphi-xe

17
推荐指数
2
解决办法
4099
查看次数

如何在Delphi中解析JSON字符串?

我该如何解析JSON字符串

{"data":{"results":[{"Branch":"ACCT590003"}]}}
Run Code Online (Sandbox Code Playgroud)

使用TJSONObject对象?我想ACCT590003从这个字符串中获取值.

delphi json delphi-xe

16
推荐指数
5
解决办法
4万
查看次数

是否存在像TInterfacedObject这样的非引用计数基类?

我需要一个基类,TInterfacedObject但没有引用计数(所以一种TNonRefCountedInterfacedObject).

这实际上是第n次我需要这样一个课程,不知何故,我总是一次又一次地写作(阅读:复制和粘贴)我自己.我无法相信我没有可以使用的"官方"基类.

在RTL实现的某个地方是否存在基类,IInterface但没有引用计数,我可以从中派生我的类?

delphi interface reference-counting delphi-xe

16
推荐指数
1
解决办法
1864
查看次数

访问Delphi类的严格受保护属性?

我需要访问一个严格的受保护属性,因为我需要创建一个验证(基于此属性的值)以避免错误.(我没有具有此属性的第三方类的源代码)只有我有类(接口)和dcu的定义(所以我无法更改属性可见性).问题是存在一种访问严格受保护财产的方法吗?(我真正读懂了Hallvard Vassbotn博客,但我不觉得这个特定主题参选.)

delphi class-helpers delphi-xe

16
推荐指数
2
解决办法
4217
查看次数

TProc <TObject>到TNotifyEvent

继这篇文章后,其接受的答案仍然非常神秘:

@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)

这是可行的,如果可行,如何实施呢?

delphi anonymous delphi-xe

16
推荐指数
2
解决办法
6237
查看次数

ClientDataset.RefreshRecord在Delphi XE中不再适用于连接表 - 任何解决方法?

尝试刷新连接到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语句中,您将看到它没有包含表连接语句.

====

我真的很感激有关如何解决这个问题的任何想法.

sql delphi tclientdataset delphi-xe

15
推荐指数
1
解决办法
2151
查看次数

FillRect不会在Delphi XE2中绘制完整的TStringGrid单元格

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 tstringgrid delphi-xe delphi-xe2

15
推荐指数
2
解决办法
4927
查看次数

Delphi XE3 EXE文件大小比Dephi 7大25倍

作为测试,我决定使用Delphi 4,5,6,7,2005,2010和XE3在Delphi中创建一个简单的"Hello world"应用程序.该应用程序只不过是一个TForm,一个带有OnClick事件的TButton调用ShowMessage('Hello world').

以下是关闭调试的每个最终EXE的结果:

EXE的文件大小

有人可以解释为什么XE3版本比之前版本的Delphi平均大26倍?

以下是我对XE3的项目设置:

设置1

设置2

delphi delphi-7 delphi-2010 delphi-xe delphi-xe3

15
推荐指数
2
解决办法
9452
查看次数