410 lines
13 KiB
ObjectPascal
410 lines
13 KiB
ObjectPascal
unit KOLPageSetupDialog;
|
|
{* Page setup dialog.
|
|
|<br>
|
|
Ver 1.4
|
|
|<br>
|
|
Now the information about selected printer can be transferred to TKOLPrinter.
|
|
If DC is needed directly use new psdReturnDC option.
|
|
|<br>
|
|
Note :page setup dialog replace print dialog marked as obsolete by Microsoft.
|
|
|<br> Bad news is that this dialog do not return printer DC. In TKOLPageSetupDialog
|
|
DC is constructed from returned values, but margins should be processed by application.
|
|
(or assigned to TKOLPrinter ;-) 17-09-2002 B.Brandys)
|
|
|<br>
|
|
Note:
|
|
|<br>
|
|
- when custom page is selected ,DC is empty (bug?)
|
|
|<br>
|
|
- application must process margins (but it is simple as AssignMargins to TKOlPrinter ;-)
|
|
|
|
}
|
|
|
|
interface
|
|
|
|
uses Windows, Messages, KOL, KOLPrintCommon;
|
|
|
|
|
|
const
|
|
|
|
DN_DEFAULTPRN = $0001; {default printer }
|
|
HELPMSGSTRING = 'commdlg_help';
|
|
|
|
//******************************************************************************
|
|
// PageSetupDlg options
|
|
//******************************************************************************
|
|
|
|
PSD_DEFAULTMINMARGINS = $00000000;
|
|
PSD_INWININIINTLMEASURE = $00000000;
|
|
PSD_MINMARGINS = $00000001;
|
|
PSD_MARGINS = $00000002;
|
|
PSD_INTHOUSANDTHSOFINCHES = $00000004;
|
|
PSD_INHUNDREDTHSOFMILLIMETERS = $00000008;
|
|
PSD_DISABLEMARGINS = $00000010;
|
|
PSD_DISABLEPRINTER = $00000020;
|
|
PSD_NOWARNING = $00000080;
|
|
PSD_DISABLEORIENTATION = $00000100;
|
|
PSD_RETURNDEFAULT = $00000400;
|
|
PSD_DISABLEPAPER = $00000200;
|
|
PSD_SHOWHELP = $00000800;
|
|
PSD_ENABLEPAGESETUPHOOK = $00002000;
|
|
PSD_ENABLEPAGESETUPTEMPLATE = $00008000;
|
|
PSD_ENABLEPAGESETUPTEMPLATEHANDLE = $00020000;
|
|
PSD_ENABLEPAGEPAINTHOOK = $00040000;
|
|
PSD_DISABLEPAGEPAINTING = $00080000;
|
|
PSD_NONETWORKBUTTON = $00200000;
|
|
|
|
//******************************************************************************
|
|
// Error constants
|
|
//******************************************************************************
|
|
|
|
|
|
CDERR_DIALOGFAILURE = $FFFF;
|
|
CDERR_GENERALCODES = $0000;
|
|
CDERR_STRUCTSIZE = $0001;
|
|
CDERR_INITIALIZATION = $0002;
|
|
CDERR_NOTEMPLATE = $0003;
|
|
CDERR_NOHINSTANCE = $0004;
|
|
CDERR_LOADSTRFAILURE = $0005;
|
|
CDERR_FINDRESFAILURE = $0006;
|
|
CDERR_LOADRESFAILURE = $0007;
|
|
CDERR_LOCKRESFAILURE = $0008;
|
|
CDERR_MEMALLOCFAILURE = $0009;
|
|
CDERR_MEMLOCKFAILURE = $000A;
|
|
CDERR_NOHOOK = $000B;
|
|
CDERR_REGISTERMSGFAIL = $000C;
|
|
PDERR_PRINTERCODES = $1000;
|
|
PDERR_SETUPFAILURE = $1001;
|
|
PDERR_PARSEFAILURE = $1002;
|
|
PDERR_RETDEFFAILURE = $1003;
|
|
PDERR_LOADDRVFAILURE = $1004;
|
|
PDERR_GETDEVMODEFAIL = $1005;
|
|
PDERR_INITFAILURE = $1006;
|
|
PDERR_NODEVICES = $1007;
|
|
PDERR_NODEFAULTPRN = $1008;
|
|
PDERR_DNDMMISMATCH = $1009;
|
|
PDERR_CREATEICFAILURE = $100A;
|
|
PDERR_PRINTERNOTFOUND = $100B;
|
|
PDERR_DEFAULTDIFFERENT = $100C;
|
|
|
|
|
|
type
|
|
|
|
|
|
|
|
{ Structure for PageSetupDlg function }
|
|
PtagPSD = ^tagPSD;
|
|
tagPSD = packed record
|
|
{* Structure for PageSetupDlg function }
|
|
lStructSize: DWORD;
|
|
hwndOwner: HWND;
|
|
hDevMode: HGLOBAL;
|
|
hDevNames: HGLOBAL;
|
|
Flags: DWORD;
|
|
ptPaperSize: TPoint;
|
|
rtMinMargin: TRect;
|
|
rtMargin: TRect;
|
|
hInstance: HINST;
|
|
lCustData: LPARAM;
|
|
lpfnPageSetupHook: function(Wnd: HWND; Message: UINT; wParam: WPARAM; lParam: LPARAM): UINT stdcall;
|
|
lpfnPagePaintHook: function(Wnd: HWND; Message: UINT; wParam: WPARAM; lParam: LPARAM): UINT stdcall;
|
|
lpPageSetupTemplateName: PAnsiChar;
|
|
hPageSetupTemplate: HGLOBAL;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function PageSetupDlg(var PgSetupDialog: tagPSD): BOOL; stdcall;external 'comdlg32.dll'
|
|
name {$IFDEF UNICODE_CTRLS} 'PageSetupDlgW' {$ELSE} 'PageSetupDlgA' {$ENDIF};
|
|
|
|
function CommDlgExtendedError():DWORD;stdcall; external 'comdlg32.dll'
|
|
name 'CommDlgExtendedError';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////
|
|
// //
|
|
// Page setup dialog. //
|
|
// //
|
|
//////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
type
|
|
TPageSetupOption = (psdMargins,psdOrientation,psdSamplePage,psdPaperControl,psdPrinterControl,
|
|
psdHundredthsOfMillimeters,psdThousandthsOfInches,psdUseMargins,psdUseMinMargins,psdWarning,psdHelp,psdReturnDC);
|
|
TPageSetupOptions = Set of TPageSetupOption;
|
|
{* Options:
|
|
|<br>
|
|
|<ul><li><b>psdMargins</b> : allow user to select margins </li>
|
|
|<li><b>psdOrientation</b> : allow user to select page orientation</li>
|
|
|<li><b>psdSamplePage</b> : draw contents of the sample page</li>
|
|
|<li><b>psdPaperControl</b> : allow paper size control </li>
|
|
|<li><b>psdPrinterControl</b> : allow user to select printer </li>
|
|
|<li><b>psdHundredthsOfMillimeters</b> : set scale to hundredths of millimeters for margins and paper size,on return indicate selected scale</li>
|
|
|<li><b>psdThousandthsOfInches</b> : set scale to thousandths of inches for margins and paper size,on return indicate selected scale</li>
|
|
|<li><b>psdUseMargins,psdUseMinMargins</b> : use suggested margins </li>
|
|
|<li><b>psdWarning</b> : generate warning when there is no default printer </li>
|
|
|<li><b>psdHelp</b> : add help button to dialog, application must process HELPMSGSTRING message</li>
|
|
|<li><b>psdReturnDC</b> : returns DC of selected printer if required </li>
|
|
|</ul>
|
|
}
|
|
|
|
PPageSetupDlg = ^TPageSetupDlg;
|
|
TKOLPageSetupDialog = PPageSetupDlg;
|
|
TPageSetupDlg = object(TObj)
|
|
{*}
|
|
private
|
|
{ Private declarations }
|
|
fhDC : HDC;
|
|
fAdvanced : WORD;
|
|
ftagPSD : tagPSD;
|
|
fOptions : TPageSetupOptions;
|
|
fDevNames : PDevNames;
|
|
PrinterInfo : TPrinterInfo;
|
|
protected
|
|
function GetError : Integer;
|
|
{*}
|
|
{ Protected declarations }
|
|
public
|
|
{ Public declarations }
|
|
destructor Destroy; virtual;
|
|
property Error : Integer read GetError;
|
|
{* Returns extended error (which is not the same as error returned from GetLastError)
|
|
|<br>
|
|
Note : if You want error descriptions each error is defined in this file source
|
|
}
|
|
function GetPaperSize : TPoint;
|
|
{*}
|
|
procedure SetMinMargins(Left,Top,Right,Bottom: Integer);
|
|
{*}
|
|
function GetMinMargins : TRect;
|
|
{*}
|
|
procedure SetMargins(Left,Top,Right,Bottom : Integer);
|
|
{*}
|
|
function GetMargins : TRect;
|
|
{*}
|
|
property Options : TPageSetupOptions read fOptions write fOptions;
|
|
{* Set of dialog options}
|
|
property DC : hDC read fhDC;
|
|
{*}
|
|
function Execute : Boolean;
|
|
{*}
|
|
function Info : PPrinterInfo;
|
|
{* Return info about selected printer.Can be used by TKOLPrinter}
|
|
{These below are usefull in Advanced mode }
|
|
property tagPSD : tagPSD read ftagPSD write ftagPSD;
|
|
{* For low-level access}
|
|
property Advanced : WORD read fAdvanced write fAdvanced;
|
|
{* 0 := default
|
|
|<br>
|
|
1 := You must assign properties to tagPSD.Flags by yourself
|
|
|<br>
|
|
2 := You can create DEVNAMES and DEVMODE structures and assign to object tagPSD
|
|
(but also You must free previous tagPSD.hDevMode and tagPSD.hDevNames)
|
|
}
|
|
procedure FillOptions(DlgOptions : TPageSetupOptions);
|
|
{* }
|
|
procedure Prepare;
|
|
{* Destroy of previous allocated DEVMODE , DEVNAMES and DC. Is always invoked on destroy and in Execute method (when Advanced :=0 of course).}
|
|
end;
|
|
|
|
function NewPageSetupDialog(AOwner : PControl; Options : TPageSetupOptions) : PPageSetupDlg;
|
|
{* Global function for page setup dialog}
|
|
|
|
implementation
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////
|
|
// //
|
|
// Page setup dialog (implementation) //
|
|
// //
|
|
//////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
function NewPageSetupDialog(AOwner : PControl; Options : TPageSetupOptions) : PPageSetupDlg;
|
|
begin
|
|
New(Result,Create);
|
|
FillChar(Result.ftagPSD,sizeof(tagPSD),0);
|
|
Result.ftagPSD.hWndOwner := AOwner.GetWindowHandle;
|
|
Result.ftagPSD.hInstance := hInstance;
|
|
Result.fOptions := Options;
|
|
Result.fAdvanced :=0;
|
|
Result.fhDC := 0;
|
|
end;
|
|
|
|
|
|
destructor TPageSetupDlg.Destroy;
|
|
begin
|
|
Prepare;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TPageSetupDlg.Prepare;
|
|
begin
|
|
if ftagPSD.hDevMode <> 0 then
|
|
begin
|
|
GlobalUnlock(ftagPSD.hDevMode);
|
|
GlobalFree(ftagPSD.hDevMode);
|
|
ftagPSD.hDevMode :=0;
|
|
end;
|
|
if ftagPSD.hDevNames <> 0 then
|
|
begin
|
|
GlobalUnlock(ftagPSD.hDevNames);
|
|
GlobalFree(ftagPSD.hDevNames);
|
|
ftagPSD.hDevNames :=0;
|
|
end;
|
|
if fhDC <> 0 then
|
|
begin
|
|
DeleteDC(fhDC);
|
|
fhDC :=0;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TPageSetupDlg.FillOptions(DlgOptions : TPageSetupOptions);
|
|
begin
|
|
ftagPSD.Flags := PSD_DEFAULTMINMARGINS;
|
|
{ Disable some parts of PageSetup window }
|
|
if not (psdMargins in DlgOptions) then Inc(ftagPSD.Flags, PSD_DISABLEMARGINS);
|
|
if not (psdOrientation in DlgOptions) then Inc(ftagPSD.Flags, PSD_DISABLEORIENTATION);
|
|
if not (psdSamplePage in DlgOptions) then Inc(ftagPSD.Flags, PSD_DISABLEPAGEPAINTING);
|
|
if not (psdPaperControl in DlgOptions) then Inc(ftagPSD.Flags,PSD_DISABLEPAPER);
|
|
if not (psdPrinterControl in DlgOptions) then inc(ftagPSD.Flags,PSD_DISABLEPRINTER);
|
|
{ Process HELPMSGSTRING message. Note : AOwner control must register and
|
|
process this message.}
|
|
if psdHelp in DlgOptions then Inc(ftagPSD.Flags, PSD_SHOWHELP);
|
|
{ Disable warning if there is no default printer }
|
|
if not (psdWarning in DlgOptions) then Inc(ftagPSD.Flags, PSD_NOWARNING);
|
|
if psdHundredthsOfMillimeters in DlgOptions then Inc(ftagPSD.Flags,PSD_INHUNDREDTHSOFMILLIMETERS);
|
|
if psdThousandthsOfInches in DlgOptions then Inc(ftagPSD.Flags,PSD_INTHOUSANDTHSOFINCHES);
|
|
if psdUseMargins in Dlgoptions then Inc(ftagPSD.Flags,PSD_MARGINS);
|
|
if psdUseMinMargins in DlgOptions then Inc(ftagPSD.Flags,PSD_MINMARGINS);
|
|
|
|
end;
|
|
|
|
function TPageSetupDlg.GetError : Integer;
|
|
begin
|
|
Result := CommDlgExtendedError();
|
|
end;
|
|
|
|
function TPageSetupDlg.Execute : Boolean;
|
|
var
|
|
ExitCode : Boolean;
|
|
Device,Driver,Output : PChar;
|
|
fDevMode : PDevMode;
|
|
begin
|
|
case fAdvanced of
|
|
0 : //Not in advanced mode
|
|
begin
|
|
Prepare;
|
|
FillOptions(fOptions);
|
|
end;
|
|
1:Prepare; //Advanced mode . User must assign properties and/or hook procedures
|
|
end; //If Advanced > 1 then You are expert ! (better use pure API ;-))
|
|
ftagPSD.lStructSize := sizeof(tagPSD);
|
|
ExitCode := PageSetupDlg(ftagPSD);
|
|
if (ftagPSD.Flags and PSD_INHUNDREDTHSOFMILLIMETERS) <> 0 then
|
|
fOptions := fOptions + [psdHundredthsOfMillimeters]
|
|
else
|
|
fOptions := fOptions - [psdHundredthsOfMillimeters];
|
|
|
|
if (ftagPSD.Flags and PSD_INTHOUSANDTHSOFINCHES) <> 0 then
|
|
fOptions := fOptions + [psdThousandthsOfInches]
|
|
else
|
|
fOptions := fOptions - [psdThousandthsOfInches];
|
|
fDevNames := PDevNames(GlobalLock(ftagPSD.hDevNames));
|
|
fDevMode := PDevMode(GlobalLock(ftagPSD.hDevMode));
|
|
if fDevNames <> nil then //support situation when user pressed cancel button
|
|
begin
|
|
Driver := PChar(fDevNames) + fDevNames^.wDriverOffset;
|
|
Device := PChar(fDevNames) + fDevNames^.wDeviceOffset;
|
|
Output := PChar(fDevNames) + fDevNames^.wOutputOffset;
|
|
if psdReturnDC in fOptions then fhDC := CreateDC(Driver,Device,Output,fDevMode);
|
|
end;
|
|
Result := ExitCode;
|
|
end;
|
|
|
|
function TPageSetupDlg.Info : PPrinterInfo;
|
|
begin
|
|
try
|
|
FillChar(PrinterInfo,sizeof(PrinterInfo),0);
|
|
with PrinterInfo do
|
|
begin
|
|
if fDevNames <> nil then
|
|
begin
|
|
ADriver := PChar(fDevNames) + fDevNames^.wDriverOffset;
|
|
ADevice := PChar(fDevNames) + fDevNames^.wDeviceOffset;
|
|
APort := PChar(fDevNames) + fDevNames^.wOutputOffset;
|
|
end;
|
|
ADevMode := ftagPSD.hDevMode;
|
|
end;
|
|
finally // support fDevNames=0 (user pressed Cancel)
|
|
Result := @PrinterInfo;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
function TPageSetupDlg.GetPaperSize : TPoint;
|
|
begin
|
|
Result := ftagPSD.ptPaperSize;
|
|
end;
|
|
|
|
procedure TPageSetupDlg.SetMinMargins(Left,Top,Right,Bottom: Integer);
|
|
begin
|
|
ftagPSD.rtMinMargin.Left := Left;
|
|
ftagPSD.rtMinMargin.Top := Top;
|
|
ftagPSD.rtMinMargin.Right := Right;
|
|
ftagPSD.rtMinMargin.Bottom := Bottom;
|
|
end;
|
|
|
|
function TPageSetupDlg.GetMinMargins : TRect;
|
|
begin
|
|
Result := ftagPSD.rtMinMargin;
|
|
end;
|
|
|
|
procedure TPageSetupDlg.SetMargins(Left,Top,Right,Bottom : Integer);
|
|
begin
|
|
ftagPSD.rtMargin.Left := Left;
|
|
ftagPSD.rtMargin.Top := Top;
|
|
ftagPSD.rtMargin.Right := Right;
|
|
ftagPSD.rtMargin.Bottom := Bottom;
|
|
end;
|
|
|
|
function TPageSetupDlg.GetMargins : TRect;
|
|
begin
|
|
Result := ftagPSD.rtMargin;
|
|
end;
|
|
|
|
|
|
|
|
begin
|
|
end.
|