TsgDWGImage in reports

Discuss and ask questions about CAD VCL (Delphi and C++ Builder).

Moderators: SDS, support, admin

Post Reply
edbored
Posts: 20
Joined: 26 Jul 2005, 00:15
Location: Canada

TsgDWGImage in reports

Post by edbored » 26 Jul 2005, 00:41

I'm trying to add CADImportVCL support to my Report Builder reports. There is a TppImage in report builder - but assigning a TsgDWGImage to it doesn't work well: the image is only a few dozen pixels high and wide...

I tried assigning to metafile first, then assigning the metafile to the TppImage, and that works well - except that there is a memory leak (I think because the reference count on EnhMetafile is never decremented properly).

I created a simple project with just a TImage and a TButton - same memory leak (palette not released, TEnhMetafile still allocated) - tested with MemProof and Memory Sleuth.

Here's the relevant code:

Code: Select all

(button1 click)
<b>var</b>
  vDWG  : TsgDWGImage;
  fName : string;
  mf    : TMetafile;
<b>begin</b>
 // image1.Picture.Bitmap.ReleaseHandle;
  fName:='d:\projects\images\GMX0247P.dwg';
  mf:=tmetafile.create;
  mf.ReleaseHandle;
  <b>try</b>
    vDWG := TsgDWGImage.Create;
    <b>try</b>
      vDWG.LoadFromFile(fName);
      vDWG.IsWithoutBorder:=True;
      vDWG.BackgroundColor:=clWhite;
      vDWG.UseWinEllipse:=True;
      vDWG.GetExtents;
 {.$DEFINE ASSIGNTOIMAGE} // define to test direct to image - no resource leaks
 {$IFDEF ASSIGNTOIMAGE}
      image1.Picture.Assign(vDWG);
      Exit;
 {$ELSE}
      mf.Assign(vdwg.ExportToMetafile(3276700));
    {.$DEFINE TESTRB} // define to test with report builder
    {$IFDEF TESTRB}
      ppImage1.Picture.Assign(mf);
      ppReport1.Print;
    {$ELSE}
      image1.picture.Assign(mf);
    {$ENDIF}
 {$ENDIF}
    <b>finally</b>
      vDWG.Free;
      vDWG:=nil;
    <b>end</b>;
    <b>finally</b>
//    DeleteObject(mf.Palette); // this fixes palette problem
//    DeleteEnhMetaFile(mf.Handle);
      mf.Free;
      mf := <b>nil</b>;
  <b>end</b>;
<b>end</b>;
Can someone suggest an alternate way for me to get data transferred to TppImage? (It is based on TPicture, with wrapper methods to control how it is displayed on screen).

I'm looking for a way to either assign the metafile and destroy it without resource leaks, or perhaps to calculate a Width and Height that can be sent to ppImage so it renders properly.

Cheers,
EdB

edbored
Posts: 20
Joined: 26 Jul 2005, 00:15
Location: Canada

Post by edbored » 26 Jul 2005, 01:43

I've actuallt simplified the function to the following:

Code: Select all

procedure TForm1.btn1Click(Sender: TObject);
<b>var</b>
  fName : string;
<b>begin</b>
  fName:='d:\projects\images\GMX0247P.dwg';
  vDWG := TsgDWGImage.Create;
 <b>try</b>
    vDWG.LoadFromFile(fName);
    vDWG.IsWithoutBorder:=True;
    vDWG.BackgroundColor:=clWhite;
    vDWG.UseWinEllipse:=True;
    vDWG.GetExtents;
    ppImage1.Picture.Metafile:=    vdwg.ExportToMetafile(3276700);
    ppReport1.Print;
  <b>finally</b>
    vDWG.Free;
    vDWG:= <b>nil</b>;
  <b>end</b>;
<b>end</b>;
The "leaking" resources appear to be coming from within CAD ImportVCL. Here's the relevant output from MemSleuth:

Resource Leaks
TypeValueStack
Palette 3108061Ch
pCADRBMEMTEST.exe Graphics.pas line 4211 (Graphics::TMetafile::GetPalette + 0AEh)
pCADRBMEMTEST.exe Graphics.pas line 4389 (Graphics::TMetafile::SetHandle + 0B4h)
pCADRBMEMTEST.exe Graphics.pas line 4032 (Graphics::TMetafileCanvas::Destroy + 03Ch)
pCADRBMEMTEST.exe system.pas line 8386 (System::TObject::Free + 0Bh)
pCADRBMEMTEST.exe DXFImage.pas line 468 (DXFImage::TsgDXFImage::ExportToMetafile + 08Bh)
pCADRBMEMTEST.exe Unit1.pas line 125 (Unit1::TForm1::btn1Click + 0B4h)
pCADRBMEMTEST.exe Controls.pas line 4706 (Controls::TControl::Click + 08Ch)
pCADRBMEMTEST.exe StdCtrls.pas line 3473 (StdCtrls::TButton::Click + 034h)

Enhanced Metafile F3460E6Dh
pCADRBMEMTEST.exe Graphics.pas line 4031 (Graphics::TMetafileCanvas::Destroy + 02Fh)
pCADRBMEMTEST.exe system.pas line 8386 (System::TObject::Free + 0Bh)
pCADRBMEMTEST.exe DXFImage.pas line 468 (DXFImage::TsgDXFImage::ExportToMetafile + 08Bh)
pCADRBMEMTEST.exe Unit1.pas line 125 (Unit1::TForm1::btn1Click + 0B4h)
pCADRBMEMTEST.exe Controls.pas line 4706 (Controls::TControl::Click + 08Ch)
pCADRBMEMTEST.exe StdCtrls.pas line 3473 (StdCtrls::TButton::Click + 034h)


Again, I think this is because the "assign" increments the reference count, and thus the TEnhMetaFile doesn't destroy properly.

Can anyone suggest an alternative approach?

Thanks.

Cheers,
EdB

edbored
Posts: 20
Joined: 26 Jul 2005, 00:15
Location: Canada

Post by edbored » 26 Jul 2005, 11:15

I finally tried registering the TGraphic type in Reporet builder ...

initialization
ppRegisterGraphicClass('DXF', TsgDXFImage);
ppRegisterGraphicClass('DWG', TsgDXFImage);
finalization
ppUnRegisterGraphicClass(TsgDXFImage);

Now I can simply use "ppImage1.LoadFromFile('abc.dwg') and the image loads nicely. For anyone using Report Builder, directdraw:=true seems to be essential.

However, doing this I lose control of "IsWithoutBorder" "GetExtents" - simply loading the image does NOT fill the image completely.

Any suggestion on doing this? That is, the ppImage control has a width and height equal to my report page width and height. I want the dwg to fill as much of the page as possible...

Thanks.
EdB

Evgeny
Posts: 115
Joined: 16 Mar 2004, 11:04
Location: Russia

Post by Evgeny » 26 Jul 2005, 11:48

Hi Ed,
thanks for your questions.
1. the problem with memory leak was in this line:

Code: Select all

ppImage1.Picture.Metafile:= vdwg.ExportToMetafile(3276700);
this line makes two metafiles.
right:
  mf := vdwg.ExportToMetafile(3276700);
  Image1.Picture.Metafile:= mf;
  mf.Free; := True;
2.

Code: Select all

using

initialization
ppRegisterGraphicClass('DXF', TsgDXFImage);
ppRegisterGraphicClass('DWG', TsgDXFImage);
finalization
ppUnRegisterGraphicClass(TsgDWGImage);
ppUnRegisterGraphicClass(TsgDXFImage);
is a good style

3. to remove frame use

Code: Select all

  TsgDXFImage(ppImage1.Picture.Graphic).IsWithoutBorder := True;
this line is one for TsgDXFImage, TsgDWGImage, TsgHPGLImage.

edbored
Posts: 20
Joined: 26 Jul 2005, 00:15
Location: Canada

Post by edbored » 26 Jul 2005, 21:28

Oh yeah!

> TsgDXFImage(ppImage1.Picture.Graphic).IsWithoutBorder := True;

using cast to TsgDXFImage works like a charm!

I'll post results of how to effectively use CADImportVCL on the Report Builder forum for you.

Many thanks!

EdB

Evgeny
Posts: 115
Joined: 16 Mar 2004, 11:04
Location: Russia

Post by Evgeny » 27 Jul 2005, 10:36

Thank you!
Evgeny
http://www.cadsofttools.com

Post Reply