Page 1 of 2
TSimpleGraph or TPrintPreview bug ?
Posted:
April 19th, 2005, 1:35 pm
by P_G
Hello again,
I noticed a strange behaviour in TPrintPreview, but I'm not sure if this is a bug.
I use the TPrintPreview as a preview for a TSimpleGraph component. To create the graphic for TPrintPreview I took the following line:
- Code: Select all
Mainform.SimpleGraph.Print(PrintPreview1.Canvas, Rect(0, 0, Mainform.SimpleGraph.GraphBounds.Right, (Mainform.SimpleGraph.GraphBounds.Bottom)));
Here's the problem: I insert about 20 nodes (in line) in TSimpleGraph; each one containing a metafile. From a certain position TPrintPreview only displays the border of the nodes but not the metafiles. If I insert a bitmap instead the problem doesn't occur.
Does anyone have an idea concerning this effect?
C.U. P_G
Posted:
April 19th, 2005, 8:11 pm
by Kambiz
The Print method of SimpleGraph draws the graph on the specified Canvas and in the rectangle specified by the Rect parameter. Therefore, you sould pass a rectangle on the PrintPreview page, not the bounding rectangle of the graph.
The following code is not tested but should work.
- Code: Select all
with PrintPreview1 do
SimpleGraph.Print(Canvas, Rect(0, 0, PagePixels.X, PagePixels.Y));
Posted:
April 20th, 2005, 4:48 pm
by P_G
Hello Kambiz,
I'm sorry but the problem occurs even with your code. And - as mentioned before - it doesn't effect nodes with simple bitmaps. That's why I thought it could be a bug, because I can't believe to have this problem by passing the wrong rect-parameters. In this case the bitmap nodes would show the same problem. BTW, nodes without graphics are always displayed in a correct way.
P_G
Posted:
April 21st, 2005, 6:39 pm
by Kambiz
Hi P_G,
I dropped an instance of PrintPreview on the main form of the SimpleGraph's demo and added the following lines of code:
- Code: Select all
procedure MainForm.PreviewGraph;
begin
PrintPreview.BeginDoc;
try
SimpleGraph.Print(PrintPreview.Canvas, PrintPreview.PageBounds);
finally
PrintPreview.EndDoc;
end;
end;
Everything works just fine!
Posted:
April 25th, 2005, 10:55 am
by P_G
Hi Kambiz,
Here's what I get (see attachment). I took the simplegraph demo the way you did. I added a second form for the printpreview and put about 25 metafiles on the simplegraph. The printpreview shows the metafile nodes to a certain point and then only the borders.
Don't know why...
P_G[/img]
Posted:
May 9th, 2005, 12:18 pm
by Kambiz
Could you please attach your sgp file?
Posted:
May 9th, 2005, 7:08 pm
by P_G
Hello Kambiz,
here's the sgp-file attached.
P_G
Posted:
May 11th, 2005, 6:17 pm
by Kambiz
Hi,
This problem occurs inside SimpleGraph. If you export the graph as metafile, you will see the bug.
So far I couldn't figure out the problem. I wonder why this bug appears only when the background image of the node is a metafile.
In case of any progress, I'll let you know.
Cheers
Posted:
May 12th, 2005, 2:13 pm
by Kambiz
This bug seems to be a Windows bug.
The bug occurs when the following conditions are met:
- The target canvas is a metafile canvas
- The canvas is clipped by a region
- A metafile is drawn on the canvas at X and Y position, which X or Y are larger than screen (better to say: reference DC) width or height, although are within the canvas bounds.
The attached program demonstrates the bug.
Cheers
Posted:
May 13th, 2005, 3:10 pm
by Kambiz
I had to modify
TGraphNode.DrawBackground as follow to add a workaround to the mentioned bug.
- Code: Select all
procedure TGraphNode.DrawBackground(Canvas: TCanvas);
var
ClipRgn: HRGN;
Bitmap: TBitmap;
Graphic: TGraphic;
begin
if Background.Graphic <> nil then
begin
ClipRgn := CreateClipRgn(Canvas);
try
SelectClipRgn(Canvas.Handle, ClipRgn);
try
Graphic := Background.Graphic;
if (Graphic is TMetafile) or (Graphic is TIcon) or Graphic.Transparent then
Canvas.FillRect(BoundsRect);
Background.OnChange := nil;
try
if (Graphic is TMetafile) and (GetObjectType(Canvas.Handle) = OBJ_ENHMETADC) and
((BoundsRect.Left >= Screen.Width) or (BoundsRect.Top >= Screen.Height)) then
begin // Workaround Windows bug!
Bitmap := TBitmap.Create;
try
Bitmap.Transparent := True;
Bitmap.TransparentColor := clFuchsia;
Bitmap.Canvas.Brush.Color := clFuchsia;
Bitmap.Width := BoundsRect.Right - BoundsRect.Left;
Bitmap.Height := BoundsRect.Bottom - BoundsRect.Top;
Bitmap.Canvas.StretchDraw(Rect(0, 0, Bitmap.Width, Bitmap.Height), Graphic);
Canvas.Draw(BoundsRect.Left, BoundsRect.Top, Bitmap);
finally
Bitmap.Free;
end;
end
else
Canvas.StretchDraw(BoundsRect, Graphic);
finally
Background.OnChange := BackgroundChanged;
end;
finally
SelectClipRgn(Canvas.Handle, 0);
end;
finally
DeleteObject(ClipRgn);
end;
Canvas.Brush.Style := bsClear;
end;
end;
The update for
SimpleGraph is avilable to download.
Posted:
May 13th, 2005, 4:23 pm
by P_G
Do you know why I like this forum? Because of the support! This thread says it all: It's not only you get great components, but you get an even better support. That's absolutely unique!
Thanks a lot, Kambiz
Posted:
May 13th, 2005, 7:58 pm
by Kambiz
Thanks to you!
Posted:
May 17th, 2005, 1:25 pm
by P_G
Hi Kambiz,
I had some problems with your workaround due to the fact that all critical nodes are converted to bitmaps now, so the quality is not satisfying.
That's why I did some modifications on the GetAsMetafile function. It's not perfect but seems to be on the right way. Maybe you could take a look on the following code:
- Code: Select all
function TSimpleGraph.GetAsMetafile: TMetafile;
var
I: Integer;
GraphRect: TRect;
MetaCanvas: TMetafileCanvas;
v,w: TSize;
begin
GraphRect := GraphBounds;
Result := TMetafile.Create;
Result.Width := GraphRect.Right - GraphRect.Left;
Result.Height := GraphRect.Bottom - GraphRect.Top;
MetaCanvas := TMetafileCanvas.Create(Result, 0);
try
// Workaraound for Windows-bug
SetViewportOrgEx(MetaCanvas.Handle, GraphRect.Left, GraphRect.Top, nil);
SetMapMode(MetaCanvas.Handle, MM_Lometric);
GetWindowExtEx(MetaCanvas.Handle, w);
GetViewPortExtEx(MetaCanvas.Handle, v);
SetMapMode(MetaCanvas.Handle, MM_Anisotropic);
SetWindowExtEx(MetaCanvas.Handle, w.cx, w.cy, nil);
SetViewPortExtEx(MetaCanvas.Handle, v.cx, -v.cy, nil);
for I := 0 to Objects.Count - 1 do
with Objects[I] do if IsLink then Draw(MetaCanvas);
for I := 0 to Objects.Count - 1 do
with Objects[I] do if not IsLink then Draw(MetaCanvas);
finally
MetaCanvas.Free;
end;
end;
P_G
Posted:
May 23rd, 2005, 7:40 am
by Kambiz
In your code, the metafile size is in actual size, however you've scaled down the graph.
Posted:
May 23rd, 2005, 8:09 am
by P_G
Yes, of course. I've seen no other way to get all the metafiles as metafiles into the nodes. BTW - I'd be thankful for further suggestions concerning this problem.
Yours, P_G