RAD Studio/Delphi/C++Builder 13 FlorenceのSmart CodeInsight Claude Patchがリリースされています。Anthropic Claudeのモデルの変更に対応するとのことです。現時点(2025/12/25)でGetItからのみインストールできます
RAD Studio 13 Smart CodeInsight Claude パッチ のリリース (en)
2025年12月25日
2025年12月11日
Skia4Delphiでリソースとして埋め込まれたフォントを使用する
このアーティクルはDelphi Advent Calendar 2025の11日目の記事です。
ここまでリソースとして埋め込まれたフォントをVCL(GDI)で使用する方法を見てきました。ところで埋め込んだフォントをSkia4DelphiのTSkLabelやISkCanvasでも使用したいときは、少し違う方法が必要になります。
Skia4Delphiで描画に使用するフォントはTSkDefaultProviders.RegisterTypeface(かIFMXFontManagerService.AddCustomFontFromFile)で登録するのですが、このときのリソースタイプは(FONTではなく)RCDATAになっている必要があります。しかしフォント以外のリソースもリソースタイプRCDATAとして登録されるため、Win32APIのEnumResourceNames関数でプログラムに含まれるRT_RCDATAのリソースを列挙し、コールバック関数でリソースを読み出したら先頭4バイトでフォントデータかどうかを判別してからWin32APIのAddFontMemResourceEx関数とTSkDefaultProviders.RegisterTypefaceに渡すようにします。
まずプロジェクトにフォントをリソースとして追加します。Delphi IDEの"メインメニュー"→"プロジェクト"→"リソースと画像"で"<プロジェクト名>のリソース"ダイアログで、フォントをリソースとして追加します。このときリソースタイプを"RCDATA"に変更しておきます。
次にプログラムのなるべく早い時点でこのフォントを読み出して登録します。
これで登録したフォントはSkia4DelphiのFont.Familiesにそのフォント名を指定することで使用できます。TSkLabelならTSkLabel.TextSettings.Font.Families、ISkCanvasに対する描画ならTSkTypeface.MakeFromNameの第1パラメータです。
ん?リソースタイプFONTではなくRCDATAで埋め込んだフォントデータをAddFontMemResourceEx関数に渡せる?じゃあ前回のアーティクルのようにリソースコンパイラを差し替えたりせず、RCDATAでやればいいのでは?と思うかもしれません。その通りで、今回の方法(フォントをRCDATAで埋め込む)を使えば、Delphi 12.3およびそれ以前でもビルド前イベントでresinatorを使って処理する必要はありません。しかしプログラムにフォント以外のRCDATAのリソースが埋め込まれていた場合は、それらもすべて読み出してフォントデータかどうかの判別をする必要があります。このオーバヘッドを許容できるのであれば、今回の方法でも問題ありません。
ここまでリソースとして埋め込まれたフォントをVCL(GDI)で使用する方法を見てきました。ところで埋め込んだフォントをSkia4DelphiのTSkLabelやISkCanvasでも使用したいときは、少し違う方法が必要になります。
Skia4Delphiで描画に使用するフォントはTSkDefaultProviders.RegisterTypeface(かIFMXFontManagerService.AddCustomFontFromFile)で登録するのですが、このときのリソースタイプは(FONTではなく)RCDATAになっている必要があります。しかしフォント以外のリソースもリソースタイプRCDATAとして登録されるため、Win32APIのEnumResourceNames関数でプログラムに含まれるRT_RCDATAのリソースを列挙し、コールバック関数でリソースを読み出したら先頭4バイトでフォントデータかどうかを判別してからWin32APIのAddFontMemResourceEx関数とTSkDefaultProviders.RegisterTypefaceに渡すようにします。
まずプロジェクトにフォントをリソースとして追加します。Delphi IDEの"メインメニュー"→"プロジェクト"→"リソースと画像"で"<プロジェクト名>のリソース"ダイアログで、フォントをリソースとして追加します。このときリソースタイプを"RCDATA"に変更しておきます。
次にプログラムのなるべく早い時点でこのフォントを読み出して登録します。
unit LoadResFontsForSkia;
{$IFNDEF SKIA}
{$MESSAGE ERROR 'Enable Skia4Delphi.'}
{$ENDIF}
interface
uses
Winapi.Windows,
System.SysUtils, System.Classes,
Vcl.Skia;
implementation
type
TFontType = (ftNotFont, ftGDIFont, ftWebFont);
function CheckFontData(Stream: TStream): TFontType;
var
Signature: DWORD;
begin
Result := TFontType.ftNotFont;
Stream.Position := 0;
try
if Stream.Read(Signature,SizeOf(Signature)) <> SizeOf(Signature) then
begin
Exit;
end;
case Signature of
$00000100, // TrueType
$4F45454F, // 'OTTO' OpenType
$66637474: // 'ttcf' TrueType Collection
begin
Result := TFontType.ftGDIFont;
end;
$46464F77, // 'wOFF' Web Open Font
$32464F77: // 'wOF2' Web Open Font 2
begin
Result := TFontType.ftWebFont;
end;
end;
finally
Stream.Position := 0;
end;
end;
function EnumResNameProc(hModule: HMODULE; lpszType: PChar; lpszName: PChar; lParam: LONG_PTR): BOOL; stdcall;
var
RS: TResourceStream;
NumFonts: DWORD;
FontType: TFontType;
begin
{ Load resource }
if Is_IntResource(lpszName) = False then
begin
{ By name }
RS := TResourceStream.Create(HInstance,String(lpszName),RT_RCDATA);
end
else
begin
{ By index }
RS := TResourceStream.CreateFromID(HInstance,NativeUInt(lpszName),RT_RCDATA);
end;
try
FontType := CheckFontData(RS);
if FontType in [TFontType.ftGDIFont] then
begin
{ Regsiter font to GDI }
if AddFontMemResourceEx(RS.Memory,RS.Size,nil,@NumFonts) = 0 then
begin
RaiseLastOSError;
end;
end;
if FontType in [TFontType.ftGDIFont, TFontType.ftWebFont] then
begin
{ Register font to Skia4Delphi }
TSkDefaultProviders.RegisterTypeface(RS);
end;
finally
RS.Free;
end;
Result := True;
end;
procedure LoadResourceFonts;
begin
if EnumResourceNames(HInstance,RT_RCDATA,@EnumResNameProc,0) = False then
begin
RaiseLastOSError;
end;
end;
initialization
LoadResourceFonts;
end.
ユニットのinitialization部で呼び出しているLoadResourceFonts関数では、Win32APIのEnumResourceNames関数でプログラムに含まれるRT_RCDATAのリソースを列挙します。コールバック関数EnumResNameProcではコンストラクタTResourceStream.Createを呼び出してフォントをストリームに読み出し、フォントデータかどうかの判定関数CheckFontDataを呼び出します。CheckFontData関数ではストリームから先頭4バイトを読み出し、TrueType(.ttf)、TrueType Collection(.ttc)、OpenType(.otf)、OpenType Collection(.otc)、WOFF(.woff)、WOFF2(.woff2)のそれぞれのシグネチャに一致するかどうかでフォントデータかどうかの判定を行います。GDIでは使用できないWOFF/WOFF2形式のフォントもSkia4Delphiでは使用できるので、WOFF/WOFF2形式のときはAddFontMemResourceEx関数に加えてTSkDefaultProviders.RegisterTypefaceも呼び出すようにしています。これで登録したフォントはSkia4DelphiのFont.Familiesにそのフォント名を指定することで使用できます。TSkLabelならTSkLabel.TextSettings.Font.Families、ISkCanvasに対する描画ならTSkTypeface.MakeFromNameの第1パラメータです。
ん?リソースタイプFONTではなくRCDATAで埋め込んだフォントデータをAddFontMemResourceEx関数に渡せる?じゃあ前回のアーティクルのようにリソースコンパイラを差し替えたりせず、RCDATAでやればいいのでは?と思うかもしれません。その通りで、今回の方法(フォントをRCDATAで埋め込む)を使えば、Delphi 12.3およびそれ以前でもビルド前イベントでresinatorを使って処理する必要はありません。しかしプログラムにフォント以外のRCDATAのリソースが埋め込まれていた場合は、それらもすべて読み出してフォントデータかどうかの判別をする必要があります。このオーバヘッドを許容できるのであれば、今回の方法でも問題ありません。
2025年12月10日
Microsoft Monthly Update 2025/12
今日はMicrosoftのセキュリティアップデートの日です。
2025 年 12 月のセキュリティ更新プログラム - リリース ノート - セキュリティ更新プログラム ガイド - Microsoft
2025 年 12 月のセキュリティ更新プログラム (月例)
2025 年 12 月のセキュリティ更新プログラム - リリース ノート - セキュリティ更新プログラム ガイド - Microsoft
2025 年 12 月のセキュリティ更新プログラム (月例)
Delphi 12.3までの環境でフォントをリソースとして埋め込むとコンパイル時にエラーになる場合の対策
このアーティクルはDelphi Advent Calendar 2025の10日目の記事です。
前回のアーティクルでプログラムにフォントをリソースとして埋め込んで使用する方法を見てきましたが、Delphi 12.3 Athensおよびそれ以前の環境ではコンパイルしようとすると、埋め込もうとしたフォントによっては
Delphiのリソースのコンパイルはデフォルトではbrcc32.exe→cgrc.exe→rc.exeと、最終的にMicrosoftのリソースコンパイラが使われるのですが、このrc.exeに多数の不具合と未定義動作があり、フォントを解析するときの処理の不具合でこのような状況になるようです(下記記事参照)。
一方Delphi 13 Florenceでは新機能ページのIDEツールの改善のリソース コンパイラの項にあるように、Ryan Liptakさんによるrc.exe互換のオープンソース実装であるresinatorをデフォルトで使用するように変更されています。
そこでこのresinatorをDelphi 12.3までの環境で使用する手順を確認していきます。
同じ環境にDelphi 13 Florence(またはそれ以降のバージョン)がインストールされている場合はパスが通った場所に既にresinatorが配置されているため、別途インストールする必要はありません。そうでない場合は、まずGitHubのリポジトリにアクセスし、最新版のWindows x64のバイナリ(2025/10/23現在ではv0.1.0にあるwindows-x86_64-resinator.zip)をダウンロードし、resinator.exeを(できればパスが通った)適切な場所に展開します(簡単なのはDelphiのインストール先のbinフォルダの下あたりかも)。
次にDelphiのIDEでエラーになるプロジェクトを開き、"メインメニュー"→"プロジェクト"→"リソースと画像"で"<プロジェクト名>のリソース"ダイアログを開いてすべての項目を削除して"OK"で閉じます(<プロジェクト名>Resource.rcファイルは削除されませんので、これをresinatorでコンパイルします)。
"メインメニュー"→"プロジェクト"→"オプション"で"プロジェクトオプション"ダイアログを開き、"ビルド"→"ビルドイベント"のターゲットで"全ての構成 - Windows 32 ビットプラットフォーム"(または"全ての構成 - Windows 64 ビットプラットフォーム")を選択し、"ビルド前イベント"の"コマンド"に
最後にプロジェクトファイル(*.dpr)の "program プロジェクト名;" の次に "{$R *.dres}" の行を追加します(リソースダイアログで全項目削除すると自動的に削除されてしまうので)。
これによって、プロジェクトをコンパイルするときのビルド前イベントでリソーススクリプトファイル(.rc)をresinatorでコンパイルしてリソースファイル(.dres)を生成しておき、リンカでこのリソースファイルをリンクする、という動作になります。
Skia4Delphiの描画(TSkLabelやISkCanvas)でもリソースとして埋め込んだフォントを使用する方法については次のアーティクルで説明します。
なおMicrosoftのリソースコンパイラrc.exeにどのような不具合があり、resinatorではどのような動作に修正されているのかについてはRyan LiptakさんのblogのEvery bug/quirk of the Windows resource compiler (rc.exe), probably - ryanliptak.comというアーティクルにまとめられています。
前回のアーティクルでプログラムにフォントをリソースとして埋め込んで使用する方法を見てきましたが、Delphi 12.3 Athensおよびそれ以前の環境ではコンパイルしようとすると、埋め込もうとしたフォントによっては
[BRCC32 エラー] "brcc32" はコード 1 を伴って終了しました。
とリソースコンパイラでエラーになることがあります。Delphiのリソースのコンパイルはデフォルトではbrcc32.exe→cgrc.exe→rc.exeと、最終的にMicrosoftのリソースコンパイラが使われるのですが、このrc.exeに多数の不具合と未定義動作があり、フォントを解析するときの処理の不具合でこのような状況になるようです(下記記事参照)。
一方Delphi 13 Florenceでは新機能ページのIDEツールの改善のリソース コンパイラの項にあるように、Ryan Liptakさんによるrc.exe互換のオープンソース実装であるresinatorをデフォルトで使用するように変更されています。
そこでこのresinatorをDelphi 12.3までの環境で使用する手順を確認していきます。
同じ環境にDelphi 13 Florence(またはそれ以降のバージョン)がインストールされている場合はパスが通った場所に既にresinatorが配置されているため、別途インストールする必要はありません。そうでない場合は、まずGitHubのリポジトリにアクセスし、最新版のWindows x64のバイナリ(2025/10/23現在ではv0.1.0にあるwindows-x86_64-resinator.zip)をダウンロードし、resinator.exeを(できればパスが通った)適切な場所に展開します(簡単なのはDelphiのインストール先のbinフォルダの下あたりかも)。
次にDelphiのIDEでエラーになるプロジェクトを開き、"メインメニュー"→"プロジェクト"→"リソースと画像"で"<プロジェクト名>のリソース"ダイアログを開いてすべての項目を削除して"OK"で閉じます(<プロジェクト名>Resource.rcファイルは削除されませんので、これをresinatorでコンパイルします)。
"メインメニュー"→"プロジェクト"→"オプション"で"プロジェクトオプション"ダイアログを開き、"ビルド"→"ビルドイベント"のターゲットで"全ての構成 - Windows 32 ビットプラットフォーム"(または"全ての構成 - Windows 64 ビットプラットフォーム")を選択し、"ビルド前イベント"の"コマンド"に
resinator.exe -v $(PROJECTNAME)Resource.rc $(PROJECTNAME).dres
と設定します(もしパスが通っていない場所にresinator.exeを配置した場合は"resinator.exe"を絶対パスで指定してください)。最後にプロジェクトファイル(*.dpr)の "program プロジェクト名;" の次に "{$R *.dres}" の行を追加します(リソースダイアログで全項目削除すると自動的に削除されてしまうので)。
program Project1;
{$R *.dres}
uses
Vcl.Forms,
...
こんな感じです。これでコンパイルするとビルド前イベントで"(プロジェクト名)を信頼しますか?"という警告ダイアログが表示されるので、"このプロジェクトを常に信頼する"にチェックを入れて"はい"をクリックします。これによって、プロジェクトをコンパイルするときのビルド前イベントでリソーススクリプトファイル(.rc)をresinatorでコンパイルしてリソースファイル(.dres)を生成しておき、リンカでこのリソースファイルをリンクする、という動作になります。
Skia4Delphiの描画(TSkLabelやISkCanvas)でもリソースとして埋め込んだフォントを使用する方法については次のアーティクルで説明します。
なおMicrosoftのリソースコンパイラrc.exeにどのような不具合があり、resinatorではどのような動作に修正されているのかについてはRyan LiptakさんのblogのEvery bug/quirk of the Windows resource compiler (rc.exe), probably - ryanliptak.comというアーティクルにまとめられています。
2025年12月9日
プログラムにフォントをリソースとして埋め込んで使用する
プログラムにフォントをリソースとして埋め込んで使用する
このアーティクルはDelphi Advent Calendar 2025の9日目の記事です。
プログラムのUIや印刷などで、標準でWindowsに含まれないフォントを使用したいようなことがあります。もちろんインストーラなどを使って実行環境に(ライセンスに従って)フォントをインストールすることができればそれでよいのですが、状況によってはフォントのインストールが難しい、ということもあります。このような場合にプログラムにフォントをリソースとして埋め込み、これを実行時にWindowsに登録して使用する、という方法があります。
まずプロジェクトにフォントをリソースとして追加します。Delphi IDEの"メインメニュー"→"プロジェクト"→"リソースと画像"→"<プロジェクト名>のリソース"ダイアログで、フォント(.ttfなど)をリソースとして追加します。このときリソースタイプはFONT、リソース識別子は(デフォルトの)1からの整数とします(一意であれば整数値でも文字列でも構いません)。これでリソーススクリプトファイル <プロジェクト名>Resource.rc が用意されて、コンパイル時にリソースコンパイラでリソースファイル <プロジェクト名>.dres が作られます。またプロジェクトソースの "program <プロジェクト名>;" の次に "{$R *.dres}" の行が自動的に追加されることでこのリソースファイルが実行ファイルにリンクされる、ということになります。
プログラム側の対応ですが、プログラムのなるべく早い時点でこのフォントを読み出して登録します。
このようなユニットをプロジェクトに追加することで、プログラムの開始時に埋め込まれているフォントリソースをWindowsに登録して使用することができるようになります。
え?Delphi 12 Athensやそれ以前の環境でコンパイルしようとするとBRCC32 エラーになる?それはMicrosoftのリソースコンパイラ(rc.exe)の不具合が原因です。次のアーティクルではこの問題を解決します。
プログラムのUIや印刷などで、標準でWindowsに含まれないフォントを使用したいようなことがあります。もちろんインストーラなどを使って実行環境に(ライセンスに従って)フォントをインストールすることができればそれでよいのですが、状況によってはフォントのインストールが難しい、ということもあります。このような場合にプログラムにフォントをリソースとして埋め込み、これを実行時にWindowsに登録して使用する、という方法があります。
まずプロジェクトにフォントをリソースとして追加します。Delphi IDEの"メインメニュー"→"プロジェクト"→"リソースと画像"→"<プロジェクト名>のリソース"ダイアログで、フォント(.ttfなど)をリソースとして追加します。このときリソースタイプはFONT、リソース識別子は(デフォルトの)1からの整数とします(一意であれば整数値でも文字列でも構いません)。これでリソーススクリプトファイル <プロジェクト名>Resource.rc が用意されて、コンパイル時にリソースコンパイラでリソースファイル <プロジェクト名>.dres が作られます。またプロジェクトソースの "program <プロジェクト名>;" の次に "{$R *.dres}" の行が自動的に追加されることでこのリソースファイルが実行ファイルにリンクされる、ということになります。
プログラム側の対応ですが、プログラムのなるべく早い時点でこのフォントを読み出して登録します。
unit LoadResFontsForGDI;
interface
uses
Winapi.Windows,
System.SysUtils, System.Classes;
implementation
function EnumResNameProc(hModule: HMODULE; lpszType: PChar; lpszName: PChar; lParam: LONG_PTR): BOOL; stdcall;
var
RS: TResourceStream;
NumFonts: DWORD;
begin
{ Load font }
if Is_IntResource(lpszName) = False then
begin
{ By name }
RS := TResourceStream.Create(HInstance,String(lpszName),RT_FONT);
end
else
begin
{ By index }
RS := TResourceStream.CreateFromID(HInstance,NativeUInt(lpszName),RT_FONT);
end;
try
{ Regsiter font to GDI }
if AddFontMemResourceEx(RS.Memory,RS.Size,nil,@NumFonts) = 0 then
begin
RaiseLastOSError;
end;
finally
RS.Free;
end;
Result := True;
end;
procedure LoadResourceFonts;
begin
if EnumResourceNames(HInstance,RT_FONT,@EnumResNameProc,0) = False then
begin
RaiseLastOSError;
end;
end;
initialization
LoadResourceFonts;
end.
ユニットのinitialization部で呼び出しているLoadResourceFonts関数では、Win32APIのEnumResourceNames関数でプログラムに含まれるRT_FONTのリソースを列挙します。コールバック関数EnumResNameProcではパラメータlpszNameに格納されているリソース名が名前かインデックスかをIs_IntResource関数で判定し、名前であればコンストラクタTResourceStream.Createの文字列を取るオーバロードを、インデックスであればインデックスを取るオーバロードを呼び出してフォントをリソースストリームに読み出し、Memoryプロパティの示すアドレスとSizeプロパティの示すサイズ(バイト数)をWin32APIのAddFontMemResourceEx関数に渡して登録します。このようなユニットをプロジェクトに追加することで、プログラムの開始時に埋め込まれているフォントリソースをWindowsに登録して使用することができるようになります。
え?Delphi 12 Athensやそれ以前の環境でコンパイルしようとするとBRCC32 エラーになる?それはMicrosoftのリソースコンパイラ(rc.exe)の不具合が原因です。次のアーティクルではこの問題を解決します。
2025年12月1日
2025/12開催のセミナー
- Web Seminar
- 2025/12/23 17:00-18:00(JST) Delphiのヘルパーを学ぼう - エンバカデロ・デベロッパーTV(2025年12月23日)
- Live Seminar
- Community Event
登録:
コメント (Atom)