unit PrvForm; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, ExtCtrls,Printers,PCTypesUtils, siComp, siLngLnk, Mask, RzEdit, RzSpnEdt, RzCmboBx; type TfrmPrv = class(TForm) ScrollBox1: TScrollBox; bClose: TBitBtn; prnLabel: TLabel; pbox: TPaintBox; bSetting: TBitBtn; bPrint: TBitBtn; lng_Forms: TsiLangLinked; pnDivOverlay: TPanel; lbDivOverlay: TLabel; seDivOverlay: TRzSpinEdit; lbDivOverlayUOM: TLabel; pnScale: TPanel; lbScale: TLabel; cbScale: TRzComboBox; Label1: TLabel; Label2: TLabel; lbPageCount: TLabel; Timer_Scale: TTimer; procedure bCloseClick(Sender: TObject); procedure pboxPaint(Sender: TObject); procedure FormCreate(Sender: TObject); procedure bSettingClick(Sender: TObject); procedure bPrintClick(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure cbScaleKeyPress(Sender: TObject; var Key: Char); procedure Timer_ScaleTimer(Sender: TObject); procedure cbScaleChange(Sender: TObject); private FScaleKoeff: Double; FIdxScaleToPaper: Integer; { Private declarations } Procedure DrawPage; Procedure DrawMargins; procedure AddIntItemToScales(AVal: Integer); procedure DefineScaleKoeff; public { Public declarations } tBmp: TBitmap; CadControl: Pointer; FPrRect: TDoubleRect; FIsRect: Boolean; Procedure Init(AStartPreview: Boolean=false); end; var frmPrv: TfrmPrv; prnName: String; resX,resY: Integer; offX,offY: Integer; dx,dy: Integer; dScale: Double; ox,oy,pw,ph:Integer; dpm: Double; Init_prnW: Integer; Init_prnH: Integer; implementation {$R *.DFM} uses PCDrawing, U_Constants, U_Common, U_BaseCommon; { TfrmPrv } procedure TfrmPrv.Init(AStartPreview: Boolean=false); var Cad: TPCDrawing; TmpInitPrnW: Integer; TmpInitPrnH: Integer; prnW,prnH: Double; //06.12.2011 Integer; pw, ph: integer; prow, pcol : integer; OFFX, OFFY: integer; ShowDivOverlay: Boolean; begin Cad := TPCDrawing(CadControl); prnName := Printer.Printers[Printer.PrinterIndex]; prnLabel.Caption := cPrevForm_Mes1 + prnName; CAD.DefinePrnDivIndent; ShowDivOverlay := false; if Not FIsRect then FPrRect := DoubleRect(0,0,Cad.WorkWidth,Cad.WorkHeight); if AStartPreview then begin cbScale.ItemIndex := cbScale.IndexOf(IntToStr(100)); FScaleKoeff := 1; DefineScaleKoeff; end; if not GPreview then begin //02.12.2011 Init_prnW := GetDeviceCaps(printer.Handle, PHYSICALWIDTH); //02.12.2011 Init_prnH := GetDeviceCaps(printer.Handle, PHYSICALHEIGHT); end; //25.11.2011 - подганяем превью под выделенный размер TmpInitPrnW := GetDeviceCaps(printer.Handle, PHYSICALWIDTH); TmpInitPrnH := GetDeviceCaps(printer.Handle, PHYSICALHEIGHT); prnW := GetDeviceCaps(printer.Handle, PHYSICALWIDTH); prnH := GetDeviceCaps(printer.Handle, PHYSICALHEIGHT); resX := GetDeviceCaps(printer.Handle, LOGPIXELSX); resY := GetDeviceCaps(printer.Handle, LOGPIXELSY); OFFX := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX); OFFY := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY); pw := round(prnW / (resX / 25.4)); ph := round(prnH / (resY / 25.4)); // Переводим в точки //prnW := round(prnW * ( (Abs(FPrRect.Right - FPrRect.Left)*FScaleKoeff) / pw)); //prnH := round(prnH * ( (Abs(FPrRect.Bottom - FPrRect.Top)*FScaleKoeff) / ph)); prnW := round(prnW * ( (Abs(FPrRect.Right - FPrRect.Left)) / pw)); prnH := round(prnH * ( (Abs(FPrRect.Bottom - FPrRect.Top)) / ph)); if (prnW > TmpInitPrnW) or (prnH > TmpInitPrnH) then begin //ShowDivOverlay := true; if FIsRect then begin TmpInitPrnW := Round(PrnW); TmpInitPrnH := Round(PrnH); end; end; if not GPreview then begin Init_prnW := TmpInitPrnW; Init_prnH := TmpInitPrnH; end; //06.12.2011 Если печатаемый размер больше размера страницы, то отображаем параметры наложения prnW := GetDeviceCaps(Printer.Handle, PHYSICALWIDTH); prnH := GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT); resX := GetDeviceCaps(printer.Handle, LOGPIXELSX); resY := GetDeviceCaps(printer.Handle, LOGPIXELSY); // Переводим в мм prnW := (prnW / resX) * 25.4; prnH := (prnH / resY) * 25.4; // Если размера бумаги меньше размера печатаемой области if ((prnW+prnReservTiling) < (Abs(FPrRect.Right - FPrRect.Left)*FScaleKoeff)) or ((prnH+prnReservTiling) < (Abs(FPrRect.Bottom - FPrRect.Top)*FScaleKoeff)) then ShowDivOverlay := true; //Количество листов Cad.CalcPrDims(prnW, prnH, prow, pcol, Abs(FPrRect.Right - FPrRect.Left), Abs(FPrRect.Bottom - FPrRect.Top), FScaleKoeff); lbPageCount.Caption := IntToStr(prow * pcol); // GPreview := False; resX := GetDeviceCaps(printer.Handle, LOGPIXELSX); resY := GetDeviceCaps(printer.Handle, LOGPIXELSY); offX := GetDeviceCaps(printer.Handle, PHYSICALOFFSETX ); offY := GetDeviceCaps(printer.Handle, PHYSICALOFFSETY ); // offX := 0; // offY := 0; //01.12.2011 pnDivOverlay.Visible := ShowDivOverlay; seDivOverlay.Value := 0; lbDivOverlayUOM.Caption := GetNameUOM(ConvertUOMToMin(GCurrProjUnitOfMeasure), true); end; procedure TfrmPrv.bCloseClick(Sender: TObject); begin Close; end; procedure TfrmPrv.pboxPaint(Sender: TObject); var //clpRgn: Integer; clpRgn: HRGN; begin {//24.11.2011 DrawPage; tbmp.Canvas.Brush.Color := clWhite; tbmp.Canvas.Brush.Style := bsSolid; tbmp.Canvas.FillRect(Rect(0,0,tbmp.Width,tbmp.Height)); TPCDrawing(CadControl).DrawToCanvas(tbmp.canvas, dx, dy, dScale); clpRgn := CreateRectRgn(dx + ox, dy + ox, dx + pw - ox, dy + ph - ox); SelectClipRgn(pbox.canvas.handle,clpRgn); Pbox.Canvas.Draw(0, 0, tbmp); SelectClipRgn(pbox.canvas.handle, 0); DeleteObject(ClpRgn); DrawMargins; } DrawPage; tbmp.Canvas.Brush.Color := clWhite; tbmp.Canvas.Brush.Style := bsSolid; tbmp.Canvas.FillRect(Rect(0,0,tbmp.Width,tbmp.Height)); if Not FIsRect then begin TPCDrawing(CadControl).DrawToCanvas(tbmp.canvas, dx, dy, dScale); end else begin //TPCDrawing(CadControl).tileX := ; //TPCDrawing(CadControl).tileY := y1; TPCDrawing(CadControl).DrawRectToCanvas(FPrRect, tbmp.canvas, dx, dy, dScale); end; clpRgn := CreateRectRgn(dx + ox, dy + ox, dx + pw - ox, dy + ph - ox); SelectClipRgn(pbox.canvas.handle,clpRgn); Pbox.Canvas.Draw(0, 0, tbmp); SelectClipRgn(pbox.canvas.handle, 0); DeleteObject(ClpRgn); DrawMargins; end; procedure TfrmPrv.DrawPage; var xr, yr, cr: Double; dpmO: Double; q: integer; begin // q := prnW; // prnW := (prnH * 2); // prnH := q; xr := (pbox.Width - 10) / Init_prnW; yr := (pBox.Height - 10) / Init_prnH; if xr < yr then cr := xr else cr := yr; pw := round(Init_prnW * cr); ph := round(Init_prnH * cr); ox := round(offX * cr); oy := round(offY * cr); if ox < 3 then ox := 3; if oy < 3 then oy := 3; dx := (pbox.Width - pw) div 2; dy := (pbox.Height - ph) div 2; dpm := (((pw * resx) / Init_prnW) / 25.4); dpmO := TPCDrawing(CadControl).DotsPerMilOrig; dScale := dpm / dpmO; pbox.Canvas.Brush.Style := bsSolid; pbox.Canvas.Brush.Color := clGray; pbox.Canvas.Pen.Color := clGray; pbox.Canvas.Pen.Style := psSolid; pbox.Canvas.Rectangle(dx + 4, dy + 4, dx + pw + 4, dy + ph + 4); pbox.Canvas.Pen.Color := clBlack; pbox.Canvas.Brush.Color := clWhite; pbox.Canvas.Rectangle(dx, dy, dx + pw, dy + ph); end; procedure TfrmPrv.DrawMargins; begin pbox.Canvas.pen.Color := clRed; pbox.Canvas.MoveTo(dx+ox,dy); pbox.Canvas.LineTo(dx+ox,dy+ph); pbox.Canvas.MoveTo(dx,dy+oy); pbox.Canvas.LineTo(dx+pw,dy+oy); pbox.Canvas.MoveTo(dx+pw-ox,dy); pbox.Canvas.LineTo(dx+pw-ox,dy+ph); pbox.Canvas.MoveTo(dx,dy+ph-oy); pbox.Canvas.LineTo(dx+pw,dy+ph-oy); end; procedure TfrmPrv.AddIntItemToScales(AVal: Integer); begin cbScale.Items.AddObject(IntToStr(AVal), TObject(AVal)); end; procedure TfrmPrv.DefineScaleKoeff; var Prcnt: Double; TmpInitPrnW: Integer; TmpInitPrnH: Integer; prnW,prnH: Double; pw, ph: Double; WorkWidth, WorkHeight: Double; OFFX, OFFY: integer; begin if (cbScale.ItemIndex <> -1) then begin // Подганяем под размер бумаги if (cbScale.ItemIndex = FIdxScaleToPaper) then begin { //06.12.2011 - работате не очень кошерно //OFFX := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX); //OFFY := GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY); TmpInitPrnW := GetDeviceCaps(printer.Handle, PHYSICALWIDTH); TmpInitPrnH := GetDeviceCaps(printer.Handle, PHYSICALHEIGHT); prnW := TmpInitPrnW; // - OFFX*2; prnH := TmpInitPrnH; // - OFFY*2; resX := GetDeviceCaps(printer.Handle, LOGPIXELSX); resY := GetDeviceCaps(printer.Handle, LOGPIXELSY); pw := prnW / (resX / 25.4); ph := prnH / (resY / 25.4); // Переводим в точки prnW := round(prnW * (Abs(FPrRect.Right - FPrRect.Left) / pw)); prnH := round(prnH * (Abs(FPrRect.Bottom - FPrRect.Top) / ph)); // Если выходим за пределы размера бумаги if (prnW > TmpInitPrnW) or (prnH > TmpInitPrnH) then begin // Если по ширине больше if Abs(prnW - TmpInitPrnW) > Abs(prnH - TmpInitPrnH) then FScaleKoeff := TmpInitPrnW / prnW else // Иначе если по высоте больше FScaleKoeff := TmpInitPrnH / prnH; end else // Иначе увеличить под размер бумаги if (TmpInitPrnW > prnW) or (TmpInitPrnH > prnH) then begin // Если по ширине ближе к краю бумаги if Abs(TmpInitPrnW - prnW) < Abs(TmpInitPrnH - prnH) then FScaleKoeff := TmpInitPrnW / prnW else FScaleKoeff := TmpInitPrnH / prnH; end;} //------------------------------ WorkWidth := Abs(FPrRect.Right - FPrRect.Left); // - TPCDrawing(CadControl).prnDivIndentX; WorkHeight := Abs(FPrRect.Bottom - FPrRect.Top); // - TPCDrawing(CadControl).prnDivIndentY; prnW := GetDeviceCaps(Printer.Handle, PHYSICALWIDTH); prnH := GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT); resX := GetDeviceCaps(printer.Handle, LOGPIXELSX); resY := GetDeviceCaps(printer.Handle, LOGPIXELSY); // Переводим в мм prnW := (prnW / resX) * 25.4; prnH := (prnH / resY) * 25.4; // Если размера бумаги меньше размера печатаемой области if (prnW < WorkWidth) or (prnH < WorkHeight) then begin // Если по ширине больше if Abs(WorkWidth - prnW) > Abs(WorkHeight - prnH) then FScaleKoeff := (prnW-TPCDrawing(CadControl).prnDivIndentX*1.5) / WorkWidth else // Иначе если по высоте больше FScaleKoeff := (prnH-TPCDrawing(CadControl).prnDivIndentY*1.5) / WorkHeight; end else if (WorkWidth < prnW) or (WorkHeight < prnH) then begin // Если по ширине больше if Abs(prnW - WorkWidth) < Abs(prnH - WorkHeight) then FScaleKoeff := (prnW - TPCDrawing(CadControl).prnDivIndentX) / WorkWidth else // Иначе если по высоте больше FScaleKoeff := (prnH - TPCDrawing(CadControl).prnDivIndentY) / WorkHeight; end; end else begin Prcnt := StrToFloatDef_My(cbScale.Items[cbScale.ItemIndex], 0); if Prcnt > 0 then FScaleKoeff := Prcnt / 100; end; end else begin Prcnt := StrToFloatDef_My(cbScale.Text, 0); if Prcnt > 0 then FScaleKoeff := Prcnt / 100; end; end; procedure TfrmPrv.FormCreate(Sender: TObject); begin tBmp := tBitmap.Create; tbmp.Width := pbox.width; tbmp.Height := pbox.height; FIsRect := false; //AddIntItemToScales(10); AddIntItemToScales(25); AddIntItemToScales(50); AddIntItemToScales(75); AddIntItemToScales(100); AddIntItemToScales(150); AddIntItemToScales(200); AddIntItemToScales(400); AddIntItemToScales(500); FIdxScaleToPaper := cbScale.Items.Add(cPrnScaleToPaper); FScaleKoeff := 1; end; procedure TfrmPrv.bSettingClick(Sender: TObject); begin TPCDrawing(CadControl).ExecuteTBCommand(cPrinterSetup); Init; PBox.Refresh; end; procedure TfrmPrv.bPrintClick(Sender: TObject); var oldScale: Double; begin TPCDrawing(CadControl).prnDivOverlay := FloatInUOM(seDivOverlay.Value, ConvertUOMToMin(GCurrProjUnitOfMeasure), umMM); oldScale := TPCDrawing(CadControl).prnScale; TPCDrawing(CadControl).prnScale := FScaleKoeff; try if Not FIsRect then TPCDrawing(CadControl).ExecuteTBCommand(cPrint) else TPCDrawing(CadControl).PrintRect(FPrRect); finally TPCDrawing(CadControl).prnScale := oldScale; end; end; procedure TfrmPrv.FormDestroy(Sender: TObject); begin //tbmp.FreeImage; //tbmp.Free; //tbmp.free; end; procedure TfrmPrv.cbScaleKeyPress(Sender: TObject; var Key: Char); begin Timer_Scale.Enabled := true; end; procedure TfrmPrv.cbScaleChange(Sender: TObject); begin Timer_Scale.Enabled := true; end; procedure TfrmPrv.Timer_ScaleTimer(Sender: TObject); begin TTimer(Sender).Enabled := false; DefineScaleKoeff; Init; PBox.Refresh; end; end.