uflxmessages.pas

来自「delphi 第三方控件很出色,表格制作的」· PAS 代码 · 共 384 行

PAS
384
字号
unit UFlxMessages;
{$IFDEF LINUX}{$INCLUDE ../FLXCOMPILER.INC}{$ELSE}{$INCLUDE ..\FLXCOMPILER.INC}{$ENDIF}
{$IFDEF LINUX}{$INCLUDE ../FLXCONFIG.INC}{$ELSE}{$INCLUDE ..\FLXCONFIG.INC}{$ENDIF}

interface
uses {$IFDEF FLX_VCL} Windows, {$ENDIF}
     {$IFDEF ConditionalExpressions}{$if CompilerVersion >= 14} variants, varutils, {$IFEND}{$ENDIF} //Delphi 6 or above
     {$IFNDEF ConditionalExpressions}ActiveX,{$ENDIF} //Delphi 5
     Classes, SysUtils;

const
  FLX_VAR_LOCALE_USER_DEFAULT = $400;

resourcestring
  FieldStr='##';
  DataSetStr='__';
  VarStr='#.';

  StrOpen='<';
  StrClose='>';


  ExtrasDelim='...';
  MarkedRowStr='...delete row...';  //Remember to change ExtrasDelim if changing this
  HPageBreakStr='...page break...'; //Remember to change ExtrasDelim if changing this
  FullDataSetStr='*';
  MainTxt='MAIN'; //This is not strictly necessary... just for checking the template
  RecordCountPrefix='RC_';

  DefaultDateTimeFormat='mm/dd/yyyy hh:mm';

  FlexCelVersion='2.6.10';
{$IFDEF SPANISH}
  {$INCLUDE FlxSpanish.inc}
{$ELSE}
{$IFDEF FRENCH}
  {$INCLUDE FlxFrench.inc}
{$ELSE}
{$IFDEF ITALIAN}
  {$INCLUDE FlxItalian.inc}
{$ELSE}
{$IFDEF ROMANIAN}
  {$INCLUDE FlxRomanian.inc}
{$ELSE}
{$IFDEF PORTUGUESEBR}
  {$INCLUDE FlxPortugueseBR.inc}
{$ELSE}
{$IFDEF CHINESE}
  {$INCLUDE FlxChinese.inc}
{$ELSE}
{$IFDEF RUSSIAN}
  {$INCLUDE FlxRussian.inc}
{$ELSE}
{$IFDEF GERMAN}
  {$INCLUDE FlxGerman.inc}
{$ELSE}
{$IFDEF POLISH}
  {$INCLUDE FlxPolish.inc}
{$ELSE}
{$IFDEF FINNISH}
  {$INCLUDE XlsFinnish.inc}
{$ELSE}
  {$INCLUDE FlxEnglish.inc}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}

  xls_Emf='EMF';
  xls_Wmf='WMF';
  xls_Jpeg='JPEG';
  xls_Png='PNG';

  FlexCelTempPrefix = 'flx';

type
  TClientAnchor= packed record
    Flag,
    Col1, Dx1, Row1, Dy1,
    Col2, Dx2, Row2, Dy2: word;
  end;
  PClientAnchor = ^TClientAnchor;

  WidestringArray=array of widestring;

const
  DefColWidthAdapt: integer=Round(256*8/7);  //font used here is 8 pixels wide, not 7

  //Printer Options
  fpo_LeftToRight = $01;  //Print over, then down
  fpo_Orientation = $02;  //0= landscape, 1=portrait
  fpo_NoPls       = $04;  //if 1, then PaperSize, Scale, Res, VRes, Copies, and Landscape data have not been obtained from the printer, so they are not valid.
  fpo_NoColor     = $08;  //1= Black and white
  fpo_Draft       = $10;  //1= Draft quality
  fpo_Notes       = $20;  //1= Print Notes
  fpo_NoOrient    = $40;  //1=orientation not set
  fpo_UsePage     = $80;  //1=use custom starting page number.

var
  ColMult:extended=256/7; //36.6;
  RowMult:extended=15;


type
  TColorPaletteRange=1..56;

  TXlsCellRange=record
    Left, Top, Right, Bottom: integer;
  end;

  TXlsMargins=packed record  //C++ builder gets this struct wrong if we use a normal record.
    Left, Top, Right, Bottom: extended;
    Header, Footer: extended;
  end;

  TXlsSheetVisible=
    (sv_Visible, sv_Hidden, sv_VeryHidden);

  TRTFRun= record
    FirstChar: word;
    FontIndex: word;
  end;

  TRTFRunList= array of TRTFRun;

  TRichString= record
    Value: widestring;
    RTFRuns: TRTFRunList;
  end;

  THyperLinkType=
    (hl_URL, hl_LocalFile, hl_UNC, hl_CurrentWorkbook);

  THyperLink= record
    LinkType: THyperLinkType;
    Description: widestring;
    TargetFrame: widestring;
    TextMark: widestring;
    Text: widestring;
    Hint: widestring;
  end;


type
  TOnGetFileNameEvent  = procedure (Sender: TObject; const  FileFormat: integer; var Filename: TFileName) of object;
  TOnGetOutStreamEvent = procedure (Sender: TObject; const  FileFormat: integer; var OutStream: TStream) of object;

  TXlsImgTypes = (xli_Emf, xli_Wmf, xli_Jpeg, xli_Png, xli_Bmp, xli_Unknown);

  VariantArray=Array [0..maxint div sizeof(Variant)-1]of variant;
  ArrayOfVariant=Array of Variant;

  TXlsCellValue= record
    Value: variant;
    XF: integer;
    IsFormula: boolean;
  end;

  TFlxAnchorType=(at_MoveAndResize, at_MoveAndDontResize, at_DontMoveAndDontResize);

  TImageProperties=record
    Col1, dx1, Row1, dy1, Col2, dx2, Row2, dy2:integer;
    FileName: widestring;  //Not really needed to set.
  end;


  function SearchPathStr(const AFileName: String): String;
  {$IFDEF  VER130}
  function IncludeTrailingPathDelimiter(const S: string): string;
  function VarIsClear(const v: variant): boolean;
  {$ENDIF}

  function StringReplaceSkipQuotes(const S, OldPattern, NewPattern: widestring): widestring;
  function FlxTryStrToDateTime(const S: widestring; out Value: TDateTime; var dFormat: widestring; var HasDate, HasTime: boolean; const DateFormat: widestring=''; const TimeFormat: widestring=''): Boolean;

  function OffsetRange(const CellRange: TXlsCellRange; const DeltaRow, DeltaCol: integer): TXlsCellRange;

  //Returns "A" for column 1, "B"  for 2 and so on
  function EncodeColumn(const C: integer): string;

implementation

function EncodeColumn(const C: integer): string;
var
  Delta: integer;
begin
  Delta:=Ord('Z')-Ord('A')+1;
  if C<=Delta then Result:=chr(Ord('A')+C-1) else
    Result:=EncodeColumn(((C-1) div Delta))+ chr(Ord('A')+(C-1) mod Delta);
end;

{$IFDEF FLX_VCL}
function SearchPathStr(const AFileName: String): String;
var
  FilePart: PChar;
begin
  SetLength(Result, MAX_PATH + 1);

  if SearchPath(nil, PChar(AFileName), '.xls',
                MAX_PATH, PChar(Result), FilePart) <> 0 then
  begin
    SetLength(Result, Length(PChar(Result)));
  end
  else
    Raise Exception.CreateFmt(ErrCantFindFile,[AFileName]);
end; // SearchRecStr
{$ELSE}
function SearchPathStr(const AFileName: String): String;
begin
  //We dont search for templates in linux
  if not FileExists(AFileName) then Raise Exception.CreateFmt(ErrCantFindFile,[AFileName]);
  Result:=AFileName;
end; // SearchRecStr
{$ENDIF}

{$IFDEF  VER130}
function IncludeTrailingPathDelimiter(const S: string): string;
begin
  Result:=IncludeTrailingBackslash(s);
end;

function VarIsClear(const v: variant): boolean;
begin
  Result:=VarIsNull(v);
end;
{$ENDIF}

//Defined as there is not posex on d5
function PosEx(const SubStr, S: string; Offset: Cardinal): Integer;
var
  i,k: integer;
  Equal: boolean;
begin
  i:= Offset;
  Result:=-1;

  while i<=Length(s)-Length(SubStr)+1 do
  begin
    if s[i]=Substr[1] then
    begin
      Equal:=true;
      for k:=2 to Length(Substr) do if s[i+k-1]<>Substr[k] then
      begin
        Equal:=false;
        break;
      end;
      if Equal then
      begin
        Result:=i;
        exit;
      end;
    end;
    inc(i);
  end;
end;
function StringReplaceSkipQuotes(const S, OldPattern, NewPattern: widestring): widestring;
var
  SearchStr, Patt: widestring;
  i,k,z: Integer;
  InQuote: boolean;
begin
  SearchStr := UpperCase(S);
  Patt := UpperCase(OldPattern);

  SetLength(Result, Length(SearchStr)*2);
  InQuote:=false;

  i:=1;k:=1;
  while i<= Length(SearchStr) do
  begin
    if SearchStr[i]='"' then InQuote:= not InQuote;
    if not InQuote and (PosEx(Patt,SearchStr,i)=i) then
    begin
       if k+Length(NewPattern)-1>Length(Result) then SetLength(Result, k+Length(NewPattern)+100);
     for z:=1 to Length(NewPattern) do Result[z+k-1]:=NewPattern[z];
      inc(k, Length(NewPattern));
      inc(i, Length(Patt));
    end else
    begin
      if k>Length(Result) then SetLength(Result, k+100);
      Result[k]:=s[i];
      inc(i);
      inc(k);
    end;
  end;

  SetLength(Result, k-1);
end;


function DateIsOk(s: string; const v: TDateTime): boolean;
  //We have an issue with a string like '1.2.3'
  //If we are using german date separator (".") it will be converted to
  //Feb 1, 2003, which is ok. But, if we use another format, windows will think it
  //is a time, and will convert it to 1:02:03 am. That's why we added this 'patch' function.
var
  p: integer;
  i, err, k: integer;
begin
  Result:= true;
  if (Trunc(v)<>0) then exit;
  s:=s+'.';
  for i:=1 to 3 do
  begin
    p:= pos('.',s);
    if p<=0 then
    begin
      if i=3 then Result:=false;
      exit;
    end;
    val(copy(s,1,p-1), k, err);
    if (err<>0) or (k<0) then exit;
    s:=copy(s,p+1,Length(s));
  end;
  if trim(s)<'' then exit;
  Result:=false;
end;

function FlxTryStrToDateTime(const s:widestring; out Value: TDateTime; var dFormat: Widestring; var HasDate, HasTime: boolean; const DateFormat: widestring=''; const TimeFormat: widestring=''): Boolean;
var
  LResult: HResult;
  aDateFormat, aTimeFormat: widestring;
  {$IFNDEF ConditionalExpressions} //Delphi 5
    v1: olevariant;
  {$ENDIF}
begin
  if DateFormat='' then aDateFormat:=ShortDateFormat else aDateFormat:=DateFormat;
  if TimeFormat='' then aTimeFormat:=ShortTimeFormat else aTimeFormat:=TimeFormat;
  aTimeFormat:=StringReplaceSkipQuotes(aTimeFormat,'AMPM','AM/PM'); //Format AMPM is not recognized by Excel. This is harcoded on sysutils
  {$IFNDEF ConditionalExpressions} //Delphi 5. Doesn't work on kylix
    LResult:=VariantChangeType(v1, s, 0, varDate);
    Value:=v1;
  {$ELSE}
    //////////////////////READ THIS!////////////////////////////////////////////////////////////////////////////////////////
    // If you get an error here with Delphi 6, make sure to install ALL latest Delphi 6 update packs, including RTL3 update
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // available from www.borland.com
    LResult := VarDateFromStr(S, FLX_VAR_LOCALE_USER_DEFAULT, 0, Value);
  {$ENDIF}

  Result:=(LResult = 0) and DateIsOk(s,Value);  //VAR_OK doesnt work on D5;

  //We have a problem with the german date separator "." and a.m. or p.m.
  //so we cant just test for a "." inside a formula to know it includes a date.
  HasDate:=(pos('.', s)>0) or (pos('/',s)>0) or (pos('-',s)>0)   //hate to hard-code this values, but I see not other viable way
          or (pos(DateSeparator, s)>0);
  HasDate:= HasDate and (Trunc(Value)>0);
  HasTime:=(pos(':',s)>0) or (pos(TimeSeparator, s)>0);    //Again... hard-coding :-( At least is isolated here

  if not HasDate and not HasTime then Result:=false;  //Things like "1A" are converted to times, even when it doesn't make sense.
  dFormat:='';
  if HasDate then dFormat:=dFormat+aDateFormat;
  if HasTime then
  begin
    if dFormat<>'' then dFormat:=dFormat+' ';
    dFormat:=dFormat+aTimeFormat;
  end;

end;

function OffsetRange(const CellRange: TXlsCellRange; const DeltaRow, DeltaCol: integer): TXlsCellRange;
begin
  Result:=CellRange;
  inc(Result.Top, DeltaRow);
  inc(Result.Left, DeltaCol);
  inc(Result.Bottom, DeltaRow);
  inc(Result.Right, DeltaCol);
end;

end.







⌨️ 快捷键说明

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