rm_e_main.pas

来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 420 行

PAS
420
字号

{******************************************************}
{                                                      }
{          Report Machine v3.0                         }
{           main export filter                         }
{                                                      }
{         write by whf and jim_waw(jim_waw@163.com)    }
{******************************************************}

unit RM_e_main;

interface

{$I RM.INC}

uses
  SysUtils, Windows, Messages, Classes, Graphics, Forms, Dialogs, StdCtrls,
  Controls, Comctrls, RM_Class
{$IFDEF RXGIF}, JvGif{$ENDIF}
{$IFDEF JPEG}, JPEG{$ENDIF};

type
  TRMEFImageFormat = (ifGIF, ifJPG, ifBMP);
  TRMObjType = (rmotMemo, rmotPicture);

  PRMEFTextRec = ^TRMEFTextRec;
  TRMEFTextRec = packed record
    Left, Top: Integer;
    Text: string;
    TextWidth: Integer;
    TextHeight: Integer;
  end;

  TRMEFDataRec = class
  private
    FTextList: TList;
    function GetTextList: TList;
    procedure ClearTextList;
    function GetTextListCount: Integer;
  public
    Left, Top, Width, Height: Integer;
    Obj: TRMReportView;
    ObjType: TRMObjType;
    Bitmap: TBitmap;
    BmpWidth: Integer;
    BmpHeight: Integer;
    TextWidth: Integer;
    ViewIndex: Integer;
    constructor Create;
    destructor Destroy; override;
    property TextList: TList read GetTextList;
    property TextListCount: Integer read GetTextListCount;
  end;

  TRMMainExportFilter = class;

  TBeforeSaveGraphicEvent = procedure(Sender: TRMMainExportFilter;
    AViewName: string; var UniqueImage: Boolean; var ReuseImageIndex: Integer;
    AAltText: string) of object;

  TAfterSaveGraphicEvent = procedure(Sender: TRMMainExportFilter;
    AViewName: string; ObjectImageIndex: Integer) of object;

 { TRMMainExportFilter }
  TRMMainExportFilter = class(TRMExportFilter)
  private
    FScaleX, FScaleY: Double;
    FExportFrames, FExportImages: Boolean;
{$IFDEF JPEG}
    FJPEGQuality: TJPEGQualityRange;
{$ENDIF}
    FViewNames: TStringList;
    FPixelFormat: TPixelFormat;
    FNowDataRec: TRMEFDataRec;
  protected
    CanMangeRotationText: Boolean;
    FDataList: TList;
    FPageNo: Integer;
    FPageWidth: Integer;
    FPageHeight: Integer;
    FExportImageFormat: TRMEFImageFormat;

    procedure SaveBitmapToPicture(aBmp: TBitmap; aImgFormat: TRMEFImageFormat
{$IFDEF JPEG}; aJPEGQuality: TJPEGQualityRange{$ENDIF}; var aPicture: TPicture);

    procedure OnBeginDoc; override;
    procedure OnEndDoc; override;
    procedure OnBeginPage; override;
    procedure OnEndPage; override;
    procedure OnExportPage(const aPage: TRMEndPage); override;
    procedure InternalOnePage(aPage: TRMEndPage); virtual;
    procedure OnText(aDrawRect: TRect; x, y: Integer; const aText: string; View: TRMView); override;
    procedure ClearDataList;
    property PixelFormat: TPixelFormat read FPixelFormat write FPixelFormat default pf24bit;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property ScaleX: Double read FScaleX write FScaleX;
    property ScaleY: Double read FScaleY write FScaleY;
    property ExportImages: Boolean read FExportImages write FExportImages default True;
    property ExportFrames: Boolean read FExportFrames write FExportFrames default True;
    property ExportImageFormat: TRMEFImageFormat read FExportImageFormat write FExportImageFormat;
{$IFDEF JPEG}
    property JPEGQuality: TJPEGQualityRange read FJPEGQuality write FJPEGQuality default High(TJPEGQualityRange);
{$ENDIF}
  end;

const
  ImageFormats: array[TRMEFImageFormat] of string = ('GIF', 'JPG', 'BMP');

function RMReplaceString(const S, OldPattern, NewPattern: string): string;

implementation

uses RM_Common, RM_Utils;

function RMReplaceString(const S, OldPattern, NewPattern: string): string;
var
  I: Integer;
  SearchStr, Str, OldPat: string;
begin
  SearchStr := AnsiUpperCase(S);
  OldPat := AnsiUpperCase(OldPattern);
  Str := S;
  Result := '';
  while SearchStr <> '' do
  begin
    I := AnsiPos(OldPat, SearchStr);
    if I = 0 then
    begin
      Result := Result + Str;
      Break;
    end;
    Result := Result + Copy(Str, 1, I - 1) + NewPattern;
    Str := Copy(Str, I + Length(OldPattern), MaxInt);
    SearchStr := Copy(SearchStr, I + Length(OldPat), MaxInt);
  end;
end;

function RMGetTextSize(AFont: TFont; const Text: string): TSize;
var
  DC: HDC;
  SaveFont: HFont;
begin
  DC := GetDC(0);
  SaveFont := SelectObject(DC, AFont.Handle);
  Result.cX := 0;
  Result.cY := 0;
  GetTextExtentPoint32(DC, PChar(Text), Length(Text), Result);
  SelectObject(DC, SaveFont);
  ReleaseDC(0, DC);
end;

{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------}

constructor TRMEFDataRec.Create;
begin
  inherited;
  FTextList := nil;
end;

destructor TRMEFDataRec.Destroy;
begin
  ClearTextList;
  FTextList.Free; FTextList := nil;
  inherited;
end;

function TRMEFDataRec.GetTextList: TList;
begin
  if FTextList = nil then
    FTextList := TList.Create;
  Result := FTextList;
end;

function TRMEFDataRec.GetTextListCount: Integer;
begin
  if FTextList = nil then
    Result := 0
  else
    Result := FTextList.Count;
end;

procedure TRMEFDataRec.ClearTextList;
var
  i: Integer;
begin
  if FTextList = nil then Exit;
  for i := 0 to FTextList.Count - 1 do
  begin
    Dispose(pRMEFTextRec(FTextList[i]));
  end;
  FTextList.Clear;
end;

{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------}
{TRMMainExportFilter}

constructor TRMMainExportFilter.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FScaleX := 1;
  FScaleY := 1;
  ShowDialog := True;
{$IFDEF JPEG}
  FJPEGQuality := High(TJPEGQualityRange);
  FExportImageFormat := ifJPG;
{$ELSE}
  FExportImageFormat := ifBMP;
{$ENDIF}

  FExportImages := True;
  FExportFrames := True;
  FPixelFormat := pf24bit;
end;

destructor TRMMainExportFilter.Destroy;
begin
  RMUnRegisterExportFilter(Self);
  inherited Destroy;
end;

procedure TRMMainExportFilter.OnBeginDoc;
begin
  FDataList := TList.Create;
  FViewNames := TStringList.Create;

  FPageNo := 0;
  FPageWidth := ParentReport.EndPages[0].PageWidth;
  FPageHeight := ParentReport.EndPages[0].PageHeight;
end;

procedure TRMMainExportFilter.OnEndDoc;
begin
  ClearDataList;
  FDataList.Free;
  FViewNames.Free;
end;

procedure TRMMainExportFilter.OnBeginPage;
begin
  ClearDataList;
end;

procedure TRMMainExportFilter.OnEndPage;
begin
  Inc(FPageNo);
end;

type
  THackRMView = class(TRMReportView)
  end;

  THackMemoView = class(TRMCustomMemoView)
  end;

procedure TRMMainExportFilter.OnText(aDrawRect: TRect; x, y: Integer; const aText: string; View: TRMView);
var
  lTextRec: pRMEFTextRec;
begin
  New(lTextRec);
  lTextRec.Left := x;
  lTextRec.Top := y;
  lTextRec.Text := aText;
  lTextRec.TextWidth := RMGetTextSize(TRMCustomMemoView(FNowDataRec.Obj).Font, aText).cx;
  lTextRec.TextHeight := RMGetTextSize(TRMCustomMemoView(FNowDataRec.Obj).Font, aText).cy;
  FNowDataRec.TextList.Add(lTextRec);
end;

procedure TRMMainExportFilter.InternalOnePage(aPage: TRMEndPage);
begin
end;

procedure TRMMainExportFilter.OnExportPage(const aPage: TRMEndPage);
var
  i, lIndex: Integer;
  t: TRMReportView;
  lDataRec: TRMEFDataRec;
  lSaveOffsetLeft, lSaveOffsetTop: Integer;
  lIsMemoView: Boolean;
begin
  FPageWidth := Round(aPage.PrinterInfo.PageWidth * ScaleX);
  FPageHeight := Round(aPage.PrinterInfo.PageHeight * ScaleY);

  for i := 0 to aPage.Page.Objects.Count - 1 do
  begin
    t := aPage.Page.Objects[i];
    if t.IsBand or (t is TRMSubReportView) then Continue;

    lDataRec := TRMEFDataRec.Create;
    lDataRec.Obj := t;
    lDataRec.Bitmap := nil;
    lDataRec.ObjType := rmotMemo;

    lIndex := FViewNames.IndexOf(t.Name);
    if lIndex < 0 then
      lIndex := FViewNames.Add(t.Name);
    lDataRec.ViewIndex := lIndex;

    lDataRec.Left := Round(t.spLeft * ScaleX);
    lDataRec.Top := Round(t.spTop * ScaleY);
    lDataRec.Width := Round(t.spWidth * ScaleX);
    lDataRec.Height := Round(t.spHeight * ScaleY);

    lIsMemoView := (t.ClassName = TRMMemoView.ClassName) or (t.ClassName = TRMCalcMemoView.ClassName);
    lIsMemoView := lIsMemoView and (CanMangeRotationText or (THackMemoView(lDataRec.Obj).RotationType = rmrtNone));
    if lIsMemoView then
    begin
      lDataRec.Width := lDataRec.Width + 1;
      lDataRec.TextWidth := RMGetTextSize(TRMCustomMemoView(t).Font, t.Memo.Text).cx;

      lSaveOffsetLeft := THackRMView(t).OffsetLeft;
      lSaveOffsetTop := THackRMView(t).OffsetTop;
      THackRMView(t).OffsetLeft := 0;
      THackRMView(t).OffsetTop := 0;
      FNowDataRec := lDataRec;
      THackRMView(t).ExportData;
      THackRMView(t).OffsetLeft := lSaveOffsetLeft;
      THackRMView(t).OffsetTop := lSaveOffsetTop;
    end
    else
    begin
      lDataRec.ObjType := rmotPicture;
      if ExportImages then
      begin
        lDataRec.Bitmap := TBitmap.Create;
        lDataRec.Bitmap.PixelFormat := FPixelFormat;
        lDataRec.Bitmap.Width := Round(t.spWidth * ScaleX + 1);
        lDataRec.Bitmap.Height := Round(t.spHeight * ScaleY + 1);

        lSaveOffsetLeft := THackRMView(t).OffsetLeft;
        lSaveOffsetTop := THackRMView(t).OffsetTop;
        THackRMView(t).OffsetLeft := 0;
        THackRMView(t).OffsetTop := 0;
        t.SetspBounds(0, 0, lDataRec.Bitmap.Width - 1, lDataRec.Bitmap.Height - 1);
        t.Draw(lDataRec.Bitmap.Canvas);
        t.SetspBounds(t.spLeft, t.spTop, t.spWidth, t.spHeight);
        THackRMView(t).OffsetLeft := lSaveOffsetLeft;
        THackRMView(t).OffsetTop := lSaveOffsetTop;
      end;
    end;

    FDataList.Add(lDataRec);
  end;

  InternalOnePage(aPage);
end;

procedure TRMMainExportFilter.ClearDataList;
var
  i: Integer;
  p: TRMEFDataRec;
begin
  if FDataList = nil then Exit;

  for i := 0 to FDataList.Count - 1 do
  begin
    p := FdataList[i];
    if p.Bitmap <> nil then
      p.Bitmap.Free; //by waw
    p.Free;
  end;
  FDataList.Clear;
end;

procedure TRMMainExportFilter.SaveBitmapToPicture(aBmp: TBitmap; aImgFormat: TRMEFImageFormat
{$IFDEF JPEG}; aJPEGQuality: TJPEGQualityRange{$ENDIF}; var aPicture: TPicture);
var
  lGraphic: TGraphic;

  procedure SaveJpgGif;
  begin
    try
      lGraphic.Assign(aBmp);
      aPicture.Assign(lGraphic);
    finally
      lGraphic.Free;
    end;
  end;

begin
  aBmp.PixelFormat := FPixelFormat;
  case aImgFormat of
    ifBMP:
      begin
        aPicture.Assign(aBmp);
      end;
    ifGIF:
      begin
{$IFDEF RXGIF}
        lGraphic := TJvGIFImage.Create;
        SaveJpgGif;
{$ELSE}
{$IFDEF JPEG}
        lGraphic := TJPEGImage.Create;
        SaveJpgGif;
{$ELSE}
        aPicture.Assign(aBmp);
{$ENDIF}
{$ENDIF}
      end;
    ifJPG:
      begin
{$IFDEF JPEG}
        lGraphic := TJPEGImage.Create;
        TJPEGImage(lGraphic).CompressionQuality := JPEGQuality;
        SaveJpgGif;
{$ELSE}
        aPicture.Assign(aBmp);
{$ENDIF}
      end;
  end;
end;

end.

⌨️ 快捷键说明

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