标签: delphi-10.2-tokyo

如何比较枚举类型的集合

从某一点来说,我厌倦了编写设置条件(and,or),因为对于更多条件或更长的变量名称,它开始变得笨拙并且令人讨厌再次写入.所以我开始写助手,所以我可以写ASet.ContainsOne([ceValue1, ceValue2])而不是(ceValue1 in ASet) or (ceValue2 in ASet).

type
  TCustomEnum = (ceValue1, ceValue2, ceValue3);
  TCustomSet = set of TCustomEnum;
  TCustomSetHelper = record helper for TCustomSet 
    function ContainsOne(ASet: TCustomSet): Boolean;
    function ContainsAll(ASet: TCustomSet): Boolean;
  end;

implementation

function TCustomSetHelper.ContainsOne(ASet: TCustomSet): Boolean;
var
  lValue : TCustomEnum;
begin
  for lValue in ASet do
  begin
    if lValue in Self then
      Exit(True);
  end;
  Result := False;
end;

function TCustomSetHelper.ContainsAll(ASet: TCustomSet): Boolean;
var
  lValue : TCustomEnum;
begin
  Result := …
Run Code Online (Sandbox Code Playgroud)

delphi delphi-10.2-tokyo

8
推荐指数
2
解决办法
249
查看次数

Delphi代码完成失败,使用匿名方法

请创建一个新的FMX应用程序,添加一个按钮和一个备忘录来运行此示例.我有这个代码:

procedure TForm1.Button1Click(Sender: TObject);
begin
  TTask.Run(procedure
            var
              client: TIdHTTP;
              result: string;
            begin
              client := TIdHTTP.Create(nil);
              try
                try
                  client.ReadTimeout := 4000;
                  client.ConnectTimeout := 4000;
                  result := client.Get('a valid url here just as test');
                  TThread.Synchronize(nil, procedure
                                           begin
                                             Memo1.Lines.Add(result);
                                           end);
                except
                  on E: Exception do
                    begin
                      TThread.Synchronize(nil, procedure
                                           begin
                                             Memo1.Lines.Add(E.Message);
                                           end);
                    end
                end;
              finally
                client.Free;
              end;
            end);
end;
Run Code Online (Sandbox Code Playgroud)

它按预期工作,但问题出在IDE中.如果我将光标放在匿名函数体内的某处,我会自动关闭finally语句.

我怎样才能解决这个问题?


首先我在这里

在此输入图像描述

然后我按回车,我有这个!

在此输入图像描述

如果将光标放在行的开头而不是行的末尾,则可以添加新的空格而不完成.如何解决这个问题呢?好吧,我发现问题发生是因为有这样的代码:

TThread.Synchronize(nil, procedure
                         begin
                           Memo1.Lines.Add(result);
                         end);
Run Code Online (Sandbox Code Playgroud)

如果删除此代码,问题就不会再发生了.这是IDE中的错误吗?

delphi delphi-10.2-tokyo

7
推荐指数
2
解决办法
357
查看次数

当我执行OnDblClick事件(Form1)打开Form2时,它会触发Form2的OnCellClick事件,而没有单击form2网格

活动表格1:

procedure TForm1.Panel1DblClick(Sender: TObject);
begin
  TForm2.Create(Self).ShowModal;
end;
Run Code Online (Sandbox Code Playgroud)

活动表格2:

procedure TForm2.DBGrid1CellClick(Column: TColumn);
begin
  ShowMessage('Test');
end;
Run Code Online (Sandbox Code Playgroud)

我该怎么做才能避免fom2的onCellClick事件?

delphi delphi-10.2-tokyo

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

为什么在优化构建下有两个顺序移动到EAX?

我查看了发布所有优化的发布版本的ASM代码,这是我遇到的内联函数之一:

0061F854 mov eax,[$00630bec]
0061F859 mov eax,[$00630e3c]
0061F85E mov edx,$00000001
0061F863 mov eax,[eax+edx*4]
0061F866 cmp byte ptr [eax],$01
0061F869 jnz $0061fa83
Run Code Online (Sandbox Code Playgroud)

代码很容易理解,它将偏移量(1)构建到表中,将其中的字节值与1进行比较,如果是NZ则进行跳转.我知道我的表的指针存储在$ 00630e3c,但我不知道$ 00630bec来自哪里.

为什么有两个人一个接一个地转向eax?是不是第一个被第二个覆盖了?这可能是缓存优化的事情还是我错过了令人难以置信的明显/模糊的东西?

上述ASM的Delphi代码如下:

if( TGameSignals.IsSet( EmitParticleSignal ) = True ) then [...]
Run Code Online (Sandbox Code Playgroud)

IsSet()是一个内联类函数,并调用TSignalManager的内联IsSet()函数:

class function TGameSignals.IsSet(Signal: PBucketSignal): Boolean;
begin
  Result := FSignalManagerInstance.IsSet( Signal );
end;
Run Code Online (Sandbox Code Playgroud)

信号管理器的最终IsSet如下:

function TSignalManagerInstance.IsSet( Signal: PBucketSignal ): Boolean;
begin
  Result := Signal.Pending;
end;
Run Code Online (Sandbox Code Playgroud)

delphi optimization assembly delphi-10.2-tokyo

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

Delphi检测到可恢复文件时的操作过程?

我的Delphi Tokyo 10.2.1 IDE刚刚崩溃.重启时我得到提示:

在此输入图像描述

RAD Studio已恢复以下文件.保存你想要保留的那些.

文件比较显示,此时文件__recovery确实是最新版本,但尚未恢复任何内容
(注意:特定文件未在IDE中重新打开,因为崩溃阻止IDE将其注册为打开file.此文件所属的项目甚至不是项目组中的当前项目,原因相同).

该对话框只有一个关闭按钮.我可以选择那个文件.我开始测试几种变化.

无论我是否选择它,单击关闭后,Delphi会要求丢弃剩余的恢复文件?.

  • 如果我然后选择否,则没有任何变化.文件未恢复,内容__recovery保持不变
  • 当我选择Yes时,我也想测试它,但是现在没有复制旧源文件加__recovery文件夹的数量会再次触发IDE警告.我无法测试进一步的变化.IDE现在不断清除__recovery文件夹.

这有点乱.恢复不起作用吗?对话文本是否不清楚?

我期望从这样的对话框中出现以下行为:

  • 它向我提供了检测到的文件.文字说:RAD Studio 发现 了以下文件. 选择 您要保留的那些.
  • 用户必须选择他想要恢复的文件.
  • 如果仍有任何未恢复的文件,则会出现丢弃剩余的恢复文件消息.

有谁知道(f)究竟发生了什么?我该怎么办(选择/回答)?
我在网上找不到答案.

因为现在我留下了一个未恢复的文件和一个空__recovery文件夹.幸运的是我做了备份.

ide delphi file-recovery delphi-10.2-tokyo

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

Delphi FMX - Android 中的虚拟键盘覆盖控制(无效的键盘高度)

我创建了一个简单的 FMX 表单(在 Delphi Tokyo 10.2.1 中),上面有 3 个控件:

  1. TLayout(LayoutKbd) - 与屏幕底部对齐。高度 1。
  2. TRectangle- 与底部对齐(在 TLayout 上方)。高度 5。
  3. TMemo - 与客户保持一致。

在表单的OnVirtualKeyboardShown事件中,我有以下代码:

procedure TForm1.FormVirtualKeyboardShown(Sender: TObject;
  KeyboardVisible: Boolean; const Bounds: TRect);
begin
  if KeyboardVisible then
  begin
    LayoutKbd.Height:=Bounds.Height;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

当我在我的 Android 手机上运行它并触摸备忘录内部时,会显示虚拟键盘并触发事件。然而,下面的值Bounds.Height是一个随机的、大的、负数(请参阅调试期间的局部变量)。

在此处输入图片说明

根据文档

事件处理程序的 Bounds 参数指定虚拟键盘窗口的屏幕坐标

我希望屏幕来显示我的键盘(重叠我的TLayout),它上面TRectangle和上面说我的TMemo。但是由于没有显示布局的高度,虚拟键盘覆盖了备忘录的一部分。

我可能遗漏了一些非常基本的东西。我的问题是:

  • 如何获得虚拟键盘的高度?
  • 我在尝试从边界获取高度时做错了什么吗?(我也试过从中获取高度Bounds.Size.Height- 这也不起作用)
  • 是否有不同/更好的方法来可靠地调整我的备忘录的大小,以便虚拟键盘不会遮挡它。

感谢在这方面的任何帮助或指导。

更新 20170906:鉴于我在 10.2.1 东京的总体体验不佳,我决定在 10.1.2 柏林尝试代码。有趣的是,该代码在柏林工作 - 但据报道键盘的高度比它应该的高度高出 25 像素。因此,通过使用LayoutKbd.Height:=Bounds.Height …

delphi keyboard android firemonkey delphi-10.2-tokyo

6
推荐指数
0
解决办法
3874
查看次数

匿名方法对TypeInfo的奇怪行为

对于需要泛型类型"family"的一段代码,我尝试使用它TypeInfo来检索所需的信息.

class function GetTypeKind<T>:TTypeKind;
Run Code Online (Sandbox Code Playgroud)

对于大多数类型,我可以解决这个问题.但匿名方法类型表现出意外.

我有一个匿名方法类型定义为:

TMethodProc = reference to procedure;
Run Code Online (Sandbox Code Playgroud)

我试着获取类型信息:

MyKind := GetTypeKind<TMethodProc>;

class function GetTypeKind<T>:TTypeKind;
var 
  TI: PTypeInfo;
begin
  TI := TypeInfo(T);

  ...
end;
Run Code Online (Sandbox Code Playgroud)

我知道匿名方法背后有一些编译魔术.但我得到以下结果:

TI.TypeData.IntfParent == IInterface
TI.TypeData.IntfFlags == [(out of bounds)6]
Run Code Online (Sandbox Code Playgroud)

标志有一个意外的值,TIntfFlag有三个值,所以6是意外的.GUID也不是指导.它有一个相同的8个字节的重复集,大多数是00.例如(0,225,48,180,0,0,0,0,0,225,48,180,0,0,0,0)

匿名方法是否被排除在TypeInfo某些调整之外或者是否有用.

另外,(奇怪的)6是一个无证的特征,还是可以是任何值?

delphi anonymous-methods typeinfo delphi-10.2-tokyo

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

自定义绘制TCustomListbox项目

我正在重写一个VCL组件,显示TCustomListbox在Delphi 10.2中定制的Firemonkey.自定义使用了重写DrawItem,基本上添加了一些缩进并根据项目文本和索引设置文本颜色.

DrawItem让它变得相当容易,但在FMX中似乎没有这样的东西.我可以PaintChildren自己覆盖和绘制每个项目,但是它看起来不同,我必须自己处理滚动和一切.我刚刚开始使用FMX并且还没有源代码.

  • DrawItemFMX中有替代品吗?我可能错过了它.

  • 如果没有,它如何获得所需信息?基本上,要绘制的矩形和理想的使用样式.

问题

Hans的解决方案有效,但有一些重大问题:

颜色

设置颜色不起作用,文本始终为黑色.我尝试了各种可能性,包括这个:

PROCEDURE TMyItem.Paint;
BEGIN
  TextSettings.FontColor := TAlphaColorRec.Red;
  INHERITED;
END;
Run Code Online (Sandbox Code Playgroud)

速度

打开一个包含180个项目的框可能需要两秒钟.我们需要很多项目和它们的数量实际上是我们需要一个自定义框的原因(我们使用TEdit我们组件的一部分提供过滤).使用字符串的版本TMyItem更快(虽然可能比VCL版本慢),但使用这些项目似乎会减慢速度(它比填充类似的HTML列表慢).

或者是其他东西?没有来源,几乎没有文件,我无法分辨.

我试图缓存项目以供重用,但这没有帮助.

看起来使用自定义项实际上比使用字符串更快(以毫秒为单位):

nItems String TMyItem
   200    672      12
  2000   5604     267
 20000  97322   18700
Run Code Online (Sandbox Code Playgroud)

当内容多次更改时,速度问题似乎会累积.我正在使用FListBox.Items.Clear;,然后我尝试了

n := FListBox.Items.Count;
FOR i := 0 TO n-1 DO FListBox.ListItems[n-1-i].Free;
Run Code Online (Sandbox Code Playgroud)

最后FListBox.Clear;,这是最有意义的(我最后发现).最后,每件物品似乎需要2毫秒.

delphi vcl firemonkey delphi-10.2-tokyo

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

如何为FireMonkey组件添加设计时图标?

我已经阅读了PawełGłowacki的这篇文章,我已经能够为我的组件显示一个图标.结果如下:

在此输入图像描述

我可以在工具选项板和结构视图中看到图像.顺便说一下,在设计器中我看到了默认图标:

在此输入图像描述

如何在设计器中显示组件的图标?


我正在使用Delphi Tokyo 10.2 Update 2.我已经按照我链接的文章来显示图像.我的组件如下:

type
  TEquationSolver = class(TComponent)
    //code...
  end;
Run Code Online (Sandbox Code Playgroud)

基本上,我做了以下事情:

  1. 我创建了3个位图(16x16 24x24 32x32)和一个png(128x128)
  2. 我已将它们作为资源添加到Project> Resources and Images中 在此输入图像描述
  3. TEquationSolver用后缀表示它们的大小.通过这种方式,它们可以正确显示在IDE上.

我在设计时间部分缺少什么?在文章中,我已经阅读以下内容:

我们的指南是:如果您想要非常简单的向后兼容性或小文件(BPL)大小,请使用PNG; 如果要快速加载,请使用位图.我们使用位图为16,24和32px图标,PNG用于128px图标.

实际上我有16x16,24x24,32x32位图和128px png.还有别的吗?

delphi firemonkey delphi-10.2-tokyo

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

Delphi/Indy 10 - 发送带有附件的文本或 HTML 电子邮件会为文本(正文)本身添加一个附件

对于多年来,我们一直在使用印10发送电子邮件(文本,而不是HTML)与连接到它的一个或多个PDF,我们从未有过任何问题。

最近(可能是因为东京发布 3 版?),我们的客户注意到电子邮件(正文)的文本部分现在是附件,而不是电子邮件本身的一部分。

我在互联网上搜索了解决方案,我测试的所有内容都没有解决这个问题。

我尝试了 Remy Lebeau 在 StackOverflow 上提出的一些解决方案,但没有成功。

身体是一个附件

这是代码(基于 StackOverflow 上的帖子)

procedure TForm1.btnSendEmailClick(Sender: TObject);

var
   smtp   : TIdSMTP;
   msg    : TidMessage;
   builder: TIdMessageBuilderHtml;

begin
   msg := TidMessage.Create(nil);

   try
      builder := TIdMessageBuilderHtml.Create();

      try
         // FIsBodyHtml IS FALSE
         if FIsBodyHtml then begin
            builder.Html.Text   := edText.Lines.Text;
            builder.HtmlCharSet := 'utf-8';
            builder.HtmlContentTransfer := 'quoted-printable';
         end else begin
            builder.PlainText.Text := edText.Lines.Text;;
            builder.PlainTextCharSet := 'utf-8';
            builder.PlainTextContentTransfer := 'quoted-printable';
         end;

         // Add attached file here
         if (edFile.Text <> '') and FileExists(edFile.Text) …
Run Code Online (Sandbox Code Playgroud)

delphi email attachment indy10 delphi-10.2-tokyo

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