小编Han*_*ans的帖子

在Delphi中实现MVVM绑定(View < - > ViewModel)的最佳方法?

对于使用本机组件的多平台应用程序,标准的Delphi方法已不再适用.到目前为止,我们的结构只有部分:GUI(表单)和业务逻辑.我们现在需要将"Forms"部分拆分为两个,这在MVVM上下文中将是ViewViewModel.

View和ViewModel之间的绑定可以通过不同方式处理:

可能会有更多.我知道这对某些人来说是一个宗教问题,但我仍然希望能得到客观答案:

如果您在Firemonkey应用程序中使用适合长期视角的多平台开发的解决方案:您做出的决定背后有哪些考虑因素?

delphi mvvm firemonkey delphi-xe7

9
推荐指数
0
解决办法
1714
查看次数

Typecasting Cardinal单身

两个CardinalSingle是4字节/ 32比特的数据类型,但是当我他们类型强制转换为彼此我得到一个Invalid Typecast错误的Delphi 10.1(柏林).

lSingleVar := Single(lCardinalVar);
Run Code Online (Sandbox Code Playgroud)

我不是在谈论在两种类型之间进行转换,因为它只存储23位基数数据(Single数据类型的小数部分).我需要将至少30位数据存储到Single变量中.我有充分的理由(类型无法更改),我将很乐意详述.

我如何对Single变量进行类型转换?

delphi delphi-10.1-berlin

9
推荐指数
3
解决办法
976
查看次数

从TButton继承的自定义按钮不显示

我正在将一个大型项目转换为Firemonkey,并且我们有一些自定义按钮,这些按钮不会显示在表单上.我已将问题分离到一个非常简单的项目:

使用下面的代码,在移动和桌面上(使用Delphi XE6中的默认新应用程序),创建tTestButton1工作正常,但tTestButton2不会在窗体上显示.怎么可能?

type
tTestButton1 = class(TButton);
tTestButton2 = class(tTestButton1);

tMainForm = class(TForm)
private
  fTestButton: TButton;
public
  constructor Create(aOwner: TComponent); override;
end;

constructor tMainForm .Create(aOwner: TComponent);
begin
  inherited;

//  fTestButton := tTestButton1.Create(Self); // this works fine (used instead of next line)
  fTestButton := tTestButton2.Create(Self);  //this button does not show up
  fTestButton.Text := 'Test';
  fTestButton.Parent := Self;
  fTestButton.Visible := True;
  fTestButton.Position.X := 20;
  fTestButton.Position.Y := 20;
end;
Run Code Online (Sandbox Code Playgroud)

delphi firemonkey delphi-xe6

8
推荐指数
1
解决办法
771
查看次数

在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
查看次数

Android Play 商店中的 Delphi 11 应用程序显示警告:非 SDK API

“Google Play 管理中心”中的“发布前报告概述”显示以下警告:

类型:

Non-SDK API
Run Code Online (Sandbox Code Playgroud)

应用程序编程接口:

Landroid/view/MotionEvent;-><init>()V
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪:

StrictMode policy violation: android.os.strictmode.NonSdkApiUsedViolation: Landroid/view/MotionEvent;-><init>()V
Run Code Online (Sandbox Code Playgroud)

此错误之前已在 Delphi 10.3 中修复,请参阅https://quality.embarcadero.com/browse/RSP-22046 ,但现在又回到了 Delphi 11 中?

我在 Google 上可以找到的解决方案是targetSdkVersion在中设置较新的AndroidManifest.xml 解决方案。但是,我们已经将其设置为 API 级别 30,因为需要部署到新的 Play 商店。在 AndroidManifest.xml 中我们有:

<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="30" />
Run Code Online (Sandbox Code Playgroud)

最近有人在 Play 商店上的“Delphi 11”应用程序中看到过此错误吗?- 最终找到了解决方案吗?

delphi android firemonkey google-play delphi-11-alexandria

5
推荐指数
1
解决办法
685
查看次数

将空分隔的PWideChar转换为字符串列表

从Windows API调用(GetUserPreferredUILanguages()),我得到一个字符串列表作为一个空分隔PWideChar.我需要将其转换为Delphi字符串列表.我开始编写代码来手动遍历列表,寻找#0字符.

有更聪明的方法吗?

PWideChar返回的示例GetUserPreferredUILanguages:

('e','n','-','U','S',#0,'f','r','-','F','R',#0,#0,...)
Run Code Online (Sandbox Code Playgroud)

(根据我在文档中读到的内容,因为当我在计算机上调用该函数时,它只返回一种语言,即'en-US'#0#0)

到目前为止,这是我的代码:

procedure GetWinLanguages(aList: TStringList);
var lCount, lSize: ULong;
    lChars: array of WideChar;
    lIndex, lLastIndex: integer;
begin
  lSize := 1000;
  SetLength(lChars, lSize);
  GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, @lCount, @lChars[0], @lSize);

  // untested quick solution to convert from lChars to aList
  lIndex := 0;
  lLastIndex := -1;
  while (lIndex<=lSize) do
  begin
    while (lIndex<lSize) and (lChars[lIndex]<>#0) do
      inc(lIndex);
    if (lIndex-lLastIndex)>1 then
    begin
      // here: copy range lLastIndex to lIndex, convert …
Run Code Online (Sandbox Code Playgroud)

delphi delphi-10.1-berlin

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