Print license

From ISXKB

(Difference between revisions)
Jump to: navigation, search

Markus (Talk | contribs)
(Taken from the code newsgroup)
Newer edit →

Revision as of 13:40, 2 March 2009

This is a copy of Sandor Hincs' post to the Inno Setup code newsgroup.

//
// By Sandor Hincs
//
[Setup]
AppName=PrintLic2009
AppVerName=PrintLic2009
DefaultDirName={pf}\PrintLic2009
DisableStartupPrompt=true
Uninstallable=false
DisableDirPage=true
OutputBaseFilename=PrintLic2009
CreateAppDir=false
DisableProgramGroupPage=true
LicenseFile=License.rtf

[Code]
type
  HGLOBAL = THandle;
  HDC = DWORD;
  HINST = THandle;
  LPARAM = Longint;

  TDocInfo = record
    cbSize: Integer;
    lpszDocName: PChar;
    lpszOutput: PChar;
    lpszDatatype: PChar;
    fwType: DWORD;
  end;

  TPrintDlg = record
    lStructSize: DWORD;
    hWndOwner: HWND;
    hDevMode: HGLOBAL;
    hDevNames: HGLOBAL;
    hDC: HDC;
    Flags: DWORD;
    nFromPage: Word;
    nToPage: Word;
    nMinPage: Word;
    nMaxPage: Word;
    nCopies: Word;
    hInstance: HINST;
    lCustData: LPARAM;
    lpfnPrintHook: DWORD;
    lpfnSetupHook: DWORD;
    lpPrintTemplateName: PChar;
    lpSetupTemplateName: PChar;
    hPrintTemplate: HGLOBAL;
    hSetupTemplate: HGLOBAL;
  end;

  TCharRange = record
    cpMin: Longint;
    cpMax: LongInt;
  end;

  TFormatRange = record
    hdc: HDC;
    hdcTarget: HDC;
    rc: TRect;
    rcPage: TRect;
    chrg: TCharRange;
  end;

const
  PD_NOSELECTION = $00000004;
  PD_NOPAGENUMS = $00000008;
  PD_RETURNDC = $00000100;
  PD_RETURNDEFAULT = $00000400;
  PD_USEDEVMODECOPIESANDCOLLATE = $00040000;

  HORZRES       = 8;     // Horizontal width in pixels
  VERTRES       = 10;    // Vertical height in pixels
  LOGPIXELSX    = 88;    // Logical pixelsinch in X
  LOGPIXELSY    = 90;    // Logical pixelsinch in Y
  PHYSICALWIDTH   = 110; // Physical Width in device units
  PHYSICALHEIGHT  = 111; // Physical Height in device units
  PHYSICALOFFSETX = 112; // Physical Printable Area x margin
  PHYSICALOFFSETY = 113; // Physical Printable Area y margin

  EM_SETSEL = 177;
  EM_EXGETSEL = 1076;
  EM_FORMATRANGE = 1081;

function GetDeviceCaps(DC: HDC; Index: Integer): Integer;
external 'GetDeviceCaps@gdi32.dll stdcall';

function PrintDlg(var pd: TPrintDlg): Boolean;
external 'PrintDlgA@comdlg32.dll stdcall';

function DeleteDC(DC: HDC): Boolean;
external 'DeleteDC@gdi32.dll stdcall';

function StartDoc(DC: HDC; const p2: TDocInfo): Integer;
external 'StartDocA@gdi32.dll stdcall';

function StartPage(DC: HDC): Integer;
external 'StartPage@gdi32.dll stdcall';

function EndPage(DC: HDC): Integer;
external 'EndPage@gdi32.dll stdcall';

function EndDoc(DC: HDC): Integer;
external 'EndDoc@gdi32.dll stdcall';

function AbortDoc(DC: HDC): Integer;
external 'AbortDoc@gdi32.dll stdcall';

function SendMsgCharRange(const Wnd: HWND; const Msg, WParam: Longint;var
cr: TCharRange ): Longint;
external 'SendMessageA@user32.dll stdcall';

function SendMsgFormatRange(const Wnd: HWND; const Msg, WParam: Longint;var
fr: TFormatRange ): Longint;
external 'SendMessageA@user32.dll stdcall';

function SelectPrinter(var pd: TPrintDlg): boolean;
begin
  pd.lStructSize:=sizeof(pd);
  pd.hWndOwner:=WizardForm.Handle;
  pd.hDevMode:=0;
  pd.hDevNames:=0;
  pd.hDC:=0;
  pd.Flags:=PD_RETURNDC or PD_USEDEVMODECOPIESANDCOLLATE or PD_NOSELECTION;
  pd.nFromPage:=0;
  pd.nToPage:=0;
  pd.nMinPage:=0;
  pd.nMaxPage:=0;
  pd.nCopies:=0;
  pd.hInstance:=0;
  pd.lCustData:=0;
  pd.lpfnPrintHook:=0;
  pd.lpfnSetupHook:=0;
  pd.lpPrintTemplateName:='';
  pd.lpSetupTemplateName:='';
  pd.hPrintTemplate:=0;
  pd.hSetupTemplate:=0;
  Result:=PrintDlg(pd);
end;

function PrintRichEdit(const pd: TPrintDlg; const RichEdit: TRichEditViewer;
const DocName: String;LeftMargin,TopMargin,RightMargin,BottomMargin:
Double): boolean;
var
  di: TDocInfo;
  fr: TFormatRange;
  hPrDC: HDC;
  hReWnd: THandle;
  i: integer;
  nHorzRes,nVertRes,nLogPixelsX,nLogPixelsY: integer;
  nPhysWidth,nPhysHeight,nPhysOffsetX,nPhysOffsetY: integer;
  cpMin: integer;

begin
  hPrDC:=pd.hDC;
  hReWnd:=RichEdit.Handle;

  di.cbSize:=SizeOf(di);
  di.lpszDocName:=PChar(DocName);
  di.lpszOutput:='';
  di.lpszDatatype:='';
  di.fwType:=0;
  if StartDoc(hPrDC,di)<=0 then Exit;

  nLogPixelsX := GetDeviceCaps(hPrDC, LOGPIXELSX);
  nLogPixelsY := GetDeviceCaps(hPrDC, LOGPIXELSY);

  nHorzRes:= GetDeviceCaps(hPrDC, HORZRES)*1440 div nLogPixelsX;
  nVertRes:= GetDeviceCaps(hPrDC, VERTRES)*1440 div nLogPixelsY;
  nPhysWidth:= GetDeviceCaps(hPrDC, PHYSICALWIDTH)*1440 div nLogPixelsX;
  nPhysHeight:= GetDeviceCaps(hPrDC, PHYSICALHEIGHT)*1440 div nLogPixelsY;

  nPhysOffsetX:= GetDeviceCaps(hPrDC, PHYSICALOFFSETX)*1440 div nLogPixelsX;
  nPhysOffsetY:= GetDeviceCaps(hPrDC, PHYSICALOFFSETY)*1440 div nLogPixelsY;

  i:=Round(LeftMargin*1440)-nPhysOffsetX;
  if i<0 then
    i:=0;
  fr.rc.Left:=i;

  i:=Round(TopMargin*1440)-nPhysOffsetY;
  if i<0 then
    i:=0;
  fr.rc.Top:=i;

  i:=nPhysWidth-Round(RightMargin*1440)-nPhysOffsetX;
  if i>nHorzRes then
    i:=nHorzRes;
  fr.rc.Right:=i;

  i:=nPhysHeight-Round(BottomMargin*1440)-nPhysOffsetY;
  if i>nVertRes then
    i:=nVertRes;
  fr.rc.Bottom:=i;

  fr.rcPage:=fr.rc;

  fr.hDC:=hPrDC;
  fr.hdcTarget:=hPrDC;

  // Select the entire contents.
  SendMessage(hReWnd, EM_SETSEL, 0, -1);
  // Get the selection into a CHARRANGE.
  SendMsgCharRange(hReWnd, EM_EXGETSEL, 0, fr.chrg);

  Result:=true;

  // Use GDI to print successive pages.
  while (fr.chrg.cpMin < fr.chrg.cpMax) and Result do begin
    Result := (StartPage(hPrDc) > 0);
    if (not Result) then break;
    cpMin:= SendMsgFormatRange(hReWnd, EM_FORMATRANGE, -1, fr);
    if (cpMin <= fr.chrg.cpMin) then begin
      Result := false;
      break;
    end
    else begin
      fr.chrg.cpMin := cpMin;
      Result := EndPage(hPrDC) > 0;
    end;
  end;
  SendMessage(hReWnd, EM_FORMATRANGE, 0, 0);
  if (Result) then
    EndDoc(hPrDC)
  else
    AbortDoc(hPrDC);
end;

// Print license
procedure PrintButtonClick(Sender: TObject);
var
  pd: TPrintDlg;

begin
  if not SelectPrinter(pd) then Exit;
  try
    PrintRichEdit(pd,WizardForm.LicenseMemo,'License',0.5,0.5,0.5,0.5);
  finally
    DeleteDC(pd.hDC);
  end;
end;

procedure InitializeWizard();
var
     PrintButton: TButton;
begin
     PrintButton := TButton.Create(WizardForm.LicensePage);
     PrintButton.Caption := '&Print';
     PrintButton.Left := WizardForm.LicenseMemo.Left +
                         WizardForm.LicenseMemo.Width -
                         PrintButton.Width;
     PrintButton.Top := WizardForm.LicenseMemo.Top +
                        WizardForm.LicenseMemo.Height + 16;
     PrintButton.OnClick := @PrintButtonClick;
     PrintButton.Parent := WizardForm.LicenseAcceptedRadio.Parent;
end;


See also

Personal tools
Ads: