Page 1 of 1

Strange annotation location upon DrawToMetaCanvas

Posted: Mon Nov 27, 2006 11:57 am
by 9242408
Hi,

Im not sure how to explain it, but I have a Chart with an annotation on it that gets a value I give it during a process. It works great and on the chart when the procedure is done its there. However when printing it for some reason the annotation always appears on the very first chart, whichever one is the first in the series of charts I have. Im not sure if I am doing something wrong.

Here's my code:

Code: Select all

procedure TForm1.AdvToolBarButton14Click(Sender: TObject);
Var
topc,botc: Integer;
Device : array[0..255] of char;
Driver : array[0..255] of char;
Port   : array[0..255] of char;
hDMode : THandle;
PDMode : PDEVMODE;
Meta: TMetaFile;
m: TMetafile;
c: TMetafileCanvas;
tmpW,tmpH: Integer;
resultspath: String;
mycanvas: TMetaFileCanvas;
b: TBitmap;

begin
Printer.PrinterIndex := Printer.PrinterIndex;
  Printer.GetPrinter(Device, Driver, Port, hDMode);
  if hDMode <> 0 then begin
    pDMode := GlobalLock(hDMode);
    if pDMode <> nil then begin
      pDMode^.dmFields := pDMode^.dmFields or dm_PaperSize;
      pDMode^.dmPaperSize := DMPAPER_11X17;
      GlobalUnlock(hDMode);
    end;
  end;

  m := TMetafile.Create;
  c := TMetafileCanvas.Create(m, 0);


  i := 0;
  topc := 2;
  botc := 3;
  m.enhanced := true;
  tmpW:=myChart[i].Width;
  tmpH:=myChart[i].Height;

  for i := 0 to charts - 1 do
  begin

    if i = 0 then
    myChart[i].DrawToMetaCanvas(c,Rect(0,0,tmpW,tmpH));

    if i = 1 then
    myChart[i].DrawToMetaCanvas(c,Rect(0,tmpH,tmpW,topc*tmpH));

    if i >= 2 then
       begin
    myChart[i].DrawToMetaCanvas(c,Rect(0,topc*tmpH,tmpW,botc*tmpH));

         Inc(topc);
         Inc(botc);
    end;

  end;
      try
      c.Destroy;
      Printer.BeginDoc;
      Printer.Canvas.StretchDraw(Rect(10,50,6500,2400),m);
      Printer.EndDoc;

      //resultspath := ConfigGrid.ColumnByName['ResultPath'].Rows[1];
      //m.SaveToFile(ResultsPath + '\' + run + ' ' + filename + '.emf');
      //m.SaveToFile('C:\test.wmf');
    finally
      m.free;
    end;
end;
Thanks,

Tom

Posted: Tue Nov 28, 2006 12:05 pm
by 9242408
Anyone have any ideas on why the annotation shows up on the top chart rather than the chart it was assigned to?


Tom

Posted: Tue Nov 28, 2006 12:19 pm
by narcis
Hi Tom,

How is the annotation positioned at the chart, is it using absolute or relative position?

Posted: Tue Nov 28, 2006 12:25 pm
by 9242408
narcis wrote:Hi Tom,

How is the annotation positioned at the chart, is it using absolute or relative position?

Hi Narcis,

its not really set that way I dont think. The end user just adds it and if its there my app will add some numbers to it. Thats why I do a loop to see if its on any of my charts. Do I need to set this?


Thanks,

Tom

Posted: Tue Nov 28, 2006 12:49 pm
by narcis
Hi Tom,

As told in this old message, annotations and similar objects need to have a position relative to the chart for being printed. Default annotation tool position is absolute.

At this other message you'll find an example on how to set custom position for an annotation tool.

Posted: Tue Nov 28, 2006 1:15 pm
by 9242408
narcis wrote:Hi Tom,

As told in this old message, annotations and similar objects need to have a position relative to the chart for being printed. Default annotation tool position is absolute.

At this other message you'll find an example on how to set custom position for an annotation tool.
Thanks.

My position is always going to be Auto Right Top, can I just set that?


Tom

Posted: Tue Nov 28, 2006 1:55 pm
by narcis
Hi Tom,

Yes, you can set the position doing something like this:

Code: Select all

procedure TForm1.Chart1AfterDraw(Sender: TObject);
begin
  ChartTool1.Left := Chart1.ChartRect.Right - 10;
  ChartTool1.Top := Chart1.ChartRect.Top - 10;
end;

Posted: Tue Nov 28, 2006 5:41 pm
by 9242408
narcis wrote:Hi Tom,

Yes, you can set the position doing something like this:

Code: Select all

procedure TForm1.Chart1AfterDraw(Sender: TObject);
begin
  ChartTool1.Left := Chart1.ChartRect.Right - 10;
  ChartTool1.Top := Chart1.ChartRect.Top - 10;
end;
Narcis,

I tried this out, however my annotation is completely gone. Shouldnt this place it up in the right top corner of my chart?


Thanks,

Tom

Posted: Wed Nov 29, 2006 8:51 am
by narcis
Hi Tom,

Yes, it works fine for me here using this:

Code: Select all

procedure TForm9.Chart1AfterDraw(Sender: TObject);
begin
  ChartTool1.Left := Chart1.ChartRect.Right + 5;
  ChartTool1.Top := Chart1.ChartRect.Top - ChartTool1.Height - 5;
end;

procedure TForm9.FormCreate(Sender: TObject);
begin
  Chart1.Draw;
end;
However, you can play a little bit with this as the proper settings will vary depending on your chart's settings.

Posted: Wed Nov 29, 2006 11:04 am
by 9242408
narcis wrote:Hi Tom,

Yes, it works fine for me here using this:

Code: Select all

procedure TForm9.Chart1AfterDraw(Sender: TObject);
begin
  ChartTool1.Left := Chart1.ChartRect.Right + 5;
  ChartTool1.Top := Chart1.ChartRect.Top - ChartTool1.Height - 5;
end;

procedure TForm9.FormCreate(Sender: TObject);
begin
  Chart1.Draw;
end;
However, you can play a little bit with this as the proper settings will vary depending on your chart's settings.
I am just placing the afterdraw code right before I print, is this right?

Like so:

Code: Select all

procedure TForm1.AdvToolBarButton14Click(Sender: TObject);
Var
topc,botc: Integer;
Device : array[0..255] of char;
Driver : array[0..255] of char;
Port   : array[0..255] of char;
hDMode : THandle;
PDMode : PDEVMODE;
Meta: TMetaFile;
m: TMetafile;
c: TMetafileCanvas;
tmpW,tmpH: Integer;
resultspath: String;
mycanvas: TMetaFileCanvas;
b: TBitmap;
d,k: integer;
begin
Printer.PrinterIndex := Printer.PrinterIndex;
  Printer.GetPrinter(Device, Driver, Port, hDMode);
  if hDMode <> 0 then begin
    pDMode := GlobalLock(hDMode);
    if pDMode <> nil then begin
      pDMode^.dmFields := pDMode^.dmFields or dm_PaperSize;
      pDMode^.dmPaperSize := DMPAPER_11X17;
      GlobalUnlock(hDMode);
    end;
  end;

  m := TMetafile.Create;
  c := TMetafileCanvas.Create(m, 0);

  d:=0;
  i := 0;
  topc := 2;
  botc := 3;
  m.enhanced := true;
  tmpW:=myChart[i].Width;
  tmpH:=myChart[i].Height;

  
    if i = 0 then
    myChart[i].DrawToMetaCanvas(c,Rect(0,0,tmpW,tmpH));

    if i = 1 then
    myChart[i].DrawToMetaCanvas(c,Rect(0,tmpH,tmpW,topc*tmpH));

    if i >= 2 then
       begin
    myChart[i].DrawToMetaCanvas(c,Rect(0,topc*tmpH,tmpW,botc*tmpH));

         Inc(topc);
         Inc(botc);
    end;

for i := 0 to charts - 1 do
  begin
    for k := 0 to mychart[i].Tools.Count - 1 do
    if (mychart[i].Tools.Items[d] is TAnnotationTool) then
    if i = mphchart then
    begin
     With (mychart[i].Tools.Items[k] as TAnnotationTool) do
      begin
        Text:='MPHPS: ' + FormatFloat('###.###',mphps);
        Left := mychart[i].ChartRect.Right - 10;
        Top := mychart[i].ChartRect.Top - 10;
      end;
      Inc(d);
    end;
  end;


      try
      c.Destroy;
      Printer.BeginDoc;
      Printer.Canvas.StretchDraw(Rect(10,50,6500,2400),m);
      Printer.EndDoc;
    finally
      m.free;
    end;
end;
Thanks,

Tom

Posted: Wed Nov 29, 2006 12:44 pm
by 9242408
I put my code in the OnAfterDraw event like it should be, however the annotation still disappears and is no where to be found. This is perplexing me alot. Any suggestions?


Tom

Posted: Thu Nov 30, 2006 12:07 pm
by 9242408
I need some help here. The OnDraw event fires correctly and the code does not error out or nothing but it will not set the annotation correctly. It simply disappears altogether.


Thanks,

Tom

Posted: Fri Dec 01, 2006 12:12 pm
by 9242408
I have flipped code around all day and cant seem to get a grip any further on why it doesnt work as I might expect it to.


Any ideas?