⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prndbgeh.pas

📁 Dbgrid 增强(附源码):支持多表头,多固定列,按表头排序,支持合计列,并支持直接打印
💻 PAS
📖 第 1 页 / 共 2 页
字号:
 end;
 TFooterValues = array[0..MaxListSize - 1] of Currency;
 PFooterValues = ^TFooterValues;

var
  ColsToPages, PrnRowHeights, PrnColWIdths: TList;
  GridWidth, RealRight,  RealLeft, MinRowHeight: Integer;
  {fPrnPhysWidth,fPrnPhysHeight,} fPrnPhysOffSetX, fPrnPhysOffSetY : Integer;
  fPrnHorsRes, fPrnVertRes, PrnTitlEh, PenW, PrnTitleTextH: Integer;
  PrintRec: TRect;
  fLogPelsX1, fLogPelsY1, fLogPelsX2, fLogPelsY2, fScaleX, fScaleY: Double;
  //TopFooterPos, TopHeaderPos:Integer;
  //FromRow, ToRow, NodeLevel, PageNo, GridRowCount: Integer;
  SavedBookMark:TBookmarkStr;
  PBm1,PBm2:TPolyBookmark;
  PSX1,PSY1,PSX2,PSY2:Integer;
  FirtsPage,AWordWrap:Boolean;
  PolyPolyPoints, PolyLengths:TList;
  TitleRect,FooterRect: TRect;
  PrnColumns:TColumnsEhList;
  FooterValues: PFooterValues;

const Macros : array [0..4] of String = ( '&[Page]', '&[ShortDate]', '&[Date]', '&[LongDate]', '&[Time]');
      MacroValues : array [0..4] of String = ('','','','','');


  procedure InitMacroValues;
  begin
    MacroValues[1] := DateToStr(Now);
    MacroValues[2] := DateToStr(Now);
    MacroValues[3] := FormatDateTime(LongDateFormat,Now);
    MacroValues[4] := TimeToStr(Now);
  end;

  procedure InitPolyBookmark(var APBm:TPolyBookmark);
  var idx:Integer;
  begin
   if DBGridEh.DataSource.DataSet.Eof then begin
     APBm.InDS := False;
     APBm.bm := '';//nil;
     if (DBGridEh.FooterRowCount = 0) then APBm.EOF := True
     else begin
       APBm.bm := '0';//Pointer(0);
       APBm.EOF := False;
     end;
   end else begin
     if DBGridEh.Selection.SelectionType = gstRecordBookmarks then begin
       if DBGridEh.SelectedRows.Find(DBGridEh.DataSource.DataSet.Bookmark,idx) then
         APBm.bm := DBGridEh.DataSource.DataSet.Bookmark
       else begin
         APBm.bm := DBGridEh.SelectedRows[0];
         DBGridEh.DataSource.DataSet.Bookmark := DBGridEh.SelectedRows[0];
       end
     end else if DBGridEh.Selection.SelectionType = gstRectangle then begin
       APBm.bm := DBGridEh.Selection.Rect.TopRow;
       DBGridEh.DataSource.DataSet.Bookmark := DBGridEh.Selection.Rect.TopRow;
     end else begin
       APBm.bm := DBGridEh.DataSource.DataSet.Bookmark;
     end;
     APBm.InDS := True;
     APBm.EOF := False;
   end;
  end;

  procedure GotoPolyBookmark(var APBm:TPolyBookmark);
  begin
    if (APBm.InDS = True) then DBGridEh.DataSource.DataSet.GotoBookmark(TBookmark(APBm.bm));
  end;

  procedure SetNextPolyBookmark(var APBm:TPolyBookmark);
  var idx:Integer;
  begin
    if APBm.EOF then Exit;

    if (APBm.InDS = True) then begin
      if DBGridEh.Selection.SelectionType = gstRecordBookmarks then begin
        if DBGridEh.SelectedRows.Find(DBGridEh.DataSource.DataSet.Bookmark,idx) then
          if idx = DBGridEh.SelectedRows.Count-1 then begin
            APBm.InDS := False;
            APBm.bm := '';//nil;
            if (DBGridEh.FooterRowCount = 0) then APBm.EOF := True
            else begin
              APBm.bm := '0';//Pointer(0);
              APBm.EOF := False;
            end;
          end
          else begin
            DBGridEh.DataSource.DataSet.Bookmark := DBGridEh.SelectedRows[idx+1];
            APBm.bm := DBGridEh.DataSource.DataSet.Bookmark;
            APBm.EOF := False;
          end
        else begin
          DBGridEh.DataSource.DataSet.Bookmark := DBGridEh.SelectedRows[0];
          APBm.bm := DBGridEh.DataSource.DataSet.Bookmark;
          APBm.EOF := False;
        end;
      end else if DBGridEh.Selection.SelectionType = gstRectangle then begin
        DBGridEh.DataSource.DataSet.Next;
        if (DBGridEh.DataSource.DataSet.CompareBookmarks(Pointer(DBGridEh.Selection.Rect.BottomRow),
                          Pointer(DBGridEh.DataSource.DataSet.Bookmark)) < 0) or
           DBGridEh.DataSource.DataSet.Eof then begin
            APBm.InDS := False;
            APBm.bm := '';//nil;
            if (DBGridEh.FooterRowCount = 0) then APBm.EOF := True
            else begin
              APBm.bm := '0';//Pointer(0);
              APBm.EOF := False;
            end
        end else begin
          APBm.bm := DBGridEh.DataSource.DataSet.Bookmark;
          APBm.EOF := False;
        end;
      end else begin
        DBGridEh.DataSource.DataSet.Next;
        if DBGridEh.DataSource.DataSet.Eof then begin
          APBm.InDS := False;
          APBm.bm := '';//nil;
          if (DBGridEh.FooterRowCount = 0) then APBm.EOF := True
          else begin
            APBm.bm := '0';//Pointer(0);
            APBm.EOF := False;
          end;
        end else begin
          APBm.bm := DBGridEh.DataSource.DataSet.Bookmark;
          APBm.EOF := False;
        end
      end
    end
    else begin
      if (DBGridEh.FooterRowCount-1 <= StrToInt(APBm.bm)) then begin
        APBm.EOF := True;
        APBm.bm := '0';//Pointer(0);
        APBm.InDS := False;
      end
      else begin
        APBm.bm := IntToStr(StrToInt(APBm.bm) + 1);
      end;
    end;
  end;

{  function ComparePolyBookmark(var APBm1,APBm2:TPolyBookmark):Boolean;
  begin
    if (APBm1.bm = APBm2.bm) and (APBm1.InDS = APBm2.InDS) then
      Result := True
    else Result := False;
  end;}

  // Add Polyline
  procedure AddPolyline(const Args: array of const);
  var i: Integer;
  begin
    for i := 0 to High(Args) do
      PolyPolyPoints.Add(Pointer(Args[i].VInteger));
    PolyLengths.Add(Pointer((High(Args)+1) div 2));
  end;

  // -------CalcColsToPages
  procedure CalcColsToPages;
  var curX,w: Integer;
      i:Integer;
  begin
   curX := PrintRec.Left + PenW;
   PrnColWIdths.Clear;
   for i := 0 to PrnColumns.Count - 1 do begin
     w := Round((PrnColumns[i].Width + 1) * fScaleX);
     if ( w > PrintRec.Right - PrintRec.Left) then w := PrintRec.Right - PrintRec.Left;
     PrnColWidths.Add(Pointer(w));
     curX := curX + w;
     if (curX > PrintRec.Right) and (i > 0) then begin
       ColsToPages.Add(Pointer(i-1));
       curX := PrintRec.Left + w + PenW;
     end;
   end;
   ColsToPages.Add(Pointer(PrnColumns.Count - 1));
  end;

  //------------------------
  function GetScaledRealGridWidth:Integer;
  var i: Integer;
  begin
   Result := PenW;
   for i := 0 to PrnColumns.Count - 1 do begin
     Result := Result + Round((PrnColumns[i].Width + 1) * fScaleX);
   end;
  end;

  //------------------------
  function GetPrintGridWidth:Integer;
  var i: Integer;
  begin
   Result := 0;
   for i := 0 to PrnColWidths.Count - 1 do begin
     Result := Result + Integer(PrnColWidths[i]);
   end;
  end;


  //--------------------------
  procedure SetIfNeedFitWidthMapMode;
  var dc :Integer;
  begin
     if GridWidth > (RealRight - RealLeft) then begin
       dc := SetMapMode(VPrinter.Canvas.Handle, MM_ISOTROPIC);
       if (dc = 0) then Raise Exception.Create(' function SetMapMode(Handle, MM_ISOTROPIC) has returned 0 ');
       SetWindowOrgEx(VPrinter.Canvas.Handle,0,0,nil);
       SetWindowExtEx(VPrinter.Canvas.Handle, GridWidth, GridWidth, nil);
       SetViewportExtEx(VPrinter.Canvas.Handle, RealRight - RealLeft, RealRight - RealLeft, nil);
     end;
  end;

  //------------------------
  procedure ResetPrinterCanvas;
  begin
    VPrinter.Canvas.Pen.Width := PenW;
    VPrinter.Canvas.BRUSH.Style := bsClear;
    VPrinter.Canvas.Brush.Color := clWhite;
    VPrinter.Canvas.Font := DBGridEh.Font;
    if (pghFitGridToPageWidth in Options) then SetIfNeedFitWidthMapMode;
  end;

  //--------------------------
  procedure CalcDeviceCaps;
  var Diver:Double;
  begin
(*     fPrnPhysWidth :=  GetDeviceCaps(VPrinter.Canvas.Handle,PHYSICALWIDTH);
     fPrnPhysHeight :=  GetDeviceCaps(VPrinter.Canvas.Handle,PHYSICALHEIGHT);
*)
//     fPrnPhysOffSetX := GetDeviceCaps(VPrinter.Canvas.Handle,PHYSICALOFFSETX);
     fPrnPhysOffSetX := (VPrinter.FullPageWidth - VPrinter.PageWidth) div 2;
//     fPrnPhysOffSetY := GetDeviceCaps(VPrinter.Canvas.Handle,PHYSICALOFFSETY);
     fPrnPhysOffSetY := (VPrinter.FullPagEheight - VPrinter.PagEheight) div 2;

     //fPrnHorsRes :=  GetDeviceCaps(VPrinter.Canvas.Handle,HORZRES);
     fPrnHorsRes := VPrinter.PageWidth;
     //fPrnVertRes :=  GetDeviceCaps(VPrinter.Canvas.Handle,VERTRES);
     fPrnVertRes := VPrinter.PagEheight;

     fLogPelsX1 := GetDeviceCaps(DBGridEh.Canvas.Handle, LOGPIXELSX);
     fLogPelsY1 := GetDeviceCaps(DBGridEh.Canvas.Handle, LOGPIXELSY);

     if VPrinter.Printers.Count > 0 then
     begin
       fLogPelsX2 :=  GetDeviceCaps(VPrinter.Handle, LOGPIXELSX);
       fLogPelsY2 :=  GetDeviceCaps(VPrinter.Handle, LOGPIXELSY);
     end else begin
       fLogPelsX2 :=  DefaultPrinterPixelsPerInchX;
       fLogPelsY2 :=  DefaultPrinterPixelsPerInchY;
     end;


     if (fLogPelsX1 > fLogPelsX2) then
         fScaleX := (fLogPelsX1 / fLogPelsX2)
     else
         fScaleX := (fLogPelsX2 / fLogPelsX1);

     if (fLogPelsY1 > fLogPelsY2) then
         fScaleY := (fLogPelsY1 / fLogPelsY2)
     else
         fScaleY := (fLogPelsY2 / fLogPelsY1);

     if Units = MM then Diver := 2.54 else Diver := 1;
     PrintRec.Left :=  Round(fLogPelsX2 * Page.LeftMargin / Diver ) - fPrnPhysOffSetX;
     PrintRec.Top :=  Round(fLogPelsY2 * Page.TopMargin / Diver ) - fPrnPhysOffSetY;
     PrintRec.Right :=  fPrnHorsRes - Round(fLogPelsX2 * Page.RightMargin / Diver ) + fPrnPhysOffSetX;
     PrintRec.Bottom := fPrnVertRes - Round(fLogPelsY2 * Page.BottomMargin / Diver ) + fPrnPhysOffSetY;

     PSX1 := Round(fScaleX); PSX2 := Round(fScaleX*2);
     PSY1 := Round(fScaleY); PSY2 := Round(fScaleY*2);
     PenW := Trunc((fLogPelsX2 + fLogPelsY2)/200); // PenWidth = 0.01 Inche
     //if (PenW mod 2 = 0) then Inc(PenW);           // Must be uneven

     if (pghFitGridToPageWidth in Options) then begin // On width of page
       GridWidth := GetScaledRealGridWidth;
       RealRight := PrintRec.Right; RealLeft := PrintRec.Left;
       SetIfNeedFitWidthMapMode;

       if GridWidth > (RealRight - RealLeft) then begin
         PrintRec.Right := MulDiv(PrintRec.Right,GridWidth,RealRight - RealLeft); // 务蜞忤螯 镱脲 耱囵钽

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -