Title doesn't print if "Position" is "Custom&

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
kai
Newbie
Newbie
Posts: 21
Joined: Mon May 10, 2004 4:00 am

Title doesn't print if "Position" is "Custom&

Post by kai » Mon Oct 18, 2004 2:32 am

Hi,
The TChart's Title does not print if the Title's "Position" is set to a custom setting. It does not work with the delivered print preview. I have not customized anything nor am I using my own print routine. My application uses the delivered Print Preview in the Chart Editor, but if you change the Title's "Position" to use the "Customized" and change the "Left" or "Top", then the title does not print when you print it.
I have seen some fixes in this newsgroup for some people using customized print routines, but I need the stock delivered Print Preview working properly.
Do you have a fix? Delphi 7, TeeChart 7
Thanks.
pl

Marjan
Site Admin
Site Admin
Posts: 745
Joined: Fri Nov 07, 2003 5:00 am
Location: Slovenia
Contact:

Post by Marjan » Mon Oct 18, 2004 7:23 am

Hi.
I have seen some fixes in this newsgroup for some people using customized print routines, but I need the stock delivered Print Preview working properly.
In this case the only solution is to:
1) transform initial custom position from screen to real axis scale
2) Then in one of the Chart events transform (fixed) real position back to screen pixels and reposition objects.

It's a bit complicated, but it should work. Another solution is to transform screen pixel coordinates (absolute values) to relative (compared with chart width and height) coordinates. Basically, use the same approach as with real axis scale, but use relative coordinates as fixed values.
Marjan Slatinek,
http://www.steema.com

kai
Newbie
Newbie
Posts: 21
Joined: Mon May 10, 2004 4:00 am

Doesn't work

Post by kai » Tue Oct 19, 2004 2:26 am

Your response is no help at all.
How do I go about fixing your TeeChart 7 Pro's Print Preview so that it prints the title if you set it to it's customized setting? Please tell me what pas file to edit and what to put in. Or better yet, perhaps you could fix it and save a lot of your customers the trouble...

kai
Newbie
Newbie
Posts: 21
Joined: Mon May 10, 2004 4:00 am

Post by kai » Wed Oct 20, 2004 1:50 am

Another solution is to print the chart as a bitmap and forget about the "Detail" more-->normal. I think the way you are printing is to reconstruct all components of the chart and that gives you the ability to change the size of each component. But, you did not handle the Title component properly with all it's customizations. I notice that if I change the Title's Border to round and change the font of the title to a larger size, when you print it you do not get what you see on the chart. (printing without setting the "Custom" position)..

So why bother? Just copy the chart's bitmap and paste it into an image and print it from there.

Also, the advice you give about using stretchdraw is no good (other posts). Stretchdraw used in that context has the risk that it will not print on some printers. Used to happen to me all the time. Instead, I found this code that does a much better job. Here it is:
procedure tFormPPreview.BltTBitmapAsDib(DestDc : hdc; {Handle of where to blt}
x : word; {Bit at x}
y : word; {Blt at y}
Width : word; {Width to stretch}
Height : word; {Height to stretch}
bm : TBitmap); {the TBitmap to Blt}
var
OriginalWidth :LongInt; {width of BM}
dc : hdc; {screen dc}
IsPaletteDevice : bool; {if the device uses palettes}
IsDestPaletteDevice : bool; {if the device uses palettes}
BitmapInfoSize : integer; {sizeof the bitmapinfoheader}
lpBitmapInfo : PBitmapInfo; {the bitmap info header}
hBm : hBitmap; {handle to the bitmap}
hPal : hPalette; {handle to the palette}
OldPal : hPalette; {temp palette}
hBits : THandle; {handle to the DIB bits}
pBits : pointer; {pointer to the DIB bits}
lPPalEntriesArray : PPalEntriesArray; {palette entry array}
NumPalEntries : integer; {number of palette entries}
i : integer; {looping variable}
begin
{If range checking is on - lets turn it off for now}
{we will remember if range checking was on by defining}
{a define called CKRANGE if range checking is on.}
{We do this to access array members past the arrays}
{defined index range without causing a range check}
{error at runtime. To satisfy the compiler, we must}
{also access the indexes with a variable. ie: if we}
{have an array defined as a: array[0..0] of byte,}
{and an integer i, we can now access a[3] by setting}
{i := 3; and then accessing a without error}
{$IFOPT R+}
{$DEFINE CKRANGE}
{$R-}
{$ENDIF}

{Save the original width of the bitmap}
OriginalWidth := bm.Width;

{Get the screen's dc to use since memory dc's are not reliable}
dc := GetDc(0);
{Are we a palette device?}
IsPaletteDevice :=
GetDeviceCaps(dc, RASTERCAPS) and RC_PALETTE = RC_PALETTE;
{Give back the screen dc}
dc := ReleaseDc(0, dc);

{Allocate the BitmapInfo structure}
if IsPaletteDevice then
BitmapInfoSize := sizeof(TBitmapInfo) + (sizeof(TRGBQUAD) * 255)
else
BitmapInfoSize := sizeof(TBitmapInfo);
GetMem(lpBitmapInfo, BitmapInfoSize);

{Zero out the BitmapInfo structure}
FillChar(lpBitmapInfo^, BitmapInfoSize, #0);

{Fill in the BitmapInfo structure}
lpBitmapInfo^.bmiHeader.biSize := sizeof(TBitmapInfoHeader);
lpBitmapInfo^.bmiHeader.biWidth := OriginalWidth;
lpBitmapInfo^.bmiHeader.biHeight := bm.Height;
lpBitmapInfo^.bmiHeader.biPlanes := 1;

if IsPaletteDevice then
lpBitmapInfo^.bmiHeader.biBitCount := 8
else
lpBitmapInfo^.bmiHeader.biBitCount := 24;
lpBitmapInfo^.bmiHeader.biCompression := BI_RGB;
lpBitmapInfo^.bmiHeader.biSizeImage :=
((lpBitmapInfo^.bmiHeader.biWidth *
longint(lpBitmapInfo^.bmiHeader.biBitCount)) div 8) *
lpBitmapInfo^.bmiHeader.biHeight;
lpBitmapInfo^.bmiHeader.biXPelsPerMeter := 0;
lpBitmapInfo^.bmiHeader.biYPelsPerMeter := 0;
if IsPaletteDevice then begin
lpBitmapInfo^.bmiHeader.biClrUsed := 256;
lpBitmapInfo^.bmiHeader.biClrImportant := 256;
end else begin
lpBitmapInfo^.bmiHeader.biClrUsed := 0;
lpBitmapInfo^.bmiHeader.biClrImportant := 0;
end;

{Take ownership of the bitmap handle and palette}
hBm := bm.ReleaseHandle;
hPal := bm.ReleasePalette;

{Get the screen's dc to use since memory dc's are not reliable}
dc := GetDc(0);

if IsPaletteDevice then begin
{If we are using a palette, it must be}
{selected into the dc during the conversion}
OldPal := SelectPalette(dc, hPal, TRUE);
{Realize the palette}
RealizePalette(dc);
end;

{Tell GetDiBits to fill in the rest of the bitmap info structure}
GetDiBits(dc,
hBm,
0,
lpBitmapInfo^.bmiHeader.biHeight,
nil,
TBitmapInfo(lpBitmapInfo^),
DIB_RGB_COLORS);

{Allocate memory for the Bits}
hBits := GlobalAlloc(GMEM_MOVEABLE,
lpBitmapInfo^.bmiHeader.biSizeImage);
pBits := GlobalLock(hBits);
{Get the bits}
GetDiBits(dc,
hBm,
0,
lpBitmapInfo^.bmiHeader.biHeight,
pBits,
TBitmapInfo(lpBitmapInfo^),
DIB_RGB_COLORS);


if IsPaletteDevice then begin
{Lets fix up the color table for buggy video drivers}
GetMem(lPPalEntriesArray, sizeof(TPaletteEntry) * 256);
{$IFDEF VER100}
NumPalEntries := GetPaletteEntries(hPal,
0,
256,
lPPalEntriesArray^);
{$ELSE}
NumPalEntries := GetSystemPaletteEntries(dc,
0,
256,
lPPalEntriesArray^);
{$ENDIF}
for i := 0 to (NumPalEntries - 1) do begin
lpBitmapInfo^.bmiColors.rgbRed :=
lPPalEntriesArray^.peRed;
lpBitmapInfo^.bmiColors.rgbGreen :=
lPPalEntriesArray^.peGreen;
lpBitmapInfo^.bmiColors.rgbBlue :=
lPPalEntriesArray^.peBlue;
end;

FreeMem(lPPalEntriesArray, sizeof(TPaletteEntry) * 256);
end;

if IsPaletteDevice then begin
{Select the old palette back in}
SelectPalette(dc, OldPal, TRUE);
{Realize the old palette}
RealizePalette(dc);
end;

{Give back the screen dc}
dc := ReleaseDc(0, dc);

{Is the Dest dc a palette device?}
IsDestPaletteDevice :=
GetDeviceCaps(DestDc, RASTERCAPS) and RC_PALETTE = RC_PALETTE;


if IsPaletteDevice then begin
{If we are using a palette, it must be}
{selected into the dc during the conversion}
OldPal := SelectPalette(DestDc, hPal, TRUE);
{Realize the palette}
RealizePalette(DestDc);
end;


{Do the blt}
StretchDiBits(DestDc,
x,
y,
Width,
Height,
0,
0,
OriginalWidth,
lpBitmapInfo^.bmiHeader.biHeight,
pBits,
lpBitmapInfo^,
DIB_RGB_COLORS,
SrcCopy);

if IsDestPaletteDevice then begin
{Select the old palette back in}
SelectPalette(DestDc, OldPal, TRUE);
{Realize the old palette}
RealizePalette(DestDc);
end;

{De-Allocate the Dib Bits}
GlobalUnLock(hBits);
GlobalFree(hBits);

{De-Allocate the BitmapInfo}
FreeMem(lpBitmapInfo, BitmapInfoSize);


{Set the ownership of the bimap handles back to the bitmap}
bm.Handle := hBm;
bm.Palette := hPal;

{Turn range checking back on if it was on when we started}
{$IFDEF CKRANGE}
{$UNDEF CKRANGE}
{$R+}
{$ENDIF}
end;


If you want the whole unit, please let me know. It works great.
Kai

kai
Newbie
Newbie
Posts: 21
Joined: Mon May 10, 2004 4:00 am

Post by kai » Mon Oct 25, 2004 11:57 pm

Here is more on this subject:
If I set the Title's "Custom" checkbox to checked and adjust the left and top, the title does not print in the Chart Editor's print preview. However, if I drop a ChartPreviewer on the form and make sure the "Smooth" setting is on and the "As Bitmap" is on, the Title does print. So I edited the source code to get rid of the "Print Preview" button on the General Tab in the Chart Editor , made the smooth checkbox checked and invisible so the user can't change it and am using the ChartPreviewer component to print now (with the two changes above). It seems to work ok.
I've also got themes working well. The only bug I"ve found is that the SaveChartToFile and LoadChartFromFile do not save and restore the Title properly if the "transparent" is not checked. It seems to be stuck on transparent.

Post Reply