{******************************************} { } { FastReport VCL } { Dot-matrix export filter } { } { Copyright (c) 1998-2021 } { by Fast Reports Inc. } { } {******************************************} unit frxDMPExport; interface {$I frx.inc} uses {$IFNDEF Linux} Windows, {$ELSE} LCLType, LCLIntf, LCLProc, {$ENDIF} Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, frxClass, Buttons, ComCtrls, frxDMPClass, frxXML {$IFDEF FPC} , LResources {$ENDIF} {$IFDEF Delphi6} , Variants {$ENDIF}; type TfrxTranslateEvent = procedure(Sender: TObject; var s: AnsiString) of object; {$IFDEF DELPHI16} /// /// The TfrxDotMatrixExport component allows reports to print on a dot-matrix /// printer. Only reports designed specificly for the DMP mode, can be /// printed. /// [ComponentPlatformsAttribute(pidWin32 or pidWin64)] {$ENDIF} TfrxDotMatrixExport = class(TfrxCustomExportFilter) private FBufWidth: Integer; FBufHeight: Integer; FCharBuf: array of AnsiChar; FCopies: Integer; FCustomFrameSet: AnsiString; FEscModel: Integer; FFrameBuf: array of Byte; FGraphicFrames: Boolean; FMaxHeight: Integer; FOEMConvert: Boolean; FPageBreaks: Boolean; FPageStyle: Integer; FPrinterInitString: AnsiString; FSaveToFile: Boolean; FStream: TStream; FStyleBuf: array of Integer; FUseIniSettings: Boolean; FOnTranslate: TfrxTranslateEvent; function GetTempFName: String; function IntToStyle(i: Integer): TfrxDMPFontStyles; function StyleChange(OldStyle, NewStyle: Integer): String; function StyleOff(Style: Integer): String; function StyleOn(Style: Integer): String; function StyleToInt(Style: TfrxDMPFontStyles): Integer; procedure CreateBuf(Width, Height: Integer); procedure DrawFrame(x, y, dx, dy: Integer; Style: Integer); procedure DrawMemo(x, y, dx, dy: Integer; Memo: TfrxDMPMemoView); procedure FlushBuf; procedure FormFeed; procedure FreeBuf; procedure Landscape; procedure Portrait; procedure Reset; procedure SetFrame(x, y: Integer; typ: Byte); procedure SetString(x, y: Integer; s: AnsiString); procedure SetStyle(x, y, Style: Integer); procedure SpoolFile(const FileName: String); procedure WriteStrLn(const str: AnsiString); procedure WriteStr(const str: AnsiString); public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function ShowModal: TModalResult; override; function Start: Boolean; override; procedure ExportObject(Obj: TfrxComponent); override; procedure Finish; override; procedure FinishPage(Page: TfrxReportPage; Index: Integer); override; procedure StartPage(Page: TfrxReportPage; Index: Integer); override; published /// /// Set of symbols used for drawing frame elements. By default this /// property is empty and frames are printed using +-| symbols or /// pseudographic symbols.
Each frame element is represented by the /// cross containing 4 lines. Each line has its own weight index:
1 ///
8
4
The CustomFrameSet property should contain 15 /// symbols. For example, symbol CustomFrameSet[1] represents line number /// 1, symbol CustomFrameSet[2] represents line number 2, symbol /// CustomFrameSet[3] represents a combination of line 1 and 2, etc. ///
property CustomFrameSet: AnsiString read FCustomFrameSet write FCustomFrameSet; property EscModel: Integer read FEscModel write FEscModel; /// /// Determines if pseudographic frames are used or not. /// property GraphicFrames: Boolean read FGraphicFrames write FGraphicFrames; /// /// The printer init string. /// property InitString: AnsiString read FPrinterInitString write FPrinterInitString; /// /// Determines whether to convert all strings to OEM character set or /// not. Default value is True. /// property OEMConvert: Boolean read FOEMConvert write FOEMConvert default True; /// /// Use page break symbol. /// property PageBreaks: Boolean read FPageBreaks write FPageBreaks default True; /// /// Determines whether to save export to file or to print it. If this /// property is True, you should also set the FileName property. /// property SaveToFile: Boolean read FSaveToFile write FSaveToFile; /// /// Store settings in the report ini-file. /// property UseIniSettings: Boolean read FUseIniSettings write FUseIniSettings; property OnTranslate: TfrxTranslateEvent read FOnTranslate write FOnTranslate; end; TfrxDMPExportDialog = class(TForm) OK: TButton; Cancel: TButton; SaveDialog1: TSaveDialog; Image1: TImage; PrinterL: TGroupBox; PrinterCB: TComboBox; EscL: TGroupBox; EscCB: TComboBox; CopiesL: TGroupBox; CopiesNL: TLabel; CopiesE: TEdit; CopiesUD: TUpDown; PagesL: TGroupBox; DescrL: TLabel; AllRB: TRadioButton; CurPageRB: TRadioButton; PageNumbersRB: TRadioButton; RangeE: TEdit; OptionsL: TGroupBox; SaveToFileCB: TCheckBox; PageBreaksCB: TCheckBox; OemCB: TCheckBox; PseudoCB: TCheckBox; procedure FormCreate(Sender: TObject); procedure PrinterCBDrawItem(Control: TWinControl; Index: Integer; ARect: TRect; State: TOwnerDrawState); procedure PrinterCBClick(Sender: TObject); procedure FormHide(Sender: TObject); procedure RangeEEnter(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); private OldIndex: Integer; end; const cmdName = 1; cmdReset = 2; cmdFormFeed = 3; cmdLandscape = 4; cmdPortrait = 5; cmdBoldOn = 6; cmdBoldOff = 7; cmdItalicOn = 8; cmdItalicOff = 9; cmdUnderlineOn = 10; cmdUnderlineOff = 11; cmdSuperscriptOn = 12; cmdSuperscriptOff = 13; cmdSubscriptOn = 14; cmdSubscriptOff = 15; cmdCondensedOn = 16; cmdCondensedOff = 17; cmdWideOn = 18; cmdWideOff = 19; cmd12cpiOn = 20; cmd12cpiOff = 21; cmd15cpiOn = 22; cmd15cpiOff = 23; CommandCount = 23; CommandNames: array[1..CommandCount] of String = ( 'Name', 'Reset', 'FormFeed', 'Landscape', 'Portrait', 'BoldOn', 'BoldOff', 'ItalicOn', 'ItalicOff', 'UnderlineOn', 'UnderlineOff', 'SuperscriptOn', 'SuperscriptOff', 'SubscriptOn', 'SubscriptOff', 'CondensedOn', 'CondensedOff', 'WideOn', 'WideOff', 'cpi12On', 'cpi12Off', 'cpi15On', 'cpi15Off'); type TfrxDMPrinter = class(TCollectionItem) public Commands: array[1..CommandCount] of String; procedure Assign(Source: TPersistent); override; end; TfrxDMPrinters = class(TCollection) private function GetItem(Index: Integer): TfrxDMPrinter; public constructor Create; function Add: TfrxDMPrinter; procedure ReadDefaultPrinters; procedure ReadExtPrinters; procedure ReadPrinters(x: TfrxXMLDocument); property Items[Index: Integer]: TfrxDMPrinter read GetItem; default; end; var frxDMPrinters: TfrxDMPrinters; implementation uses frxUtils, frxPrinter, Printers, frxRes, IniFiles{$IFNDEF FPC}, Winspool{$ENDIF}; {$R *.dfm} const FrameSet: array[1..2] of AnsiString = ( ' + |++ +-+++++', #32#32#192#32#179#218#195#32#217#196#193#191#180#194#197); DefaultPrinters: String = '' + '' + ' ' + ' ' + ' ' + ' ' + ''; type TWordSet = set of 0..15; PWordSet = ^TWordSet; PfrxDMPFontStyles = ^TfrxDMPFontStyles; { TfrxDMPrinter } procedure TfrxDMPrinter.Assign(Source: TPersistent); begin if Source is TfrxDMPrinter then Commands := TfrxDMPrinter(Source).Commands; end; { TfrxDMPrinters } constructor TfrxDMPrinters.Create; begin inherited Create(TfrxDMPrinter); end; function TfrxDMPrinters.Add: TfrxDMPrinter; begin Result := TfrxDMPrinter(inherited Add); end; function TfrxDMPrinters.GetItem(Index: Integer): TfrxDMPrinter; begin Result := TfrxDMPrinter(inherited Items[Index]); end; procedure TfrxDMPrinters.ReadDefaultPrinters; var x: TfrxXMLDocument; s: TStringStream; begin x := TfrxXMLDocument.Create; s := TStringStream.Create(DefaultPrinters{$IFDEF Delphi12}, TEncoding.UTF8{$ENDIF}); try x.LoadFromStream(s); ReadPrinters(x); finally s.Free; x.Free; end; end; procedure TfrxDMPrinters.ReadExtPrinters; var x: TfrxXMLDocument; begin if not FileExists(ExtractFilePath(Application.ExeName) + 'printers.xml') then Exit; x := TfrxXMLDocument.Create; try x.LoadFromFile(ExtractFilePath(Application.ExeName) + 'printers.xml'); ReadPrinters(x); except ShowMessage('Error in file printers.xml'); end; x.Free; end; procedure TfrxDMPrinters.ReadPrinters(x: TfrxXMLDocument); var i, j: Integer; xi: TfrxXMLItem; Item: TfrxDMPrinter; function ConvertProp(s: String): String; var i: Integer; s1: String; begin Result := ''; s1 := ''; if Pos('#', s) = 1 then begin s := s + '#'; for i := 2 to Length(s) do if s[i] = '#' then begin Result := Result + Chr(StrToInt(s1)); s1 := ''; end else s1 := s1 + s[i]; end else begin for i := 1 to Length(s) do begin s1 := s1 + s[i]; if i mod 2 = 0 then begin Result := Result + Chr(StrToInt('$' + s1)); s1 := ''; end; end; end; end; begin Clear; for i := 0 to x.Root.Count - 1 do begin Item := Add; xi := x.Root[i]; if xi.Prop['Inherit'] <> '' then Item.Assign(Items[StrToInt(xi.Prop['Inherit'])]); for j := 1 to CommandCount do if xi.PropExists(CommandNames[j]) then if j = 1 then Item.Commands[j] := xi.Prop[CommandNames[j]] else Item.Commands[j] := ConvertProp(xi.Prop[CommandNames[j]]); end; end; { TfrxDotMatrixExport } constructor TfrxDotMatrixExport.Create(AOwner: TComponent); begin inherited Create(AOwner); frxDotMatrixExport := Self; FCopies := 1; FOEMConvert := True; FPageBreaks := True; FUseIniSettings := True; end; destructor TfrxDotMatrixExport.Destroy; begin FreeBuf; frxDotMatrixExport := nil; inherited; end; function TfrxDotMatrixExport.GetTempFName: String; var Path: String; FileName: String; begin Path := Report.EngineOptions.TempDir; if Path = '' then begin Path := GetTemporaryFolder(); end else Path := Path + #0; SetLength(FileName, MAX_PATH); GetTempFileName(@Path[1], PChar('fr'), 0, @FileName[1]); {$IFDEF Delphi12} Result := StrPas(PWideChar(@FileName[1])); {$ELSE} Result := StrPas(PChar(@FileName[1])); {$ENDIF} end; function TfrxDotMatrixExport.IntToStyle(i: Integer): TfrxDMPFontStyles; begin Result := TfrxDMPFontStyles(PfrxDMPFontStyles(@i)^); end; function TfrxDotMatrixExport.StyleToInt(Style: TfrxDMPFontStyles): Integer; begin Result := Word(PWordSet(@Style)^); end; {$HINTS OFF} procedure TfrxDotMatrixExport.SpoolFile(const FileName: String); const BUF_SIZE = 1024; var f: TFileStream; buf: AnsiString; l: longint; begin if Report.ReportOptions.Name <> '' then frxPrinters.Printer.Title := Report.ReportOptions.Name else frxPrinters.Printer.Title := Report.FileName; frxPrinters.Printer.BeginRAWDoc; f := TFileStream.Create(FileName, fmOpenRead); SetLength(buf, BUF_SIZE); l := BUF_SIZE; while l = BUF_SIZE do begin l := f.Read(buf[1], BUF_SIZE); SetLength(buf, l); frxPrinters.Printer.WriteRAWDoc(buf); end; f.Free; frxPrinters.Printer.EndRAWDoc; end; {$HINTS ON} procedure TfrxDotMatrixExport.FormFeed; begin WriteStr(AnsiString(frxDMPrinters[FEscModel].Commands[cmdFormFeed])); end; procedure TfrxDotMatrixExport.Landscape; begin WriteStr(AnsiString(frxDMPrinters[FEscModel].Commands[cmdLandscape])); end; procedure TfrxDotMatrixExport.Portrait; begin WriteStr(AnsiString(frxDMPrinters[FEscModel].Commands[cmdPortrait])); end; procedure TfrxDotMatrixExport.Reset; begin WriteStr(AnsiString(frxDMPrinters[FEscModel].Commands[cmdReset])); end; function TfrxDotMatrixExport.StyleOff(Style: Integer): String; var st: TfrxDMPFontStyles; begin st := IntToStyle(Style); Result := ''; if fsxBold in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmdBoldOff]; if fsxItalic in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmdItalicOff]; if fsxUnderline in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmdUnderlineOff]; if fsxSuperScript in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmdSuperscriptOff]; if fsxSubScript in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmdSubscriptOff]; if fsxCondensed in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmdCondensedOff]; if fsxWide in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmdWideOff]; if fsx12cpi in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmd12cpiOff]; if fsx15cpi in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmd15cpiOff]; end; function TfrxDotMatrixExport.StyleOn(Style: Integer): String; var st: TfrxDMPFontStyles; begin st := IntToStyle(Style); Result := ''; if fsxBold in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmdBoldOn]; if fsxItalic in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmdItalicOn]; if fsxUnderline in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmdUnderlineOn]; if fsxSuperScript in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmdSuperscriptOn]; if fsxSubScript in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmdSubscriptOn]; if fsxCondensed in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmdCondensedOn]; if fsxWide in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmdWideOn]; if fsx12cpi in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmd12cpiOn]; if fsx15cpi in st then Result := Result + frxDMPrinters[FEscModel].Commands[cmd15cpiOn]; end; function TfrxDotMatrixExport.StyleChange(OldStyle, NewStyle: Integer): String; begin Result := StyleOff(OldStyle) + StyleOn(NewStyle); end; procedure TfrxDotMatrixExport.SetFrame(x, y: Integer; typ: Byte); begin if (x < 0) or (y < 0) or (x >= FBufWidth) or (y >= FBufHeight) then Exit; FFrameBuf[FBufWidth * y + x] := FFrameBuf[FBufWidth * y + x] or typ; end; procedure TfrxDotMatrixExport.SetString(x, y: Integer; s: AnsiString); var i, j: Integer; c: AnsiChar; begin if (x < 0) or (y < 0) or (y >= FBufHeight) then Exit; if Assigned(FOnTranslate) then FOnTranslate(Self, s); for i := 1 to Length(s) do begin if x + i - 1 >= FBufWidth then break; c := s[i]; j := FBufWidth * y + x + i - 1; FCharBuf[j] := c; end; end; procedure TfrxDotMatrixExport.SetStyle(x, y, Style: Integer); begin if (x < 0) or (y < 0) or (x >= FBufWidth) or (y >= FBufHeight) then Exit; FStyleBuf[FBufWidth * y + x] := Style; end; procedure TfrxDotMatrixExport.WriteStr(const str: AnsiString); begin if Length(str) > 0 then FStream.Write(str[1], Length(str)) end; procedure TfrxDotMatrixExport.WriteStrLn(const str: AnsiString); begin WriteStr(str); WriteStr(#13#10); end; procedure TfrxDotMatrixExport.DrawFrame(x, y, dx, dy: Integer; Style: Integer); var i, j: Integer; begin if dx = 1 then begin SetFrame(x, y, 4); for i := y + 1 to y + dy - 2 do SetFrame(x, i, 5); SetFrame(x, y + dy - 1, 1); end else begin SetFrame(x, y, 2); for i := x + 1 to x + dx - 2 do SetFrame(i, y, 10); SetFrame(x + dx - 1, y, 8); end; for i := x to x + dx - 1 do for j := y to y + dy - 1 do SetStyle(i, j, Style); if y + dy > FMaxHeight then FMaxHeight := y + dy; end; procedure TfrxDotMatrixExport.DrawMemo(x, y, dx, dy: Integer; Memo: TfrxDMPMemoView); var i, sx, sy: Integer; Lines: TStringList; Text: String; Style: Integer; function StrToOem(AnsiStr: AnsiString): AnsiString; var i: Integer; begin SetLength(Result, Length(AnsiStr)); if Length(Result) > 0 then begin for i := 1 to Length(AnsiStr) do if AnsiStr[i] = #160 then AnsiStr[i] := #32; {$IFDEF Linux} Result := AnsiStr; {$ELSE} CharToOemBuffA(PAnsiChar(AnsiStr), PAnsiChar(Result), Length(Result)); {$ENDIF} end; end; function MakeStr(C: AnsiChar; N: Integer): AnsiString; begin if N < 1 then Result := '' else begin SetLength(Result, N); FillChar(Result[1], Length(Result), C); end; end; function AddChar(C: AnsiChar; const S: AnsiString; N: Integer): AnsiString; begin if Length(S) < N then Result := MakeStr(C, N - Length(S)) + S else Result := S; end; function AddCharR(C: AnsiChar; const S: AnsiString; N: Integer): AnsiString; begin if Length(S) < N then Result := S + MakeStr(C, N - Length(S)) else Result := S; end; function LeftStr(const S: AnsiString; N: Integer): AnsiString; begin Result := AddCharR(' ', S, N); end; function RightStr(const S: AnsiString; N: Integer): AnsiString; begin Result := AddChar(' ', S, N); end; function CenterStr(const S: AnsiString; Len: Integer): AnsiString; begin if Length(S) < Len then begin Result := MakeStr(' ', (Len div 2) - (Length(S) div 2)) + S; Result := Result + MakeStr(' ', Len - Length(Result)); end else Result := S; end; function AlignBuf(const buf: AnsiString): AnsiString; begin if (Memo.HAlign = haLeft) then Result := LeftStr(buf, dx) else if (Memo.HAlign = haRight) then Result := RightStr(buf, dx) else if (Memo.HAlign = haCenter) then Result := CenterStr(buf, dx) else Result := LeftStr(buf, dx); end; begin Lines := TStringList.Create; if not Memo.WordWrap and Memo.TruncOutboundText then Text := Memo.GetoutBoundText else Text := Memo.WrapText(True); if FOEMConvert then Text := String(StrToOem(AnsiString(Text))); Lines.Text := Text; if dy > Lines.Count then begin if (Memo.VAlign = vaBottom) then sy := y + dy - Lines.Count else if (Memo.VAlign = vaCenter) then sy := y + (dy - Lines.Count) div 2 else sy := y end else sy := y; for i := 0 to Lines.Count - 1 do begin if i > dy - 1 then break; SetString(x, sy + i, AlignBuf(AnsiString(Lines[i]))); end; Lines.Free; Style := StyleToInt(Memo.FontStyle); for sx := x to x + dx - 1 do for sy := y to y + dy - 1 do SetStyle(sx, sy, Style); if y + dy > FMaxHeight then FMaxHeight := y + dy; end; procedure TfrxDotMatrixExport.CreateBuf(Width, Height: Integer); var i, j: Integer; begin FBufWidth := Width; FBufHeight := Height; SetLength(FCharBuf, FBufWidth * FBufHeight); SetLength(FStyleBuf, FBufWidth * FBufHeight); SetLength(FFrameBuf, FBufWidth * FBufHeight); for i := 0 to FBufHeight - 1 do for j := 0 to FBufWidth - 1 do begin FCharBuf[i * FBufWidth + j] := ' '; FStyleBuf[i * FBufWidth + j] := FPageStyle; FFrameBuf[i * FBufWidth + j] := 0; end; end; procedure TfrxDotMatrixExport.FreeBuf; begin FFrameBuf := nil; FStyleBuf := nil; FCharBuf := nil; FBufHeight := 0; FBufWidth := 0; end; procedure TfrxDotMatrixExport.FlushBuf; var i, j, Style, CurrentStyle: Integer; buf: AnsiString; Frames: AnsiString; function Trim_Right(const s: AnsiString): AnsiString; var i: Integer; begin Result := s; for i := Length(Result) downto 1 do if Result[i] <> ' ' then break; SetLength(Result, i); end; begin if Length(CustomFrameSet) = 15 then Frames := CustomFrameSet else if FGraphicFrames then Frames := FrameSet[2] else Frames := FrameSet[1]; CurrentStyle := FPageStyle; for i := 0 to FMaxHeight - 1 do begin buf := AnsiString(StyleOn(CurrentStyle)); for j := 0 to FBufWidth - 1 do begin Style := FStyleBuf[i * FBufWidth + j]; if Style <> CurrentStyle then begin buf := buf + AnsiString(StyleChange(CurrentStyle, Style)); CurrentStyle := Style; end; if FFrameBuf[i * FBufWidth + j] <> 0 then buf := buf + Frames[FFrameBuf[i * FBufWidth + j]] else buf := buf + FCharBuf[i * FBufWidth + j]; end; buf := Trim_Right(buf) + AnsiString(StyleOff(CurrentStyle)); WriteStrLn(buf); end; end; function TfrxDotMatrixExport.ShowModal: TModalResult; var Ini: TCustomIniFile; begin Ini := Report.GetIniFile; with TfrxDMPExportDialog.Create(nil) do begin if FUseIniSettings then begin FPageBreaks := Ini.ReadBool('DMP', 'PageBreaks', True); FOEMConvert := Ini.ReadBool('DMP', 'OEM', True); FGraphicFrames := Ini.ReadBool('DMP', 'GraphFrame', False); FEscModel := Ini.ReadInteger('DMP', 'PrinterType', 0); end; if FEscModel >= frxDMPrinters.Count then FEscModel := 0; PageBreaksCB.Checked := FPageBreaks; OemCB.Checked := FOEMConvert; PseudoCB.Checked := FGraphicFrames; SaveToFileCB.Checked := FSaveToFile; EscCB.ItemIndex := FEscModel; CopiesUD.Position := Report.PrintOptions.Copies; RangeE.Text := PageNumbers; Result := ShowModal; if Result = mrOk then begin FSaveToFile := SaveToFileCB.Checked; if FSaveToFile then if SaveDialog1.Execute then FileName := SaveDialog1.Filename else Result := mrCancel; CurPage := False; if PageNumbersRB.Checked then PageNumbers := RangeE.Text else if CurPageRB.Checked then CurPage := True else PageNumbers := ''; FCopies := StrToInt(CopiesE.Text); FPageBreaks := PageBreaksCB.Checked; FOEMConvert := OemCB.Checked; FGraphicFrames := PseudoCB.Checked; FEscModel := EscCB.ItemIndex; Ini.WriteBool('DMP', 'OEM', FOEMConvert); Ini.WriteBool('DMP', 'GraphFrame', FGraphicFrames); Ini.WriteBool('DMP', 'PageBreaks', FPageBreaks); Ini.WriteInteger('DMP', 'PrinterType', FEscModel); end; Free; end; Ini.Free; end; function TfrxDotMatrixExport.Start: Boolean; begin if not ShowDialog then FCopies := Report.PrintOptions.Copies; if Assigned(Stream) then FStream := Stream else begin if not FSaveToFile then FileName := GetTempFName; if FileName <> '' then FStream := TFileStream.Create(FileName, fmCreate) else FStream := nil; end; if Assigned(FStream) then begin Reset; WriteStr(FPrinterInitString); WriteStr(AnsiString(Report.ReportOptions.InitString)); Result := True end else Result := False; end; procedure TfrxDotMatrixExport.StartPage(Page: TfrxReportPage; Index: Integer); begin FMaxHeight := 0; FPageStyle := StyleToInt(TfrxDMPPage(Page).FontStyle); CreateBuf(Round(Page.Width / fr1CharX) + 1, Round(Page.Height / fr1CharY) + 1); if Page.Orientation = poLandscape then Landscape else Portrait; end; procedure TfrxDotMatrixExport.ExportObject(Obj: TfrxComponent); var Style: Integer; Memo: TfrxDMPMemoView; begin if (Obj is TfrxView) and not TfrxView(Obj).Printable then Exit; if Obj is TfrxDMPMemoView then begin Memo := TfrxDMPMemoView(Obj); Style := StyleToInt(Memo.FontStyle); DrawMemo(Round(Memo.AbsLeft / fr1CharX), Round(Memo.AbsTop / fr1CharY), Round(Memo.Width / fr1CharX), Round(Memo.Height / fr1CharY), Memo); if (ftLeft in Memo.Frame.Typ) then DrawFrame(Round(Memo.AbsLeft / fr1CharX) - 1, Round(Memo.AbsTop / fr1CharY) - 1, 1, Round(Memo.Height / fr1CharY) + 2, Style); if (ftRight in Memo.Frame.Typ) then DrawFrame(Round((Memo.AbsLeft + Memo.Width) / fr1CharX), Round(Memo.AbsTop / fr1CharY) - 1, 1, Round(Memo.Height / fr1CharY) + 2, Style); if (ftTop in Memo.Frame.Typ) then DrawFrame(Round(Memo.AbsLeft / fr1CharX) - 1, Round(Memo.AbsTop / fr1CharY) - 1, Round(Memo.Width / fr1CharX) + 2, 1, Style); if (ftBottom in Memo.Frame.Typ) then DrawFrame(Round(Memo.AbsLeft / fr1CharX) - 1, Round((Memo.AbsTop + Memo.Height) / fr1CharY), Round(Memo.Width / fr1CharX) + 2, 1, Style); end else if Obj is TfrxDMPLineView then begin Style := StyleToInt(TfrxDMPLineView(Obj).FontStyle); if Obj.Width = 0 then DrawFrame(Trunc(Obj.AbsLeft / fr1CharX), Trunc(Obj.AbsTop / fr1CharY), 1, Round(Obj.Height / fr1CharY) + 1, Style) else if Obj.Height = 0 then begin if TfrxDMPLineView(Obj).Align = baWidth then DrawFrame(Trunc(Obj.AbsLeft / fr1CharX) - 1, Trunc(Obj.AbsTop / fr1CharY), Round(Obj.Width / fr1CharX) + 3, 1, Style) else if TfrxDMPLineView(Obj).Align = baLeft then DrawFrame(Trunc(Obj.AbsLeft / fr1CharX) - 1, Trunc(Obj.AbsTop / fr1CharY), Round(Obj.Width / fr1CharX) + 1, 1, Style) else if TfrxDMPLineView(Obj).Align = baRight then DrawFrame(Trunc(Obj.AbsLeft / fr1CharX), Trunc(Obj.AbsTop / fr1CharY), Round(Obj.Width / fr1CharX) + 2, 1, Style) else DrawFrame(Trunc(Obj.AbsLeft / fr1CharX), Trunc(Obj.AbsTop / fr1CharY), Round(Obj.Width / fr1CharX) + 1, 1, Style); end; end else if Obj is TfrxDMPCommand then begin SetString(Round(Obj.AbsLeft / fr1CharX), Round(Obj.AbsTop / fr1CharY), AnsiString(TfrxDMPCommand(Obj).ToChr)); end; end; procedure TfrxDotMatrixExport.FinishPage(Page: TfrxReportPage; Index: Integer); begin FlushBuf; FreeBuf; if FPageBreaks then FormFeed; end; procedure TfrxDotMatrixExport.Finish; var i: Integer; fname: String; f, ffrom: TFileStream; begin if FStream <> Stream then begin FStream.Free; if not frxPrinters.HasPhysicalPrinters then Exit; if not FSaveToFile then begin fname := GetTempFName; f := TFileStream.Create(fname, fmCreate); ffrom := TFileStream.Create(FileName, fmOpenRead); f.Write(FPrinterInitString[1], Length(FPrinterInitString)); f.CopyFrom(ffrom, 0); f.Free; ffrom.Free; f := TFileStream.Create(FileName, fmCreate); ffrom := TFileStream.Create(fname, fmOpenRead); f.CopyFrom(ffrom, 0); f.Free; ffrom.Free; DeleteFile(fname); for i := 1 to FCopies do SpoolFile(FileName); DeleteFile(FileName); end; end; end; { TfrxTXTExportDialog } procedure TfrxDMPExportDialog.FormCreate(Sender: TObject); var i: Integer; begin rePadding(Self); Caption := frxGet(500); PrinterL.Caption := frxGet(501); PagesL.Caption := frxGet(502); CopiesL.Caption := frxGet(503); CopiesNL.Caption := frxGet(504); DescrL.Caption := frxGet(9); OptionsL.Caption := frxGet(505); EscL.Caption := frxGet(506); OK.Caption := frxGet(1); Cancel.Caption := frxGet(2); SaveToFileCB.Caption := frxGet(507); AllRB.Caption := frxGet(3); CurPageRB.Caption := frxGet(4); PageNumbersRB.Caption := frxGet(5); PageBreaksCB.Caption := frxGet(6); OemCB.Caption := frxGet(508); PseudoCB.Caption := frxGet(509); SaveDialog1.Filter := frxGet(510); PrinterCB.Items := frxPrinters.Printers; PrinterCB.ItemIndex := frxPrinters.PrinterIndex; OldIndex := frxPrinters.PrinterIndex; for i := 0 to frxDMPrinters.Count - 1 do EscCB.Items.Add(frxDMPrinters[i].Commands[cmdName]); SetWindowLong(CopiesE.Handle, GWL_STYLE, GetWindowLong(CopiesE.Handle, GWL_STYLE) or ES_NUMBER); if UseRightToLeftAlignment then FlipChildren(True); end; procedure TfrxDMPExportDialog.FormHide(Sender: TObject); begin if ModalResult <> mrOk then frxPrinters.PrinterIndex := OldIndex; end; procedure TfrxDMPExportDialog.PrinterCBClick(Sender: TObject); begin frxPrinters.PrinterIndex := PrinterCB.ItemIndex; end; procedure TfrxDMPExportDialog.PrinterCBDrawItem(Control: TWinControl; Index: Integer; ARect: TRect; State: TOwnerDrawState); var r: TRect; begin r := ARect; r.Right := r.Left + 18; r.Bottom := r.Top + 16; OffsetRect(r, 2, 0); with PrinterCB.Canvas do begin FillRect(ARect); BrushCopy(r, Image1.Picture.Bitmap, Rect(0, 0, 18, 16), clOlive); TextOut(ARect.Left + 24, ARect.Top + 1, PrinterCB.Items[Index]); end; end; procedure TfrxDMPExportDialog.RangeEEnter(Sender: TObject); begin PageNumbersRB.Checked := True; end; procedure TfrxDMPExportDialog.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_F1 then frxResources.Help(Self); end; initialization frxDMPrinters := TfrxDMPrinters.Create; frxDMPrinters.ReadDefaultPrinters; frxDMPrinters.ReadExtPrinters; finalization frxDMPrinters.Free; end.