Changing autosize on runtime
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
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
This discussion has been closed.
Comments
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
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
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
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
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
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
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
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
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
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
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
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
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
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
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com