1

次のコードはかなりの問題を引き起こします:

procedure TForm1.Button1Click(Sender: TObject);
var dc : HDC;
    meta : TMetafile;
    metaCanv : TMetafileCanvas;
    cr : TRect;
    sz : TSize;
begin
     dc := GetDC(0);
     SetWindowExtEx(dc, 4800, 1300, @sz);
     ShowMessage(Format('size %d, %d', [sz.cx, sz.cy]));

     meta := TMetafile.Create;

     meta.SetSize(4500, 1300);

     metaCanv := TMetafileCanvas.Create(meta, dc);
     try
        IntersectClipRect(metaCanv.Handle, 0, 0, 4600, 1300);

        cr := metaCanv.ClipRect;

        with cr do
             ShowMessage(Format('clip rect: %d, %d, %d, %d', [Top, Left, Bottom, Right]));

     finally
            metaCanv.Free;
            meta.Free;
     end;


     DeleteDC(dc);
end;

問題は、クリッピング長方形がディスプレイ解像度にバインドされていることです。たとえば、画面の幅が1920ピクセルの場合、クリッピング長方形はこの値にバインドされます。

クリッピングを完全に削除し、線のイベントを完全な下部の長方形のコーナーにペイントすることは問題ではないことに注意してください。この問題は、クリッピング領域が設定されていて(たとえば、例に示すように完全なメタファイルの幅/高さに)、線をペイントする場合に発生します->画面の幅/高さにクリップされます。

基本的に問題を解決するリファレンスとしてプリンタDCを使用できることはわかっていますが、いくつかの副作用があります(たとえば、このようなDCを使用してメタファイルにgdi +を描画しても機能しません)。

この奇妙なクリッピング動作がもう存在しないようにシステムを「だます」方法を知っている人はいますか?

4

1 に答える 1

3

ClipRectあなたが描くことができる唯一の部分であることは誤った推定です。

に関するドキュメントTCustomCanvas.ClipRect

ClipRectを使用して、キャンバスにペイントが必要な場所を特定します。

これは、次のように、超えて描画し、描画されたClipRectものを表示しようとすることで簡単に確認できます。

procedure TForm1.Button1Click(Sender: TObject);
var
  MetaFile: TMetafile;
  MetaCanvas: TMetafileCanvas;
begin
  MetaFile := TMetafile.Create;
  try
    MetaCanvas := TMetafileCanvas.Create(MetaFile, 0);
    try
      MetaFile.SetSize(4500, 1300);
      MetaCanvas.LineTo(4500, 1300);
    finally
      MetaCanvas.Free;
    end;
    Canvas.Draw(-4400, -1200, MetaFile);
  finally
    MetaFile.Free;
  end;
end;

ここに画像の説明を入力してください

于 2013-03-21T13:15:34.273 に答える