📄 frxunicodeutils.pas
字号:
PWStr^.Obj := nil;
Result := FWideStringList.Add(PWStr);
end;
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.Delete(Index: Integer);
var
PWStr: ^TWString;
begin
PWStr := FWideStringList.Items[Index];
if PWStr <> nil then
Dispose(PWStr);
FWideStringList.Delete(Index);
end;
function {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.IndexOf(const S: WideString): Integer;
var
Index: Integer;
PWStr: ^TWString;
begin
Result := -1;
for Index := 0 to FWideStringList.Count -1 do
begin
PWStr := FWideStringList.Items[Index];
if PWStr <> nil then
begin
if S = PWStr^.WString then
begin
Result := Index;
break;
end;
end;
end;
end;
{$IFDEF Delphi10}
function TfrxWideStrings.GetCount: Integer;
begin
Result := FWideStringList.Count;
end;
{$ELSE}
function TWideStrings.Count: Integer;
begin
Result := FWideStringList.Count;
end;
{$ENDIF}
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.Insert(Index: Integer; const S: WideString);
var
PWStr: ^TWString;
begin
if((Index < 0) or (Index > FWideStringList.Count)) then
raise Exception.Create('Wide String Out of Bounds');
if Index < FWideStringList.Count then
begin
PWStr := FWideStringList.Items[Index];
if PWStr <> nil then
PWStr.WString := S;
end
else
Add(S);
end;
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.AddStrings(Strings: TWideStrings);
var
I: Integer;
begin
for I := 0 to Strings.Count - 1 do
AddObject(Strings[I], Strings.Objects[I]);
end;
function {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.AddObject(const S: WideString; AObject: TObject): Integer;
begin
Result := Add(S);
PutObject(Result, AObject);
end;
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.Assign(Source: TPersistent);
var
I: Integer;
begin
if Source is TWideStrings then
begin
Clear;
AddStrings(TWideStrings(Source));
end
else if Source is TStrings then
begin
Clear;
for I := 0 to TStrings(Source).Count - 1 do
AddObject(TStrings(Source)[I], TStrings(Source).Objects[I]);
end
else
inherited Assign(Source);
end;
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.AssignTo(Dest: TPersistent);
var
I: Integer;
begin
if Dest is TWideStrings then
Dest.Assign(Self)
else if Dest is TStrings then
begin
TStrings(Dest).BeginUpdate;
try
TStrings(Dest).Clear;
for I := 0 to Count - 1 do
TStrings(Dest).AddObject(Strings[I], Objects[I]);
finally
TStrings(Dest).EndUpdate;
end;
end
else
inherited AssignTo(Dest);
end;
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.DefineProperties(Filer: TFiler);
begin
// compatibility
Filer.DefineProperty('Strings', ReadData, nil, Count > 0);
{$IFDEF Delphi12}
Filer.DefineProperty('UTF8', ReadDataWOld, nil, Count > 0);
Filer.DefineProperty('UTF8W', ReadDataW, WriteDataW, Count > 0);
{$ELSE}
Filer.DefineProperty('UTF8', ReadDataW, WriteDataW, Count > 0);
{$ENDIF}
end;
function {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.GetTextStr: WideString;
var
I, L, Size, Count: Integer;
P: PWideChar;
S, LB: WideString;
begin
Count := FWideStringList.Count;
Size := 0;
LB := sLineBreak;
for I := 0 to Count - 1 do Inc(Size, Length(Get(I)) + Length(LB));
SetString(Result, nil, Size);
P := Pointer(Result);
for I := 0 to Count - 1 do
begin
S := Get(I);
L := Length(S);
if L <> 0 then
begin
System.Move(Pointer(S)^, P^, L * SizeOf(WideChar));
Inc(P, L);
end;
L := Length(LB);
if L <> 0 then
begin
System.Move(Pointer(LB)^, P^, L * SizeOf(WideChar));
Inc(P, L);
end;
end;
end;
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.LoadFromFile(const FileName: WideString);
var
Stream: TStream;
begin
Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.LoadFromStream(Stream: TStream);
var
Size: Integer;
S: WideString;
ansiS: String;
sign: Word;
begin
Size := Stream.Size - Stream.Position;
sign := 0;
if Size > 2 then
Stream.Read(sign, 2);
if sign = $FEFF then
begin
Dec(Size, 2);
SetLength(S, Size div 2);
Stream.Read(S[1], Size);
SetTextStr(S);
end
else
begin
Stream.Seek(-2, soFromCurrent);
SetLength(ansiS, Size);
Stream.Read(ansiS[1], Size);
SetTextStr(ansiS);
end;
end;
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.LoadFromWStream(Stream: TStream);
var
Size: Integer;
S: WideString;
begin
Size := Stream.Size - Stream.Position;
SetLength(S, Size div 2);
Stream.Read(S[1], Size);
SetTextStr(S);
end;
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.ReadData(Reader: TReader);
begin
Clear;
Reader.ReadListBegin;
while not Reader.EndOfList do
if Reader.NextValue in [vaString, vaLString] then
Add(Reader.ReadString) {TStrings compatiblity}
else
Add(Reader.ReadWideString);
Reader.ReadListEnd;
end;
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.ReadDataW(Reader: TReader);
begin
Clear;
Reader.ReadListBegin;
while not Reader.EndOfList do
{$IFDEF Delphi12}
Add(Reader.ReadString);
{$ELSE}
Add(Utf8Decode(Reader.ReadString));
{$ENDIF}
Reader.ReadListEnd;
end;
{$IFDEF Delphi12}
procedure TfrxWideStrings.ReadDataWOld(Reader: TReader);
begin
Clear;
Reader.ReadListBegin;
while not Reader.EndOfList do
Add(Utf8Decode(AnsiString(Reader.ReadString)));
Reader.ReadListEnd;
end;
{$ENDIF}
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.SaveToFile(const FileName: WideString);
var
Stream: TStream;
begin
Stream := TFileStream.Create(FileName, fmCreate);
try
SaveToStream(Stream);
finally
Stream.Free;
end;
end;
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.SaveToStream(Stream: TStream);
var
SW: WideString;
begin
SW := GetTextStr;
Stream.WriteBuffer(PWideChar(SW)^, Length(SW) * SizeOf(WideChar));
end;
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.SetTextStr(const Value: WideString);
var
P, Start: PWideChar;
S: WideString;
begin
Clear;
P := Pointer(Value);
if P <> nil then
while P^ <> #0 do
begin
Start := P;
{$IFDEF Delphi12}
while not (CharInSet(P^, [WideChar(#0), WideChar(#10), WideChar(#13)])) and (P^ <> WideLineSeparator) do
{$ELSE}
while not (P^ in [WideChar(#0), WideChar(#10), WideChar(#13)]) and (P^ <> WideLineSeparator) do
{$ENDIF}
Inc(P);
SetString(S, Start, P - Start);
Add(S);
if P^ = #13 then Inc(P);
if P^ = #10 then Inc(P);
if P^ = WideLineSeparator then Inc(P);
end;
end;
procedure {$IFDEF Delphi10}TfrxWideStrings{$ELSE}TWideStrings{$ENDIF}.WriteDataW(Writer: TWriter);
var
I: Integer;
begin
Writer.WriteListBegin;
for I := 0 to Count - 1 do
{$IFDEF Delphi12}
Writer.WriteString(Get(I));
{$ELSE}
Writer.WriteString(Utf8Encode(Get(I)));
{$ENDIF}
Writer.WriteListEnd;
end;
function TranslateCharsetInfo(lpSrc: DWORD; var lpCs: TCharsetInfo;
dwFlags: DWORD): BOOL; stdcall; external gdi32 name 'TranslateCharsetInfo';
function CharSetToCodePage(ciCharset: DWORD): Cardinal;
var
C: TCharsetInfo;
begin
if ciCharset = DEFAULT_CHARSET then
Result := GetACP
else if ciCharset = MAC_CHARSET then
Result := CP_MACCP
else if ciCharset = OEM_CHARSET then
Result := CP_OEMCP// GetACP
else
begin
Win32Check(TranslateCharsetInfo(ciCharset, C, TCI_SRCCHARSET));
Result := C.ciACP;
end;
end;
function AnsiToUnicode(const s: AnsiString; Charset: UINT; CodePage: Integer): WideString;
var
InputLength, OutputLength: Integer;
begin
Result := '';
if CodePage = 0 then
CodePage := CharSetToCodePage(Charset);
InputLength := Length(S);
OutputLength := MultiByteToWideChar(CodePage, 0, PAnsiChar(S), InputLength, nil, 0);
if OutputLength <> 0 then
begin
SetLength(Result, OutputLength);
MultiByteToWideChar(CodePage, 0, PAnsiChar(S), InputLength, PWideChar(Result), OutputLength);
end;
end;
function _UnicodeToAnsi(const WS: WideString; Charset: UINT; CodePage: Integer): AnsiString;
var
InputLength,
OutputLength: Integer;
begin
Result := '';
if CodePage = 0 then
CodePage := CharSetToCodePage(Charset);
InputLength := Length(WS);
OutputLength := WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, nil, 0, nil, nil);
if OutputLength <> 0 then
begin
SetLength(Result, OutputLength);
WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, PAnsiChar(Result), OutputLength, nil, nil);
end;
end;
function GetLocalByCharSet(Charset: UINT): Cardinal;
begin
case Charset of
EASTEUROPE_CHARSET: Result := $0405;//$040e
RUSSIAN_CHARSET: Result := $0419;
GREEK_CHARSET: Result := $0408;
TURKISH_CHARSET: Result := $041F;
HEBREW_CHARSET: Result := $040D;
ARABIC_CHARSET: Result := $3401;
BALTIC_CHARSET: Result := $0425;
VIETNAMESE_CHARSET: Result := $042A;
JOHAB_CHARSET: Result := $0812;
THAI_CHARSET: Result := $041E;
SHIFTJIS_CHARSET: Result := $0411;
GB2312_CHARSET: Result := $0804;
HANGEUL_CHARSET: Result := $0412;
CHINESEBIG5_CHARSET: Result := $0C04;
else
Result := GetThreadLocale;
end;
end;
end.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -