見出し画像

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が考慮されるため、描画結果に影響を及ぼす可能性がある。

考えられる原因は以下の通り。

  1. プリンターのDPIが高すぎる

    • プリンターの解像度は 600~1200 DPI が一般的で、ディスプレイ(96~144 DPI)とは大きく異なる。

    • その結果、メタファイル内の座標計算やスケーリングが狂い、描画が崩れる可能性がある。

  2. 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仕様変更が影響している可能性もあるため、追加の検証が必要になりそうだ。

いいなと思ったら応援しよう!