Home General
New Blog Posts: Merging Reports - Part 1 and Part 2

Changing autosize on runtime

edited February 2006 in General
Hi,

is it possible to change the .autosize property on a TppLabel on runtime
from false to true, and then retrieving the resulting 'auto' size of that
label, to use as a base for further calculations?

Example:

ppLabel1.AutoSize := (lMustHaveAutoSize);
ppLabel2.Left := ppLabel1.Left + ppLabel1.Width + 4;

Tried it already, but it doesn't seem to work here...

Michael

Comments

  • edited February 2006
    Sorry for the incomplete description. To explain it better:

    What I'm trying to accomplish is - in the simplest case - to print a
    series of 3 horizontal labels,multiplied by a LineNum factor. So for
    example one report will contain 15 lines with 3 labels on each line.

    The first label always acts as a item name, the third one is a
    description. And the one between them is simply a colon. I'm traversing
    all the lines, try to get the .Width of the leftmost label, find the
    longest text, and adjust the other two labels to the right.

    To find the size of a text, I was assuming setting .AutoSize to true and
    assigning the .Caption is enough to re-adjust the leftmost label. Seems
    to be not working. Additionally, there's a special case when no item
    description exists. Then the leftmost label is expanded over the full
    line and contains the single text. The other labels are then set to
    .Visible=false.

    All this stuff is contained in the .DetailBandBeforePrint event
    procedure, and I guess this is a bit too late to get them auto-adjusted.

    Michael


  • edited February 2006
    Hi Michael,

    Unfortunately the AutoSize option is not taken into account until the
    component is drawn to the screen or paper. One option would be to measure
    the text manually. This can be done using the printer canvas (in printer
    pixels) or screen canvas. For instance...

    var
    lBitmap: TBitmap;
    lCanvas: TCanvas;
    lTextWidth: Integer;
    begin

    lBitmap := TBitmap.Create;

    try
    lCanvas := lBitmap.Canvas;
    lCanvas.Font := ppLabel1.Font;
    lTextWidth := lCanvas.TextWidth(aText);
    finally
    lBitmap.Free;
    end;

    end;

    --
    Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited February 2006
    Nico,

    it appears to work in most cases, thank you. Unfortunately, on large
    texts (i.e. 30 or more chars), it seems to measure a bit incorrectly, so
    my colon would be overwritten by the leftmost label.

    Is measuring text on a bitmap's canvas almost identical with the
    measurement functions of the report generator?

    Michael

  • edited February 2006
    Hi Michael,

    Instead of using the screen canvas, try using the printer canvas. If you
    add ppPrinter to your uses clause you will have access to the
    ppPrinter.Canvas property with will measure your text more accurately with
    printer pixels rather than screen pixels. You will then need to convert the
    printer pixels to the units you are using in your report (i.e. inches).
    This can be done using the utility functions provided in the ppUtils.pas
    file.

    uses
    ppPrinter,
    ppUtils,
    ppTypes;

    ...

    liTextWidthPP := ppPrinter.Canvas.TextWidth(aText);
    liTextWidthMM := ppToMMThousandths(liTextWidthPP, utPrinterPixels,
    pprtHorizontal, ppPrinter);
    ldTextWidthInches := ppFromMMThousandths(liTextWidthMM, utInches,
    pprtHorizontal, ppPrinter);
    --
    Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited March 2006
    Nico,

    after implementing this functionality, it works almost all the time. But
    I just have a few workstations where it sporadically will fail with the
    very first printout. Now, I've implemented two Assert() calls to see if
    the ppPrinter is nil or if the ppPrinter.Canvas is nil.

    But for the time being... is there something I should take into account,
    for example, initializing something or the like?

    All calls to my function are done (indirectly) from onDetailBeforePrint,
    so I'd suspect the ppPrinter's already initialized and ready.

    Michael

  • edited March 2006
    Hi Michael,

    Which version of ReportBuilder are you using? In later versions, I believe
    this issue was fixed. Are you able to determine what steps need to be taken
    to cause the application to fail? For instace, are you creating a file
    device and calling PrintToDevices? In this case, the printer object would
    not be available.

    --
    Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited March 2006
    Nico,

    we're using 7.03, I guess. We don't print to a file but sometimes to
    screen. But in this case, we also need to get font dimensions and I think
    it should work.

    Users just start to print, and when it fails, then it fails only for the
    first time. But it doesn't do that all the time.

    Michael

  • edited March 2006
    Hi Michael,

    Yes, this issue was fixed for a later release of ReportBuilder. I would
    recommend upgrading RB to the latest version (10.02). Otherwise, you will
    need to be sure the printer object has been created before using its canvas
    property.

    --
    Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited March 2006
    Nico,

    as we're not in the position to upgrade immediately, do you have a
    workaround for the meantime?

    How could I ensure that the printer object is available when I need its
    canvas? Could I create or initialize it manually at application startup or
    at least shortly before it's needed?

    Michael


  • edited March 2006
    You will need to check to see if the printer object is nil every time you
    use it. If it is, you will either need to create it manually or wait until
    it is created by ReportBuilder.

    --
    Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
This discussion has been closed.