
Windows11 24H2 APIの問題: Printer.Handle とメタファイル描画の不具合 by Delphi
概要
Windows 11 24H2 環境で Printer.Handle を TMetafileCanvas.Create に渡した際に、描画結果がおかしくなる問題が発生した。これについて調査した結果と対策をまとめる。
発生した問題
Printer.Handle を TMetafileCanvas.Create の第一引数に渡すと、以下のような不具合が発生する。
画像が消えたり、意図しないスケーリングが発生する。
プリンターの解像度の影響で描画結果が崩れる。
Windows 11 24H2 でのみ発生し、以前のバージョンでは問題なし。
原因の考察
TMetafileCanvas.Create(AHandle: HDC, AMetafile: TMetafile) は指定されたデバイスコンテキスト(DC)の情報を基にメタファイルを作成する。Printer.Handle を使うと、プリンターのデバイスコンテキストのDPIが考慮されるため、描画結果に影響を及ぼす可能性がある。
考えられる原因は以下の通り。
プリンターのDPIが高すぎる
プリンターの解像度は 600~1200 DPI が一般的で、ディスプレイ(96~144 DPI)とは大きく異なる。
その結果、メタファイル内の座標計算やスケーリングが狂い、描画が崩れる可能性がある。
Windows 11 24H2 のAPI変更
以前のWindowsでは問題なかったが、Windows 11 24H2 で Printer.Handle の挙動が変わった可能性。
高DPI環境のスケーリング処理が変わり、想定外の描画結果になることが考えられる。
原因調査方法
今回の不具合について、より詳細な原因を突き止めるため、組み込みアセンブラで Printer.Handle の内部処理を解析する予定。これにより、API呼び出しの際にどのような値が渡され、どう処理されるのかを正確に把握する。
解決策
問題を回避するために、Printer.Handle ではなく 0 を指定することを推奨。
var
MetaFile: TMetafile;
Canvas: TMetafileCanvas;
begin
MetaFile := TMetafile.Create;
try
Canvas := TMetafileCanvas.Create(MetaFile, 0); // 0 を指定してシステムのデフォルトDCを使用
try
// 通常の描画処理
finally
Canvas.Free;
end;
// メタファイルの利用
finally
MetaFile.Free;
end;
end;
まとめ
Windows 11 24H2 で Printer.Handle を使うと、描画が崩れる問題が発生した。原因はプリンターの高DPI設定やAPIの変更による可能性が高い。
回避策として 0 を指定してシステムのデフォルトDCを使うことで正常に描画できることを確認。
今後、組み込みアセンブラを使って Printer.Handle の内部処理を解析し、さらなる原因調査を進める予定。WindowsのAPI仕様変更が影響している可能性もあるため、追加の検証が必要になりそうだ。