Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi Firemonkey:将字体从资源添加到内存并使用它_Delphi_Fonts_Firemonkey_Delphi Xe5 - Fatal编程技术网

Delphi Firemonkey:将字体从资源添加到内存并使用它

Delphi Firemonkey:将字体从资源添加到内存并使用它,delphi,fonts,firemonkey,delphi-xe5,Delphi,Fonts,Firemonkey,Delphi Xe5,在VCL中,我可以从资源中加载字体,而无需保存,就可以从内存中使用它 这是我使用的代码,它在VCL中工作: procedure TForm1.Button1Click(Sender: TObject); var ResStream : tResourceStream; FontsCount : DWORD; begin ResStream := tResourceStream.Create(hInstance, 'MyResourceName', RT_RCDATA);

VCL
中,我可以从资源中加载字体,而无需保存,就可以从内存中使用它

这是我使用的代码,它在
VCL
中工作:

procedure TForm1.Button1Click(Sender: TObject);
var
   ResStream  : tResourceStream;
   FontsCount : DWORD;
begin
   ResStream  := tResourceStream.Create(hInstance, 'MyResourceName', RT_RCDATA);
   winapi.windows.AddFontMemResourceEx(ResStream.Memory, ResStream.Size, nil, @FontsCount);
   ResStream.Free();
   button1.Font.name := 'MySavedFontNameInResource';
end;
在Firemonkey中,我刚刚将
button1.Font.name
更改为
button1.Font.family
,但不幸的是字体没有更改。所以我认为这段代码与firemonkey不兼容

所以在Firemonkey中,如何从资源中加载字体,并将其临时保存到内存中,然后直接从内存中使用它

更新: 我看到这些页面:


根据他的回答,FMX似乎没有解决这个问题的方法。但如果我们在运行应用程序之前安装字体,也许我们可以加载字体。我尝试了几乎所有的方法,但仍然无法加载字体。

在新的Delphi中还有StylesSettings.ssFamily:Boolean属性,必须设置为False才能使用自定义字体族。尺寸、样式和颜色也一样。

这可能有帮助,也可能没有帮助

免责声明

这需要额外的研究,我还没有找到时间,但我相信这是一个很好的起点

MSDN页面的链接:-

您需要使用WinAPI.D2D1单元(可能还需要FMX.TextLayout和FMX.Canvas.D2D)来访问DirectWrite API。您可以使用它访问DirectWrite工厂,它将允许您从磁盘定义和加载字体

一旦将字体加载到AFAIK中,整个应用程序以及所有firemonkey控件都应该可以使用它。firemonkey完全可能只在应用程序加载时枚举字体,所以这一切可能都是徒劳的


正如我所说的,这需要我尚未进行的研究,因此只有在您还自定义绘制控件(我将这样做)的情况下才可能有效,因此可能不适合。

我想我有一个答案,这是因为Embarcadero的支持人员Roy Nelson为我指明了正确的方向

我已经验证了Berlin 10.1(没有应用周年纪念补丁)可以在Windows 10上64位运行,但我不能保证它可以在所有编译器版本/Windows版本上运行,其他人提供的任何见解都会非常有趣

首先,我认为(目前)无法解决的问题始于尝试使用AddFontMemResourceEx,因为它会生成不可枚举的字体,而Firemonkey要将已安装的TrueType字体转换为图形化呈现的D2D字体(这就是它实际使用的字体),它必须首先能够找到它

用从资源中写入的临时字体文件替换AddFontMemResourceEx,可以解决这个问题,但这还不够。安装后,您需要强制TextLayout渲染引擎重建其字体列表,您可以从FMX.Canvas.D2D.pas单元调用两行

UnregisterCanvasClasses; //this tells it to forget everything it knows
RegisterCanvasClasses; //this tells it to learn it again based on the current state of this system, which now includes our dynamically loaded font.
我已经在GitHub上发布了一个测试项目,供任何想尝试的人使用


基本上,您创建了一个包含字体的资源文件——从0到任意数字——将FMXFontInstaller.pas中的{$R assimilate.res}行替换为您刚刚创建的那一行,将此文件添加到您的项目源代码中,理论上应该可以使用。

我认为您的函数在VCL和FMX情况下都会成功?当然,它可以编译,因为它在语法上是正确的。问题是,它是否在两种情况下都返回成功状态?请尽可能检查错误。@在
VCL
FMX
中,函数返回
true
。我不知道,但我认为
fontsunt:integer有问题
我将
integer
更改为
DWORD
,但什么也没发生()
pcFonts
参数不重要,它只接收从资源添加的字体数(返回时应为
=1
)。对不起,我没有主意了。但我想向未来的读者指出,加载字体资源的方法是可行的(请参阅),并且在某些FMX字体字符串处理中可能存在问题(可能不可枚举字体会造成一些影响)。我认为这不是原因,因为当我在
button1.font.name:=“MyFontName”中更改
MyFontName
对于现有字体(如Tahoma或Segoe UI),字体会发生更改。请尝试使用按钮字体大小;-)将TButton设置为默认TForm,将字体大小设置为55,然后转到StyledSettings并切换ssSize复选框-然后查看切换时TButton上的文本会发生什么情况!我知道你的意思。但我的问题不在于
样式设置
。我可以像我在第一条评论中说的那样更改字体。当我在设计时选择新的家族字体时,它就可以工作了。如果你想在运行时做同样的事情,我认为你应该使用样式。使用TStyleBook设计新的按钮样式,并在运行时进行更改:)哦,顺便说一下,我认为这是一种非常不雅观的方法,我建议Embarcadero将其自动用于您在项目的图像/资源中安装的任何字体。适用于Mac和Windows。如果你同意的话,你可以更新原始的bug报告。。我在Windows7 64位机器上测试了这个,但它不起作用。有人有什么想法吗?(除了“哦,废话。”)