home *** CD-ROM | disk | FTP | other *** search
- {$V-,F+}
- {tPrinter unit subclasses by D.Overmyer to directly support
- margins, headers, footer, change printer dialog and changing fonts}
- UNIT Printer1;
- (***********************************************************)
- INTERFACE
- (***********************************************************)
- USES WObjects,WinTypes,WinProcs,Strings,WinDos,Printer;
- const
- pm_NoPrint = 0;
- pm_PrintText = 1;
- pm_PrintFooter = 2;
-
- type
- PPrinter1 = ^TPrinter1;
- TPrinter1 = object(tPrinter)
- Margin:TRect; {Rect struct for left,top,right,bottom values in pixels}
- CurFont:hFont; {Current printing font}
- PageNumber:Integer;{Current page number}
- FooterY:Integer; {Height of footer}
- PrtMode:Integer; {modal flag - set to pm_xxxxxxxxx constants}
-
- constructor Init(inst: tHandle;par: pWindowsObject);
- Function Start(dName: pChar;hw: hWnd): Boolean; virtual;
- Function Print(aStr: pChar): Boolean; virtual;
- Function PrintString(aStr: pChar): Boolean; virtual;
- Function NewLine: Boolean; virtual;
- Function CheckNewPage: Boolean; virtual;
- Function NewPage: Boolean; virtual;
- Function ResetPos: Boolean; virtual;
- Function DoNewFrame: Boolean; virtual;
- Function LineWidth(aStr: pChar): Integer; virtual;
- procedure SetMarginL(NewMargin:Integer);virtual;
- procedure SetMarginT(NewMargin:Integer);virtual;
- procedure SetMarginR(NewMargin:Integer);virtual;
- procedure SetMarginB(NewMargin:Integer);virtual;
- function SetMargin(NewMargin:TRect):Boolean;virtual;
- function GetMargin(var CurMargin:TRect):Boolean;virtual;
- function SetFont(NewFont:hFont):hFont;virtual;
- function DoHeader:Boolean;virtual;
- procedure ChgPrinter;virtual;
- function CalcFooterY:Integer;virtual;
- function DoFooter:Boolean;virtual;
- function SetupPage:Boolean;virtual;
- function GetQuickDC:hDC;virtual;
- function DeleteQuickDC:Boolean;virtual;
- function prnDeviceMode(wnd: hWnd):Integer; virtual;
- End;
-
- tGetDevMode = function(hWindow: hWnd; dHan: tHandle; devName,output: pChar): Boolean;
- tGetExtDevMode = function(hWIndow: hWnd;
- dHan: tHandle;
- outMode: tDevMode;
- devName: pChar;
- outPut: pChar;
- inMode: tDevMode;
- profile: pChar;
- pMode: word): Boolean;
- tMode= tDeviceMode;
-
- (***********************************************************)
- IMPLEMENTATION
- (***********************************************************)
- {$R Printer1.RES}
- var
- userAbort: Boolean;
- PrintDialog: pPrnDialog;
- const
- id_PrtD1OK = 1102;
- id_PrtD1LB1 = 1101;
- type
- PPRTDlg1 = ^TPRTDlg1;
- TPRTDlg1 = object(TDialog)
- szAllDevices:Array[0..4096] of Char;
- procedure WMInitDialog(var Msg:TMessage);virtual wm_First+wm_InitDialog;
- procedure IDPRTD1OK(var Msg:TMessage);virtual id_First+id_PrtD1OK;
- end;
-
- (***********************************************************)
-
- Constructor TPrinter1.Init(inst: tHandle; par: pWindowsObject);
- Begin
- TPrinter.Init(Inst,Par);
- PageNumber := 1;
- PrtMode := pm_PrintText;
- FooterY := 0;
- hPrintDC := 0; {init the device conText to 0}
- End;
-
- Function TPrinter1.Start;
- var
- ap: tPoint;
- Begin
- Margin.Left := 0;
- Margin.Top := 0;
- Margin.Right := 0;
- Margin.Bottom := 0;
- hWindow := Hw; {save the parent window. Seemed like a good idea}
- hPrintDC := 0; {init the device conText to 0}
- GlobalCompact(0); {compacts global memory}
- if (getPrinterParms and DCcreated) then
- begin
- docName := dName;
- getTextMetrics(hPrintDC,Metrics);
- PageSize(ap);
- MaxX := ap.x-1;
- MaxY := ap.y-1;
- start := CheckStart;
- end
- else
- start := false;
- CurFont := GetStockObject(Device_Default_Font);
- End;
-
-
- Function TPrinter1.lineWidth(aStr: pChar): Integer;
- var
- Res:LongInt;
- Begin
- if (aStr <> nil) then
- begin
- res := (GetTextExtent(hPrintDC,aStr,strLen(aStr)));
- lineWidth := LongRec(res).lo;
- end
- else
- LineWidth := 0;
- End;
-
- function TPrinter1.Print(aStr:PChar):Boolean;
- var
- Extent:Integer;
- begin
- Extent := lineWidth(aStr);
- if PrintString(aStr) then
- begin
- PosX := PosX + Extent;
- Print := True;
- end
- else
- Print := False;
- end;
-
- function TPrinter1.PrintString(aStr:pChar):Boolean;
- begin
- if OKPrint then
- begin
- if(PrtMode <> pm_NoPrint) then
- PrintString := TextOut(hPrintDC,PosX,PosY,aStr,strLen(aStr))
- end
- else
- PrintString := False;
- end;
-
-
- function TPrinter1.NewLine:Boolean;
- Begin
- PosX := Margin.Left;
- PosY := PosY + Height;
- CheckNewPage;
- end;
-
- function TPrinter1.CheckNewPage:Boolean;
- begin
- if PrtMode = pm_PrintText then
- if (PosY + Margin.Bottom + 2*Height + FooterY > MaxY ) then
- begin
- PrtMode := pm_PrintFooter;
- DoFooter;
- PrtMode := pm_PrintText;
- NewPage;
- end;
- end;
-
-
- function TPrinter1.NewPage:Boolean;
- begin
- if OkToPrint then
- begin
- ResetPos;
- DoNewFrame;
- Inc(PageNumber);
- SetupPage;
- end;
- end;
-
- function TPrinter1.SetupPage:Boolean;
- begin
- ResetPos;
- CalcFooterY;
- DoHeader;
- end;
-
- function TPrinter1.ResetPos:Boolean;
- Begin
- PosX := Margin.Left;
- PosY := Margin.Top;
- end;
-
-
- Function TPrinter1.DoNewFrame: Boolean;
- Begin
- if OkPrint then
- begin
- DoNewFrame := TPrinter.DoNewFrame;
- SelectObject(hPrintDC,CurFont);
- end;
- End;
-
- function TPrinter1.DoHeader:Boolean;
- begin
- {formal method - override in instance variable}
- end;
-
- function TPrinter1.DoFooter:Boolean;
- begin
- {Formal Method - override in instance variable}
- end;
-
- function TPrinter1.CalcFooterY:Integer; {Estimate footer height in pixels}
- {Can be called between print lines with care!}
- var
- OldX,OldY:Integer;
- OldPM:Integer;
- OldFont:hFont;
- begin
- OldFont := SetFont(CurFont);
- OldX := PosX;
- OldY := PosY;
- OldPM := PrtMode;
- PrtMode := pm_NoPrint;
- DoFooter;
- FooterY := PosY - OldY;
- PosX := OldX;
- PosY := OldY;
- SetFont(OldFont);
- PrtMode := OldPM;
- CalcFooterY := FooterY;
- end;
-
- procedure TPrinter1.SetMarginL(NewMargin:Integer);
- begin
- Margin.Left := NewMargin;
- end;
-
- procedure TPrinter1.SetMarginT(NewMargin:Integer);
- begin
- Margin.Top := NewMargin;
- end;
-
- procedure TPrinter1.SetMarginR(NewMargin:Integer);
- begin
- Margin.Right := NewMargin;
- end;
-
- procedure TPrinter1.SetMarginB(NewMargin:Integer);
- begin
- Margin.Bottom := NewMargin;
- end;
-
- function TPrinter1.SetMargin(NewMargin:TRect):Boolean;
- begin
- Margin := NewMargin;
- SetMargin := True;
- end;
-
- function TPrinter1.GetMargin(var CurMargin:TRect):Boolean;
- begin
- CurMargin := Margin;
- end;
-
- function TPrinter1.SetFont(NewFont:hFont):hFont;
- var
- MM:Integer;
- LogFont:TLogFont;
- begin
- SetFont := SelectObject(hPrintDC,NewFont);
- CurFont := NewFont;
- getTextMetrics(hPrintDC,Metrics);
- end;
-
- procedure TPrinter1.ChgPrinter;
- var
- PRTDlg1 : pPRTDlg1;
- begin
- PRTDlg1 := new(pPRTDlg1,Init(TheParent,'PRT_Dlg1'));
- Application^.ExecDialog(PRTDlg1);
- end;
-
- function TPrinter1.GetQuickDC:hDC; {This function does not fully initialized the printer object}
- begin
- if hPrintDC = 0 then
- begin
- GetPrinterParms;
- DCCreated;
- GetQuickDC := hPrintDC;
- end
- else
- GetQuickDC := 0;
- end;
-
- function TPrinter1.DeleteQuickDC:Boolean;
- begin
- DeleteContext;
- end;
-
- function TPrinter1.prnDeviceMode(Wnd:HWnd):Integer;
- var
- dHandle: tHandle; {handle of the load library for the current printer}
- drvName: pChar; {name of the driver used to get dHandle}
- pAddr: tFarProc; {address of the function in the DLL we want to EXEC}
- Begin
- if getPrinterParms then
- begin {retrieve printer info from windows}
- drvName := driver;
- strCat(drvName,'.drv'); {make a file name out of the driver}
- dHandle := LoadLibrary(drvName); {load the DLL for the printer}
- pAddr := getProcAddress(dHandle,'ExtDeviceMode');
- if (pAddr <> nil) then
- begin
- tGetExtDevMode(pAddr)(wnd,dHandle,dMode,Device,prnPort,dMode,nil,
- dm_prompt OR dm_Update);
- end
- else
- begin
- pAddr := GetProcAddress(dHandle,'DEVICEMODE');
- if (pAddr <> nil) then
- begin
- tGetDevMode(pAddr)(wnd,dHandle,drvName,prnPort);
- End;
- End;
- FreeLibrary(dHandle); {the library is freed when we are done with it}
- End;
- end;
-
- {***********************************************************************}
- procedure TPRTDlg1.WMInitDialog(var Msg:TMessage);
- var
- pAllDevices:PChar;
- Buf:Array[0..64] of Char;
- pBuf:PChar;
- szPrinter1:Array[0..64] of Char;
- szPrinter:Array[0..64] of Char;
- pPrinter:PChar;
- begin
- GetProfileString('devices',nil,'',szAllDevices,sizeof(szAllDevices));
- TDialog.WMInitDialog(Msg);
- pAllDevices := szAllDevices;
- pBuf := @Buf;
- pPrinter := @szPrinter;
- repeat
- StrCopy(Buf,pAllDevices);
- GetProfileString('devices',Buf,'',szPrinter1,sizeof(szPrinter1));
- StrCat(StrCat(StrCopy(szPrinter,Buf),','),szPrinter1);
- SendDlgItemMsg(id_PrtD1LB1,lb_AddString,word(0),LongInt(pPrinter));
- pAllDevices := pAllDevices+StrLen(pBuf)+1;
- until StrLen(pAllDevices) = 0;
- end;
-
- procedure TPRTDlg1.IDPRTD1OK(var Msg:TMessage);
- var
- Idx:Integer;
- Buf:Array[0..64] of Char;
- Ptr:PChar;
- Ptr1:PChar;
- cPos:PChar;
- ErrCode:Integer;
- szPrinter:Array[0..64] of Char;
- szDriver:Array[0..64] of Char;
- szPort:Array[0..64] of Char;
- szNewDevice:Array[0..64] of Char;
- begin
- StrCopy(Buf,'');
- Ptr := @Buf;
- Idx := SendDlgItemMsg(id_PrtD1LB1,lb_GetCurSel,0,0);
- if Idx <> lb_Err then
- SendDlgItemMsg(id_PrtD1LB1,lb_GetText,idx,Longint(Ptr));
- if StrLen(Ptr) > 0 then
- begin
- StrCopy(szNewDevice,Buf);
- WriteProfileString('Windows','device',szNewDevice);
- end;
- EndDlg(1);
- end;
-
- end.
-