📄 frxutils.pas
字号:
procedure frxInfoMsg(const Text: String);
begin
Application.MessageBox(PChar(Text), PChar(frxResources.Get('mbInfo')),
mb_Ok + mb_IconInformation);
end;
function frxIsValidFloat(const Value: string): Boolean;
begin
Result := True;
try
frxStrToFloat(Value);
except
Result := False;
end;
end;
procedure frxAssignImages(Bitmap: TBitmap; dx, dy: Integer;
ImgList1: TImageList; ImgList2: TImageList = nil);
var
b: TBitmap;
x, y: Integer;
Done: Boolean;
begin
b := TBitmap.Create;
b.Width := dx;
b.Height := dy;
x := 0; y := 0;
repeat
b.Canvas.CopyRect(Rect(0, 0, dx, dy), Bitmap.Canvas, Rect(x, y, x + dx, y + dy));
Done := y > Bitmap.Height;
if not Done then
begin
ImgList1.AddMasked(b, b.TransparentColor);
if ImgList2 <> nil then
begin
Inc(x, dx);
b.Canvas.CopyRect(Rect(0, 0, dx, dy), Bitmap.Canvas, Rect(x, y, x + dx, y + dy));
ImgList2.AddMasked(b, b.TransparentColor);
end;
end;
Inc(x, dx);
if x >= Bitmap.Width then
begin
x := 0;
Inc(y, dy);
end;
until Done;
b.Free;
end;
procedure frxDrawTransparent(Canvas: TCanvas; x, y: Integer; bmp: TBitmap);
var
img: TImageList;
begin
if Assigned(bmp) then
begin
img := TImageList.Create(nil);
try
img.Width := bmp.Width;
img.Height := bmp.Height;
img.AddMasked(bmp, bmp.TransparentColor);
img.Draw(Canvas, x, y, 0);
img.Clear;
finally
img.Free;
end;
end;
end;
procedure DrawBitmap(aCanvas: TCanvas; Dest: TRect; Bitmap: TBitmap);
var
Info: PBitmapInfo;
HInfo: HGLOBAL;
InfoSize: DWord;
Image: Pointer;
HImage: HGLOBAL;
ImageSize: DWord;
begin
with Bitmap do
begin
GetDIBSizes(Handle, InfoSize, ImageSize);
HInfo := GlobalAlloc(GMEM_MOVEABLE or GMEM_SHARE, InfoSize);
Info := PBitmapInfo(GlobalLock(HInfo));
try
HImage := GlobalAlloc(GMEM_MOVEABLE or GMEM_SHARE, ImageSize);
Image := Pointer(GlobalLock(HImage));
try
GetDIB(Handle, Palette, Info^, Image^);
SetStretchBltMode(ACanvas.Handle, STRETCH_HALFTONE);
with Info^.bmiHeader do
StretchDIBits(aCanvas.Handle, Dest.Left, Dest.Top,
Dest.RIght - Dest.Left, Dest.Bottom - Dest.Top,
0, 0, biWidth, biHeight, Image, Info^, DIB_RGB_COLORS, SRCCOPY);
finally
GlobalUnlock(HImage);
GlobalFree(HImage);
end;
finally
GlobalUnlock(HInfo);
GlobalFree(HInfo);
end;
end;
end;
procedure frxDrawGraphic(Canvas: TCanvas; DestRect: TRect; aGraph: TGraphic;
IsPrinting: Boolean);
var
Bitmap: TBitmap;
begin
if (aGraph is TMetaFile) or not IsPrinting then
Canvas.StretchDraw(DestRect, aGraph)
else
begin
Bitmap := TBitmap.Create;
try
Bitmap.Width := aGraph.Width;
Bitmap.Height := aGraph.Height;
Bitmap.PixelFormat := pf32Bit;
Bitmap.Canvas.Draw(0, 0, aGraph);
DrawBitmap(Canvas, DestRect, Bitmap);
finally
Bitmap.Free;
end;
end
end;
procedure frxParsePageNumbers(const PageNumbers: String; List: TStrings;
Total: Integer);
var
i, j, n1, n2: Integer;
s: String;
IsRange: Boolean;
begin
List.Clear;
s := PageNumbers;
while Pos(' ', s) <> 0 do
Delete(s, Pos(' ', s), 1);
if s = '' then Exit;
if s[Length(s)] = '-' then
s := s + IntToStr(Total);
s := s + ',';
i := 1; j := 1; n1 := 1;
IsRange := False;
while i <= Length(s) do
begin
if s[i] = ',' then
begin
n2 := StrToInt(Copy(s, j, i - j));
j := i + 1;
if IsRange then
while n1 <= n2 do
begin
List.Add(IntToStr(n1));
Inc(n1);
end
else
List.Add(IntToStr(n2));
IsRange := False;
end
else if s[i] = '-' then
begin
IsRange := True;
n1 := StrToInt(Copy(s, j, i - j));
j := i + 1;
end;
Inc(i);
end;
end;
function HTMLRGBColor(Color: TColor): string;
var
TheRgbValue : TColorRef;
begin
TheRgbValue := ColorToRGB(Color);
Result := '#' + Format('%.2x%.2x%.2x', [GetRValue(TheRGBValue), GetGValue(TheRGBValue), GetBValue(TheRGBValue)]);
end;
procedure ConvertOneItem(Item: TCollectionItem; ToAnsi: Boolean);
var
i: Integer;
TypeInfo: PTypeInfo;
PropCount: Integer;
PropList: PPropList;
function Convert(const Value: String): String;
var
i: Integer;
begin
Result := '';
i := 1;
while i <= Length(Value) do
begin
if ToAnsi then
begin
if Value[i] >= #128 then
Result := Result + #1 + Chr(Ord(Value[i]) - 128) else
Result := Result + Value[i];
end
else
begin
if (Value[i] = #1) and (i < Length(Value)) then
begin
Result := Result + Chr(Ord(Value[i + 1]) + 128);
Inc(i);
end
else
Result := Result + Value[i];
end;
Inc(i);
end;
end;
procedure DoStrProp;
var
Value, NewValue: String;
begin
Value := GetStrProp(Item, PropList[i]);
NewValue := Convert(Value);
if Value <> NewValue then
SetStrProp(Item, PropList[i], NewValue);
end;
procedure DoVariantProp;
var
Value: Variant;
begin
Value := GetVariantProp(Item, PropList[i]);
if (TVarData(Value).VType = varString) or (TVarData(Value).VType = varOleStr)
{$IFDEF Delphi12} or (TVarData(Value).VType = varOleStr){$ENDIF} then
begin
Value := Convert(Value);
SetVariantProp(Item, PropList[i], Value);
end;
end;
begin
TypeInfo := Item.ClassInfo;
PropCount := GetTypeData(TypeInfo).PropCount;
GetMem(PropList, PropCount * SizeOf(PPropInfo));
GetPropInfos(TypeInfo, PropList);
try
for i := 0 to PropCount - 1 do
begin
case PropList[i].PropType^.Kind of
tkString, tkLString, tkWString:
DoStrProp;
tkVariant:
DoVariantProp;
end;
end;
finally
FreeMem(PropList, PropCount * SizeOf(PPropInfo));
end;
end;
procedure frxWriteCollection(Collection: TCollection; Writer: TWriter;
Owner: TfrxComponent);
var
i: Integer;
xs: TfrxXMLSerializer;
s: String;
{$IFDEF Delphi12}
{$ELSE}
vt: TValueType;
l: Integer;
{$ENDIF}
begin
if Owner.IsWriting then
begin
{ called from SaveToStream }
Writer.WriteListBegin;
xs := TfrxXMLSerializer.Create(nil);
try
xs.Owner := Owner.Report;
for i := 0 to Collection.Count - 1 do
begin
Writer.WriteListBegin;
{$IFDEF Delphi12}
s := {UTF8Encode(}xs.ObjToXML(Collection.Items[i]);
Writer.WriteString(s);
Writer.WriteListEnd;
{$ELSE}
s := xs.ObjToXML(Collection.Items[i]);
vt := vaLString;
Writer.Write(vt, SizeOf(vt));
l := Length(s);
Writer.Write(l, SizeOf(l));
Writer.Write(s[1], l);
Writer.WriteListEnd;
{$ENDIF}
end;
finally
Writer.WriteListEnd;
xs.Free;
end;
end
else
begin
{ called from Delphi streamer }
Writer.WriteCollection(Collection);
end;
end;
procedure frxReadCollection(Collection: TCollection; Reader: TReader;
Owner: TfrxComponent);
var
i: Integer;
vt: TValueType;
xs: TfrxXMLSerializer;
s: String;
Item: TCollectionItem;
NeedFree: Boolean;
begin
vt := Reader.ReadValue;
if vt <> vaCollection then
begin
{ called from LoadFromStream }
NeedFree := False;
xs := nil;
if Owner.Report <> nil then
xs := TfrxXMLSerializer(Owner.Report.XMLSerializer);
if xs = nil then
begin
xs := TfrxXMLSerializer.Create(nil);
xs.Owner := Owner.Report;
NeedFree := True;
end;
try
Collection.Clear;
while not Reader.EndOfList do
begin
Reader.ReadListBegin;
Item := Collection.Add;
{$IFDEF Delphi12}
//UTF8Decode()
s := Reader.ReadString;
{$ELSE}
s := Reader.ReadString;
{$ENDIF}
if NeedFree then
xs.ReadPersistentStr(Owner.Report, Item, s)
else
xs.XMLToObj(s, Item);
Reader.ReadListEnd;
end;
finally
Reader.ReadListEnd;
if NeedFree then
xs.Free;
end;
end
else
begin
{ called from Delphi streamer }
Reader.ReadCollection(Collection);
for i := 0 to Collection.Count - 1 do
ConvertOneItem(Collection.Items[i], False);
end;
end;
function GetTemporaryFolder: String;
var
Path: String;
begin
Setlength(Path, MAX_PATH);
SetLength(Path, GetTempPath(MAX_PATH, @Path[1]));
{$IFDEF Delphi12}
Result := StrPas(PWideChar(@Path[1]));
{$ELSE}
Result := StrPas(@Path[1]);
{$ENDIF}
end;
function GetTempFile: String;
var
Path: String;
FileName: String;
begin
SetLength(Path, MAX_PATH);
SetLength(Path, GetTempPath(MAX_PATH, @Path[1]));
SetLength(FileName, MAX_PATH);
GetTempFileName(@Path[1], PChar('fr'), 0, @FileName[1]);
{$IFDEF Delphi12}
Result := StrPas(PWideChar(@FileName[1]));
{$ELSE}
Result := StrPas(@FileName[1]);
{$ENDIF}
end;
function frxCreateTempFile(const TempDir: String): String;
var
Path: String;
FileName: String;
begin
Path := TempDir;
if (Path <> '') and (Path[Length(Path)] <> '\') then
Path := Path + '\';
SetLength(FileName, MAX_PATH);
if Path = '' then
begin
SetLength(Path, MAX_PATH);
SetLength(Path, GetTempPath(MAX_PATH, @Path[1]));
end
else begin
Path := Path + #0;
SetLength(Path, MAX_PATH);
end;
GetTempFileName(@Path[1], PChar('fr'), 0, @FileName[1]);
{$IFDEF Delphi12}
Result := StrPas(PWideChar(@FileName[1]));
{$ELSE}
Result := StrPas(@FileName[1]);
{$ENDIF}
end;
function GetAppFileName: String;
var
fName: String;
nsize: cardinal;
begin
nsize := MAX_PATH;
SetLength(fName,nsize);
SetLength(fName, GetModuleFileName(hinstance, pchar(fName), nsize));
Result := fName;
end;
function GetAppPath: String;
begin
Result := ExtractFilePath(GetAppFileName);
end;
{$IFNDEF Delphi7}
function frFloat2Str(const Value: Extended; const Prec: Integer = 2): String;
var
i: Integer;
IntVal: Integer;
begin
IntVal := Trunc(Value);
if IntVal <> Value then
Result := Format('%.' + IntToStr(Prec)+ 'f', [Value])
else
Result := IntToStr(IntVal);
if DecimalSeparator <> '.' then
begin
i := Pos(DecimalSeparator, Result);
if i > 0 then
Result[i] := '.';
end;
end;
{$ELSE}
function frFloat2Str(const Value: Extended; const Prec: Integer = 2; const Sep: Char = '.'): String;
var
FormatSettings: TFormatSettings;
Buffer: array[0..63] of Char;
begin
FormatSettings.DecimalSeparator := Sep;
FormatSettings.ThousandSeparator := Char(0);
SetString(Result, Buffer, FloatToText(Buffer, Value, fvExtended,
ffFixed, 32, Prec, FormatSettings));
end;
{$ENDIF}
function frxReverseString(const AText: string): string;
var
I: Integer;
P: PChar;
begin
SetLength(Result, Length(AText));
P := PChar(Result);
for I := Length(AText) downto 1 do
begin
P^ := AText[I];
Inc(P);
end;
end;
function ChangeChars(const Str: string; FromChar, ToChar: Char): string;
var
I: Integer;
begin
Result := Str;
for I := 1 to Length(Result) do
if Result[I] = FromChar then
Result[I] := ToChar;
end;
function frxUnixPath2WinPath(const Path: string): string;
begin
Result := ChangeChars(Path, '/', '\');
end;
{$IFNDEF Delphi6}
function DirectoryExists(const Name: string): Boolean;
var
Code: Integer;
begin
Code := GetFileAttributes(PChar(Name));
Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
end;
{$ENDIF}
{$IFNDEF Delphi7}
function PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer;
var
I,X: Integer;
Len, LenSubStr: Integer;
begin
if Offset = 1 then
Result := Pos(SubStr, S)
else
begin
I := Offset;
LenSubStr := Length(SubStr);
Len := Length(S) - LenSubStr + 1;
while I <= Len do
begin
if S[I] = SubStr[1] then
begin
X := 1;
while (X < LenSubStr) and (S[I + X] = SubStr[X + 1]) do
Inc(X);
if (X = LenSubStr) then
begin
Result := I;
exit;
end;
end;
Inc(I);
end;
Result := 0;
end;
end;
{$ENDIF}
end.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -