【问题标题】:Metafile clipping rectangle元文件剪裁矩形
【发布时间】:2013-03-10 19:11:54
【问题描述】:

下面的代码很麻烦:

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 作为参考,基本上可以解决问题,但有一些副作用(例如,gdi+ 在元文件上绘图) dc 根本不起作用)。

任何人都知道如何“欺骗”系统,使这种奇怪的剪辑行为不会 还有吗?

【问题讨论】:

  • 我看不到“奇怪的剪辑”,按要求工作,您使用剪辑的意图是什么?
  • 什么你看不到奇怪的剪辑?显示消息是否显示与 4600、1300 不同的值?至少在我的计算机(和其他计算机)上,此代码显示 3600、1200(这是我的桌面宽度),而其他代码仅显示 1920x1200 左右的值(现在最常见)。
  • 我认为默认的 cliprect 是针对桌面大小的,因为这是图元文件的可见部分而不是可绘制部分。您可能想查看stackoverflow.com/questions/9739124/… 来设置您的图元文件,看看是否可以为您提供更好的cliprect。如果没有:没关系,因为你可以在你的cliprect之外绘制。
  • 如果你使用 IntersectClipRect 然后你告诉 Win API 将你给的矩形与当前(屏幕大小的)剪切矩形相交。如果您想避免它,请使用 setClipRgn 而不是上面的那个。

标签: delphi clipping metafile


【解决方案1】:

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;

【讨论】:

  • 谢谢!你拯救了我的一天。我完全没有意识到 cliprect 函数不返回实际设置的剪辑区域,而只返回需要重新绘制的部分 - 所以现在完全有道理 gdi 假设不需要在屏幕分辨率后面绘制任何内容。
猜你喜欢
  • 2013-10-05
  • 2014-02-03
  • 2013-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-08
相关资源
最近更新 更多