Copyright © 1989-2010 by Joe C. Hecht All Rights Reserved
Copyright © 2011-2019 by CODE4SALE, LLC All Rights Reserved
Contact CODE4SALE, LLC - Joe Hecht.
TExcellent home page
TExcellent documentation home page!
Try TExcellentFormPrinter!
Buy TExcellentFormPrinter!
Try TExcellentImagePrinter!
Buy TExcellentImagePrinter!
Product names, trademarks, and servicemarks mentioned are owned by their respective owners.
Changes since version 3.4
All TExcellent products have now been upgraded to be compatible with all 32 and 64 bit versions of the
Delphi and C++ Builder Windows compilers, and the TExcellent version number has been adjusted to now reflect
compatibility with RAD Studio compiler version numbers.
Please note that TExcellentFormPrinter and the PrnUtils dialog are very VCL specific.
Non VCL notes: While TExcellent products are VCL and Windows specific, and FireMonkey is not officially supported,
we have found that some TExcellent products are in fact usable in non-VCL projects. For example, TExcellentImagePrinter
can be used in a FireMonkey Windows application (complete with the PrnUtils abort dialog) with minimal changes to your
calling code. For example, creating our printing abort / status dialog can be accomplished with the following code:
C++Builder:
AbortDialog := CreateAbortDialog(FMX.Platform.Win.FormToHWND(this), this);Delphi:
AbortDialog := CreateAbortDialog(FMX.Platform.Win.FormToHWND(self), self);
TExcellentCompilerDefs.inc: Not required by the TExcellent products themselves.
The example and demo projects now make use of an include file to help determine the compiler version and capabilities in use, and is
PrnDibBuildMode.inc: An include file used to determine the build mode (Currently demo/release) and
is required to compile release (non-demo) versions of TExcellent products.
Some Types have been renamed to reflect the name of the unit they are used in (to avoid scoping and compiler errors,
and to allow the C and Pascal source to have greater symmetry).
Pointer types traditionally passed to callback functions as typecast integer values have been typed to a pointer sized
integer (size_t where practical and a 32 unsigned integer where not practical) and renamed as follows:
UNITNAME_PTR_UINT
UNITNAME_PTR_AS_UINT
Example:
PRNFORM_PTR_AS_UINT
PRNFORM_PTR_UINT
TAppCallbackFn() has been renamed to:
TPrnFormAppCallbackFn (TExcellentFormPrinter)
TPrnDibAppCallbackFn (TExcellentImagePrinter)
Pointers to character strings used in filenames and captions hsve changed to TCaption and TFilename types!
In some cases, pointers to untyped pointer types (void *) have changed to (PVOID *).
Installation
GetPrnPageInfo
TPrnPageInfo
TScaleInfo
ScaleToFitX
ScaleToFitY
ScaleToBestFit
TPixelSizeInfo
GetPixelSizeInfo
GetNumPagesRequired
GetMemEx
FreeMemEx
LoadDIBFromStream
LoadDIBFromFile
LoadDIBFromTBitmap
TAbortDialog
TPrinterAbortDialog
CreateAbortDialog
FreeAbortDialog
AbortDialogSetCaption
AbortDialogUserHasCanceled
CreatePrinterAbortDialog
FreePrinterAbortDialog
PrinterAbortDialogSetCaption
PrinterAbortDialogAborted
Back to Functions and Structures
function GetPrnPageInfo(dc : HDC; lpPrnPageInfo : PPrnPageInfo) : BOOL; stdcall;
Location: PrnUtils.pas
This function is usefull for retrieving page information from a given device context. It accepts a dc (Canvas.Handle) and a pointer to a TPrnPageInfo structure. Retruns TRUE if successfull.
Example:
uses PrnUtils; var PrnPageInfo : TPrnPageInfo; begin GetPrnPageInfo(Printer.Canvas.Handle, @PrnPageInfo); end;
Back to Functions and Structures
type PPrnPageInfo = ^TPrnPageInfo; TPrnPageInfo = packed record Margin : TRect; { normal margins to printing area } PageSize : TPoint; { normal page or paper size } PageArea : TPoint; { normal page image size } AdjustedMargin : TRect; { adjusted margins (equal on all sizes) } AdjustedPageArea : TPoint; { page image size adjusted for equal margins } AdjustedMarginOffset : TPoint; { amount to offset output for adjusted margins } DPI : TPoint; { pixels per inch of the device } end;
Location: PrnUtils.pas
Note: Not all devices have equal margins on all sides. This function is
used with the GetPrnPageInfo() function and
retrieves margin and page information and calculates the "adjusted
margins" for the device allowing you to offset either the device context,
or offset your drawing operations, to obtain page output that is equally
centered on the page. All values are returned in pixel coordinates. The Margin
and AdjustedMargin members are the distances from the edge of the device to the
edge of the corrisponding rect. In other words, given that the margins are:
Margin.Left = 150;
Margin.Top = 100;
Margin.Right = 25;
Margin.Bottom = 50;
The Adjusted margines would be:
AdjustedMargin.Left = 150;
AdjustedMargin.Top = 150;
AdjustedMargin.Right = 150;
AdjustedMargin.Bottom = 150;
This structures "Adjusted" members also adjusts for super high
resolution devices that have a page area that exceed 32000 pixels wide or high.
Under Win9x platforms, it is an error condition when output coordinates exceed
32000 pixels. The adjusted page size accounts for this limitation, allowing you
a safe working area under all Windows platforms on all devices.
Back to Functions and Structures
type PScaleInfo = ^TScaleInfo; TScaleInfo = packed record OriginalSize_X : double; OriginalSize_Y : double; ScaledSize_X : double; ScaledSize_Y : double; ScaleFactor_X : double; ScaleFactor_Y : double; end;
Location: PrnUtils.pas
This structure is used with many of the scaling functions included in the PrnUtils unit.
Back to Functions and Structures
function ScaleToFitX(lpScaleInfo : PScaleInfo) : BOOL; stdcall;
Location: PrnUtils.pas
This function accepts a pointer to a TScaleInfo structure. Given an original(X,Y) and an X size to fit, this function calculates the scaled Y size (in proportion to X), and the scale factors used. Returns TRUE if successfull.
TScaleInfo On Input: OriginalSize_X : Horizontal size of the original. OriginalSize_Y : Vertical size of the original. ScaledSize_X : Horizontal size to fit. ScaledSize_Y : Not filled in. ScaleFactor_X : Not filled in. ScaleFactor_Y : Not filled in. TScaleInfo On Output: OriginalSize_X : Horizontal size of the original. OriginalSize_Y : Vertical size of the original. ScaledSize_X : Horizontal size to fit. ScaledSize_Y : OriginalSize_Y scaled in proportion to X. ScaleFactor_X : Horizontal scaling factor. ScaleFactor_Y : Vertical scaling factor.
Example:
uses PrnUtils; var ScaleInfo : TScaleInfo; begin ScaleInfo.OriginalSize_X := 100; ScaleInfo.OriginalSize_Y := 200; ScaleInfo.ScaledSize_X := 1000; ScaleToFitX(@ScaleInfo); {Note:} {ScaledSize_X now equals 1000} {ScaledSize_Y now equals 2000} {ScaleFactor_X now equals 10} {ScaleFactor_Y now equals 10} end;
Back to Functions and Structures
function ScaleToFitY(lpScaleInfo : PScaleInfo) : BOOL; stdcall;
Location: PrnUtils.pas
This function accepts a pointer to a TScaleInfo structure. Given an Original(X,Y) and any Y size to fit, this function calculates the scaled X size (in proportion to Y), and the scale factors used. Returns TRUE if successfull.
TScaleInfo On Input: OriginalSize_X : Horizontal size of the original. OriginalSize_Y : Vertical size of the original. ScaledSize_X : Not filled in. ScaledSize_Y : Vertical size to fit. ScaleFactor_X : Not filled in. ScaleFactor_Y : Not filled in. TScaleInfo On Output: OriginalSize_X : Horizontal size of the original. OriginalSize_Y : Vertical size of the original. ScaledSize_X : OriginalSize_X scaled in proportion to Y. ScaledSize_Y : Vertical size to fit. ScaleFactor_X : Horizontal scaling factor. ScaleFactor_Y : Vertical scaling factor.
Example:
uses PrnUtils; var ScaleInfo : TScaleInfo; begin ScaleInfo.OriginalSize_X := 100; ScaleInfo.OriginalSize_Y := 200; ScaleInfo.ScaledSize_Y := 1000; ScaleToFitY(@ScaleInfo); {Note:} {ScaledSize_X now equals 500} {ScaledSize_Y now equals 1000} {ScaleFactor_X now equals 5} {ScaleFactor_Y now equals 5} end;
Back to Functions and Structures
function ScaleToBestFit(lpScaleInfo : PScaleInfo) : BOOL; stdcall;
Location: PrnUtils.pas
This function accepts a pointer to a TScaleInfo structure. Given an original(X,Y) and an (X,Y) size to fit, this function calculates the "best fit" scaled X and Y size and the scale factors used. The scaling is done in proportion, and *either* the ScaledSize X or Y will fit in the maximum area allowed, and the other "side" will be scaled for a "best fit". If you wish to use the returned scaling factors to stretch drawing coordinates, always multiply *both* the x and y coordinates you wish to scale using the *smaller* of the ScaleFactor_X or ScaleFactor_Y value returned from the function. Returns TRUE if successful.
TScaleInfo On Input: OriginalSize_X : Horizontal size of the original. OriginalSize_Y : Vertical size of the original. ScaledSize_X : Maximum horizontal size to fit. ScaledSize_Y : Maximum vertical size to fit. ScaleFactor_X : Not filled in. ScaleFactor_Y : Not filled in. TScaleInfo On Output: OriginalSize_X : Horizontal size of the original. OriginalSize_Y : Vertical size of the original. ScaledSize_X : OriginalSize_X scaled to best fit. ScaledSize_Y : OriginalSize_Y scaled to best fit. ScaleFactor_X : Horizontal scaling factor. ScaleFactor_Y : Vertical scaling factor.
Example:
uses PrnUtils; var ScaleInfo : TScaleInfo; SmallestScaleFactor : double; begin ScaleInfo.OriginalSize_X := 100; ScaleInfo.OriginalSize_Y := 200; ScaleInfo.ScaledSize_X := 1000; ScaleInfo.ScaledSize_Y := 1000; ScaleToBestFit(@ScaleInfo); {Note:} {ScaledSize_X now equals 500} {ScaledSize_Y now equals 1000} {ScaleFactor_X now equals 10} {ScaleFactor_Y now equals 5} if (ScaleInfo.ScaleFactor_X < ScaleInfo.ScaleFactor_Y) then begin SmallestScaleFactor := ScaleInfo.ScaleFactor_X; end else begin SmallestScaleFactor := ScaleInfo.ScaleFactor_Y; end; Canvas.MoveTo(0, 0); Canvas.LineTo(Trunc(SmallestScaleFactor * 100), Trunc(SmallestScaleFactor * 200)); end;
Back to Functions and Structures
type PPixelSizeInfo = ^TPixelSizeInfo; TPixelSizeInfo = packed record DotsPerInch_X : double; DotsPerInch_Y : double; DotsPerMillimeter_X : double; DotsPerMillimeter_Y : double; DotsPerPoint_X : double; DotsPerPoint_Y : double; end;
Location: PrnUtils.pas
This structure is used with the GetPixelSizeInfo() function and returns information pixel measurements in several popular measuring units. Note that the DotsPerPoint member is a "Printers Point" where their 72 points equal one inch. Additional information: 12 points equal one pica, and 6 picas equals one inch.
Back to Functions and Structures
function GetPixelSizeInfo(dc : HDC; lpPixelSizeInfo : PPixelSizeInfo) : BOOL; stdcall;
Location: PrnUtils.pas
This function accepts a given device context (Canvas.Handle), and a pointer to a TPixelSizeInfo structure, and correctly fills out the TPixelSizeInfo structure. If dc value passed in is zero, then information returned is from the screen dc. Returns TRUE if successful.
Example:
uses PrnUtils; var PixelSizeInfo : TPixelSizeInfo; begin GetPixelSizeInfo(Printer.Canvas.Handle, @PixelSizeInfo); end;
Back to Functions and Structures
function GetNumPagesRequired(PrinterPageSize : DWORD; ImageSize : DWORD) : DWORD; stdcall;
Location: PrnUtils.pas
Given the page size of a device (x or y), and an image size you wish to print (x or y), returns the number of pages (across or down) required to print imagesize in the direction given.
Example:
uses PrnUtils; var NumberOfPagesToPrintAcross : DWORD; NumberOfPagesToPrintDown : DWORD; begin NumberOfPagesToPrintAcross := GetNumPagesRequired(Printer.PageWidth, 20000); NumberOfPagesToPrintDown := GetNumPagesRequired(Printer.PageHeight, 10000); end;
Back to Functions and Structures
function GetMemEx(size : PRNUTILS_PTR_UINT) : pointer; stdcall;
Location: PrnUtils.pas
Allocates a memory block and zeros out the memory block. Returns null on failure. This function is preferable over the RTL memory functions when allocating memory for graphics used in a threaded enviroment. Please use the FreeMemEx() function to free the memory block allocated.
Example:
uses PrnUtils; var p : pointer; begin p := GetMemEx(1024); p := FreeMemEx(p); end;
Back to Functions and Structures
function FreeMemEx(p : pointer) : pointer; stdcall;
Location: PrnUtils.pas
Frees a memory block allocated using the GetMemEx() function. Returns nill on success or returns the original pointer on failure.
Example:
uses PrnUtils; var p : pointer; begin p := GetMemEx(1024); p := FreeMemEx(p); end;
Back to Functions and Structures
function LoadDIBFromStream(TheStream : TStream; var lpBitmapInfo : pointer; var lpBits : Pointer; var BitmapWidth : integer; var BitmapHeight : integer) : BOOL; stdcall;
Location: PrnUtils.pas
This function loads a DIB (device independent bitmap from a TStream object.
The function allocates the neccessary memory for the DIBInfoHeader and the DIB
Bits using the GetMemEx() function, and fills in the
lpBitmapInfo, lpBits, BitmapWidth, and BitmapHeight
parameters. You must use the FreeMemEx() function to
free the memory for the lpBitmapInfo and lpBits when you are
finished using them.
Note: The stream objects current position is advanced. In the case of a failure
(the bitmap is not valid), the stream objects current position may be invalid.
If you are storing multiple DIB images in a stream, it is recommended that you
either create a table of StreamOffsets for each DIB, or use a header for each
bitmap indicating the exact size that the DIB occupies, there may be times when
a given DIB may report an invalid size (or the size must be calculated and the
DIB Header may be invalid). Using this method will allow you to recover from a
read of an improperly formatted DIB image.
Returns TRUE if successful, else returns FALSE.
Example:
uses PrnUtils, PrnDIB; {A unit from out TExcellentImagePrinter product!} var TheStream : TFileStream; {a stream} BitmapInfo : PBITMAPINFO; {pointer to a BitmapInfo structure} Bits : pointer; {pointer to the bits} BitmapWidth : integer; {bitmap width} BitmapHeight : integer; {bitmap height} begin TheFileStream := TFileStream.Create('test.bmp', fmOpenRead OR fmShareDenyWrite); if (NOT LoadDIBFromStream(TheStream, pointer(BitmapInfo), Bits, BitmapWidth, BitmapHeight)) then begin TheStream.Free; ShowMessage('Bitmap load error'); exit; end; TheStream.Free; Printer.BeginDoc; {A function from out TExcellentImagePrinter product!} PrintDIBitmap(Printer.Canvas.Handle, BitmapInfo, Bits, TRUE, TRUE); Printer.EndDoc; FreeMemEx(BitmapInfo); FreeMemEx(Bits); ShowMessage('Printing Completed!'); end;
Back to Functions and Structures
function LoadDIBFromFile(const FileName : string; var lpBitmapInfo : pointer; var lpBits : Pointer; var BitmapWidth : integer; var BitmapHeight : integer) : BOOL; stdcall;
Location: PrnUtils.pas
This function loads a DIB (device independent bitmap) from a file. The function allocates the neccessary memory for the DIBInfoHeader and the DIB Bits using the GetMemEx() function, and fills in the lpBitmapInfo, lpBits, BitmapWidth, and BitmapHeight parameters. You must use the FreeMemEx() function to free the memory for the lpBitmapInfo and lpBits when you are finished using them. Returns TRUE if successful, else returns FALSE.
Example:
uses PrnUtils, PrnDIB; {A unit from out TExcellentImagePrinter product!} var BitmapInfo : PBITMAPINFO; {pointer to a BitmapInfo structure} Bits : pointer; {pointer to the bits} BitmapWidth : integer; {bitmap width} BitmapHeight : integer; {bitmap height} begin if (NOT LoadDIBFromFile('test.bmp', pointer(BitmapInfo), Bits, BitmapWidth, BitmapHeight)) then begin ShowMessage('Bitmap load error'); exit; end; Printer.BeginDoc; {A function from out TExcellentImagePrinter product!} PrintDIBitmap(Printer.Canvas.Handle, BitmapInfo, Bits, TRUE, TRUE); Printer.EndDoc; FreeMemEx(BitmapInfo); FreeMemEx(Bits); ShowMessage('Printing Completed!'); end;
function LoadDIBFromTBitmap(ABitmap : TBitmap; var lpBitmapInfo : pointer; var lpBits : Pointer; var BitmapWidth : integer; var BitmapHeight : integer) : BOOL; stdcall;
Location: PrnUtils.pas
This function loads a DIB (device independent bitmap) from a VCL TBitmap. The
function allocates the neccessary memory for the DIBInfoHeader and the DIB Bits
using the GetMemEx() function, and fills in the
lpBitmapInfo, lpBits, BitmapWidth, and BitmapHeight
parameters. You must use the FreeMemEx() function to
free the memory for the lpBitmapInfo and lpBits when you are
finished using them.
Note: This function is only as accurate as the VCL in its ability to save a
bitmap to a stream. We simply ask the VCL to save the TBitmap to a stream, then
we load it from the stream. In some versions of the VCL, the bitmap format may
change in the process. Note that LoadDIBFromTBitmap() has proven to be much
more reliable than the VCL's GetDibSizes() and GetDIBBits() functions, where we
have seen many real world failures (even though the VCL may use these functions
internally to save the same bitmap to a stream). This is especially true in a
threaded enviroment.
Returns TRUE if successful, else returns FALSE.
Example:
uses PrnUtils, PrnDIB; {A unit from out TExcellentImagePrinter product!} var BitmapInfo : PBITMAPINFO; {pointer to a BitmapInfo structure} Bits : pointer; {pointer to the bits} BitmapWidth : integer; {bitmap width} BitmapHeight : integer; {bitmap height} begin if (NOT LoadDIBFromTBitmap(Image1.Picture.Bitmap, pointer(BitmapInfo), Bits, BitmapWidth, BitmapHeight)) then begin ShowMessage('Bitmap load error'); exit; end; Printer.BeginDoc; {A function from a TExcellentImagePrinter product!} PrintDIBitmap(Printer.Canvas.Handle, BitmapInfo, Bits, TRUE, TRUE); Printer.EndDoc; FreeMemEx(BitmapInfo); FreeMemEx(Bits); ShowMessage('Printing Completed!'); end;
Back to Functions and Structures
type TAbortDialog = class(TForm) btnCancel: TButton; procedure btnCancelClick(Sender: TObject); private { Private declarations } Canceled : BOOL; public { Public declarations } function Aborted : BOOL; end;
Location: PrnUtils.pas
An abort dialog box used by the TExcellentPrinter family of products. We have designed wrapper functions to create, query, and free this dialog class. While you are free to use the class directly, we discourage this practice, as it may not be upwardly compatible with updates to the TExcellentPrinter family of products. In addition, by using the wrapper functions, we can assure compatibility with many of our products when used from other non-VCL languages, as we plan to offer many of our products in a DLL format where the wrapper functions can be called.
Back to Functions and Structures
type TPrinterAbortDialog = TAbortDialog;
Location: PrnUtils.pas
A backwards compatible Abort Dialog prototype for use with code that was written for earlier versions of our products.
Back to Functions and Structures
function CreateAbortDialog(ApplicationHandle : THandle; AOwner: TComponent) : TAbortDialog; stdcall;
Location: PrnUtils.pas
Creates and shows an abort dialog. ApplicationHandle should be set to Application.Handle when called from an executable, and should be set to the Application.Handle of the calling executable when used from a Dynamic Link Library. Returns a 32bit object reference to an TAbortDialog if successful, or nil on failure.
Example:
uses PrnUtils, var AbortDialog : TAbortDialog; {any 32 bit type will so if calling from a non VCL language} begin AbortDialog := CreateAbortDialog(Application.Handle, self); AbortDialogSetCaption(AbortDialog, 'Printing'); {do some lengthy operation} if (AbortDialogUserHasCanceled(AbortDialog)) then begin {Abort the process} end; FreeAbortDialog(AbortDialog); end;
Back to Functions and Structures
procedure FreeAbortDialog(AbortDialog : TAbortDialog); stdcall;
Location: PrnUtils.pas
Frees an abort dialog.
Example:
uses PrnUtils, var AbortDialog : TAbortDialog; {any 32 bit type will so if calling from a non VCL language} begin AbortDialog := CreateAbortDialog(Application.Handle, self); AbortDialogSetCaption(AbortDialog, 'Printing'); {do some lengthy operation} if (AbortDialogUserHasCanceled(AbortDialog)) then begin {Abort the process} end; FreeAbortDialog(AbortDialog); end;
Back to Functions and Structures
procedure AbortDialogSetCaption(AbortDialog : TAbortDialog; s : pChar); stdcall;
Location: PrnUtils.pas
Sets the caption of an abort dialog.
Example:
uses PrnUtils, var AbortDialog : TAbortDialog; {any 32 bit type will so if calling from a non VCL language} begin AbortDialog := CreateAbortDialog(Application.Handle, self); AbortDialogSetCaption(AbortDialog, 'Printing'); {do some lengthy operation} if (AbortDialogUserHasCanceled(AbortDialog)) then begin {Abort the process} end; FreeAbortDialog(AbortDialog); end;
Back to Functions and Structures
function AbortDialogUserHasCanceled(AbortDialog : TAbortDialog) : BOOL; stdcall;
Location: PrnUtils.pas
Returns TRUE if the user has pressed the cancel button of an abort dialog.
Example:
uses PrnUtils, var AbortDialog : TAbortDialog; {any 32 bit type will so if calling from a non VCL language} begin AbortDialog := CreateAbortDialog(Application.Handle, self); AbortDialogSetCaption(AbortDialog, 'Printing'); {do some lengthy operation} if (AbortDialogUserHasCanceled(AbortDialog)) then begin {Abort the process} end; FreeAbortDialog(AbortDialog); end;
Back to Functions and Structures
function CreatePrinterAbortDialog(ApplicationHandle : THandle; AOwner: TComponent) : TPrinterAbortDialog; stdcall;
Location: PrnUtils.pas
This is a backwards compatible wrapper function for code that was written for earlier versions of our products. We now encourage you to use the newer CreateAbortDialog() function where possible. The documentation for this function is the same as the CreateAbortDialog() function.
Back to Functions and Structures
procedure FreePrinterAbortDialog(AbortDialog : TPrinterAbortDialog); stdcall;
Location: PrnUtils.pas
This is a backwards compatible wrapper function for code that was written for earlier versions of our products. We now encourage you to use the newer FreeAbortDialog() function where possible. The documentation for this function is the same as the FreeAbortDialog() function.
Back to Functions and Structures
procedure PrinterAbortDialogSetCaption(AbortDialog : TPrinterAbortDialog; ACaption : TCaption); stdcall;
Location: PrnUtils.pas
This is a backwards compatible wrapper function for code that was written for earlier versions of our products. We now encourage you to use the newer AbortDialogSetCaption() function where possible. The documentation for this function is the same as the AbortDialogSetCaption() function.
Back to Functions and Structures
function PrinterAbortDialogAborted(AbortDialog : TPrinterAbortDialog) : BOOL; stdcall;
Location: PrnUtils.pas
This is a backwards compatible wrapper function for code that was written for earlier versions of our products. We now encourage you to use the newer AbortDialogUserHasCanceled() function where possible. The documentation for this function is the same as the AbortDialogUserHasCanceled() function.
Back to Functions and Structures