标签: delphi-xe7

使用RTTI时,我们如何获取和设置更深层次的子属性?

概观

我很感激之前已经提出过几个类似的问题:

但是,我没有进一步了解如何将RTTI用于我的需求.

我也花了很多时间和精力来写这个问题所以我希望它不会被关闭:)

工作实例

我在下面有几个过程可以输出到TStrings列表中的组件的属性名称,值和类型.原始来源不是我的,我只是做了一些小改动,整理了代码并将它们放入一些整洁的可重用程序:


下面将输出属性名称,例如:

  • 颜色
  • DoubleBuffered
  • 启用
  • 高度
  • 宽度
procedure GetComponentPropertyNames(Component: TComponent; OutList: TStrings);
var
  I: Integer;
  Count, Size: Integer;
  PropList: PPropList;
  PropInfo: PPropInfo;
begin
  OutList.BeginUpdate;
  try
    OutList.Clear;

    Count := GetPropList(Component.ClassInfo, tkAny, nil);
    Size  := Count * SizeOf(Pointer);
    GetMem(PropList, Size);
    try
      Count := GetPropList(Component.ClassInfo, tkAny, PropList);
      for I := 0 to Count -1 do
      begin
        PropInfo := PropList^[I];
        if not (PropInfo^.PropType^.Kind = tkMethod) then
        begin
          OutList.Add(PropInfo^.Name);
        end;
      end;
    finally
      FreeMem(PropList);
    end;
  finally
    OutList.EndUpdate; …
Run Code Online (Sandbox Code Playgroud)

delphi rtti delphi-xe7

7
推荐指数
1
解决办法
1421
查看次数

JVCL安装Delphi XE7

我最近安装了Delphi XE7并且一直在添加我的第三方组件集.我的开发机器上也有Delphi 7,XE4和XE6.运行JVCL 3.48安装时,我可以选择安装或更新7,XE 4和XE 6但不是XE 7.我需要做什么才能拿到这个版本?

非常感激

delphi jvcl delphi-xe7

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

Excel 2010 自动化常量在 Delphi XE7 中不起作用

我正在尝试将程序从 Delphi 2010 转换为 Delphi XE7(32 位/windows VCL)。曾经在 D2010 中通过后期绑定 OLE 自动化 Excel 的代码现在在 Delphi XE7 中给出异常“无法设置应用程序类的窗口状态属性”,当应用程序最大化或最小化时。

我从具有这些常量的 ExcelXP 单元中获取常量 xlmaximized 和 xlminimized: xlMaximized = $FFFFEFD7; xlMinimized = $FFFFEFD4;

但是,如果我使用简单的常量值 -4137 和 -4140,程序确实可以正常工作。我意识到我必须做一些简单的事情是错误的。

下面是一些说明问题的示例代码。我对此进行了测试,它在 Delphi 2010 中有效,但在 Delphi XE7 中无效。我想这一定与新版本中如何处理常量有关(?)有人能指出我正确的方向吗?提前致谢!

//XLA is a global variable of type OLEVariant;
//Program uses ComObj and ExcelXP unit

//This proc just runs or connects to Excel

procedure TForm3.RunExcelClick(Sender: TObject);

begin
  try
    xla := GetActiveOLEObject('Excel.Application');
  except
    try
      xla := CreateOleObject('Excel.Application');
    except
      on E: Exception do …
Run Code Online (Sandbox Code Playgroud)

delphi excel ole delphi-2010 delphi-xe7

6
推荐指数
1
解决办法
1419
查看次数

如何在Delphi XE7中设置"版本信息"?[德尔福设计问题]

我刚刚将我的一个项目从Delphi XE升级到XE7."所有平台/所有配置"全局目标的版本信息(我应该称之为"base"?)是从旧项目中正确复制的.

公司名称:xxx
文件版本:3.2.1

但是,当我检查子目标(32位/释放,32位/调试等)时,它们都被设置为''.因此,他们不会复制/继承"所有平台/所有配置"中的信息.

公司名称:''
文件版本:1.0.0

如何强制子目标继承"所有平台/所有配置".


更新:这似乎是Delphi XE7的设计问题.只要您不编辑它们,子目标就会保持同步.该窗口中缺少"主目标的同步子目标"按钮.还有一个与此相关的BUG关闭(有关详细信息,请参阅我的回答).

delphi delphi-xe7

6
推荐指数
1
解决办法
1453
查看次数

如何在Delphi DataSnap REST服务器上映射自定义HTTP方法前缀

使用Delphi的DataSnap创建的RESTful服务基于HTTP方法类型为DataSnap服务器中公开的REST方法提供了前缀的默认映射.这些如下:

HTTP Method type   Prefix       Example
GET                none         MyValue
POST               Update       UpdateMyValue
PUT                Accept       AcceptMyValue
DELETE             Cancel       CancelMyValue
Run Code Online (Sandbox Code Playgroud)

文档声明"可以覆盖映射模式.用户可以根据类名和方法名参数覆盖每种类型的映射." 但是,我完全没有找到有关如何执行此操作的任何文档.我想将PUT的前缀从Accept更改为其他内容.我怎么做?

我应该注意到,StackOverflow上的另一个帖子(REST Datasnap覆盖URI映射)试图通过指出TDSHTTPService具有执行此映射的方法来回答这个问题.同一篇文章还引用了MarcoCantù的DataSnap白皮书,该白皮书据说也描述了如何做到这一点.该白皮书说:"您可以通过处理DSHTTPWebDispatcher组件的四个相应事件处理程序来自定义这些映射."

在RAD Studio XE中,TDSHTTPService和TDSHTTPWebDispather组件都有四个特定事件,对应于上面列出的四种HTTP方法,并且用于映射前缀.XE2及更高版本中不存在这些方法.

delphi rest datasnap delphi-xe delphi-xe7

6
推荐指数
1
解决办法
1450
查看次数

在iOS上使用TDateTime进行舍入错误

从时间戳(TDateTime)计算32位ID时,我得到一个奇怪的错误.在某些情况下,不同处理器的值不同.

fTimeStamp字段是从DoubleSQLite数据库中的字段中读取的.下面的代码计算一个32位ID(lIntStamp)fTimeStamp,但在某些(罕见)情况下,即使源数据库文件完全相同(即文件中存储的Double相同),不同计算机上的值也不同.

...
fTimeStamp: TDateTime
...

var
  lIntStamp: Int64;
begin
  lIntStamp := Round(fTimeStamp * 864000); //86400=24*60*60*10=steps of 1/10th second
  lIntStamp := lIntStamp and $FFFFFFFF;
  ...
end;
Run Code Online (Sandbox Code Playgroud)

TDateTime(Double)的精度是15位数,但代码中的舍入值仅使用11位数,因此应该有足够的信息正确舍入.

提一个值的例子:在特定的测试运行中,lIntStampWindows计算机上的值为74AE6699B,iPad上的值为74AE699A(=最后一位不同).

Round每个平台上的功能实现不同吗?

PS.我们的目标平台目前是Windows,MacOS和iOS.

编辑:

我根据评论做了一个小测试程序:

var d: Double;
    id: int64 absolute d;
    lDouble: Double;
begin
  id := $40E4863E234B78FC;
  lDouble := d*864000;
  Label1.text := inttostr(Round(d*864000))+' '+floattostr(lDouble)+' '+inttostr(Round(lDouble));
end;
Run Code Online (Sandbox Code Playgroud)

Windows上的输出是:

36317325723 36317325722.5 36317325722
Run Code Online (Sandbox Code Playgroud)

在iPad上输出是:

36317325722 36317325722.5 36317325722
Run Code Online (Sandbox Code Playgroud)

区别在于第一个数字,它显示了中间计算的舍入,因此问题发生是因为x86具有比ARM(64位)更高的内部精度(80位).

delphi sqlite firemonkey delphi-xe7

6
推荐指数
1
解决办法
168
查看次数

为什么 Delphi XE7 会更改每个 FMX 表单保存的 PNG 图像?

我有一个包含许多自定义 firemonkey 组件的表单,其中每个组件都包含多个位图(从 PNG 图像文件加载)。每次保存表单时,FMX 文件中 PNG 图像的二进制数据都会发生变化!

这弄乱了我的版本控制日志 (SVN),因为仅更改表单中的一个属性会导致数千行更改。

有什么办法可以避免这种情况吗?

在此处查看 SVN 差异的屏幕截图:

SVN差异在这里

表单保存时,DotInlay.PNG图像没有被我更改,甚至包含图像的控件也没有任何更改。

编辑: 根据评论,这是 Delphi 中的一个错误,所以我创建了一个新的 QP 报告:https : //quality.embarcadero.com/browse/RSP-11259

如果您认为应该解决它,请为它投票。

delphi png firemonkey delphi-xe7

6
推荐指数
1
解决办法
999
查看次数

如何在MainForm之前创建表单?

我想创建一个启动屏幕(在主窗体之前)将显示x秒但我不想延迟使用x秒创建主窗体.

所以,我创建了启动画面窗体,创建主窗体然后在x秒后关闭启动窗体.
据我所知,使用CreateForm创建的第一个表单是主表单.这是正确的吗?

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := FALSE;
  Application.Title := AppName;
  frmSplash:= TfrmSplash.Create(NIL);         <----- not main form??
  Application.CreateForm(TfrmMain, frmMain);  <----- main form??
  frmMain.LateInitialization;
  frmMain.show;
  Application.Run;
end.
Run Code Online (Sandbox Code Playgroud)

关闭启动窗体
启动画面有一个TTimer.计时器在启动窗体中执行一些动画,在x秒后它关闭窗体:

procedure TfrmSplash.CloseSplashForm;
begin
 Timer.Enabled:= FALSE;
 Close;        <-- I do see the program reaching this point
end;
Run Code Online (Sandbox Code Playgroud)

但是,应用程序在关闭时泄漏mem:

5 - 12 bytes: TMoveArrayManager<System.Classes.TComponent> x 4, Unknown x 2
13 - 20 bytes: TObservers x 1, TList x 3, Unknown x 3
21 - 36 bytes: TComponent.GetObservers$942$ActRec x 1, TPen x 2, …
Run Code Online (Sandbox Code Playgroud)

delphi splash-screen delphi-xe7

6
推荐指数
2
解决办法
415
查看次数

在Delphi中更改单元的初始化顺序

我正在使用Delphi XE7开发Windows 32位应用程序.

我的应用程序包含许多单元,它有一个初始化部分.我需要首先初始化一个特定的初始化部分.

是否可以设置优先级?我曾尝试在dpr文件中编写初始化部分,但编译器拒绝了这一点.

请帮我初步执行特定的初始化部分.提前致谢.

delphi delphi-xe7

6
推荐指数
2
解决办法
421
查看次数

允许用户从密码字段复制文本

在我的应用程序中有一个TEditwith PasswordChar = '*'.

当用户按下时会Ctrl + C出现提示。

密码模式下的 Windows 编辑控件的屏幕截图,显示其“无法复制”气球。

翻译:

不允许

您不能从密码字段复制文本。

显然,下拉菜单中的复制项被禁用

密码模式下的 Windows 编辑控件的屏幕截图,其上下文菜单可见; 复制项目被禁用。

有没有办法为密码编辑器启用复制操作?

delphi delphi-xe7

6
推荐指数
2
解决办法
1059
查看次数