Question

Following code makes quite some troubles:

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;

The problem is that the clipping rectangle is bound to the display resolution e.g. if your screen has 1920 pixels width the clipping rectangle is bound to this value.

Note it is NOT a problem to remove clipping at all and paint lines event to the complete bottom rect corner. The problem arises if a clipping region is set (e.g. to the complete metafile width/height as shown in the example) and then paint the line -> it is clipped to the screen width/height.

I know that I could use e.g. a printer dc as reference which will basically fix the problem but there are a few side effects (e.g. gdi+ drawing on metafiles with such dc's simply does not work).

Anyone knows how to "trick" the system such that this odd clipping behaviour is not there any more?

Was it helpful?

Solution

ClipRect being the only part in which you can draw is a false presumption.

The documentation on TCustomCanvas.ClipRect:

Use ClipRect to determine where the canvas needs painting.

This is easily verified by drawing beyond ClipRect and trying to show what has been drawn, for example as follows:

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;

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top