📄 jvfunctions.pas
字号:
begin
if Pivot < 0 then
raise EJVCLException.Create('JvFunctions.MakeYear4Digit: Pivot < 0');
{ map 100 to zero }
if Year = 100 then
Year := 0;
if Pivot = 100 then
Pivot := 0;
// turn 2 digit pivot to 4 digit
if Pivot < 100 then
Pivot := Pivot + 1900;
{ turn 2 digit years to 4 digits }
if (Year >= 0) and (Year < 100) then
begin
Century := (Pivot div 100) * 100;
Result := Year + Century; // give the result the same century as the pivot
if Result < Pivot then
// cannot be lower than the Pivot
Result := Result + 100;
end
else
Result := Year;
end;
function StrIsInteger(const S: string): Boolean;
var
I: Integer;
Ch: Char;
begin
Result := S <> '';
for I := 1 to Length(S) do
begin
Ch := S[I];
if (not CharIsNumber(Ch)) or (Ch = DecimalSeparator) then //Az
begin
Result := False;
Exit;
end;
end;
end;
function StrIsFloatMoney(const Ps: string): Boolean;
var
liLoop, liDots: Integer;
Ch: Char;
begin
Result := True;
liDots := 0;
for liLoop := 1 to Length(Ps) do
begin
{ allow digits, space, Currency symbol and one decimal dot }
Ch := Ps[liLoop];
if Ch = DecimalSeparator then
begin
Inc(liDots);
if liDots > 1 then
begin
Result := False;
Break;
end;
end
else
if not CharIsMoney(Ch) then
begin
Result := False;
Break;
end;
end;
end;
function StrIsDateTime(const Ps: string): Boolean;
const
MIN_DATE_TIME_LEN = 6; {2Jan02 }
MAX_DATE_TIME_LEN = 30; { 30 chars or so in '12 December 1999 12:23:23:00' }
var
liLoop: Integer;
Ch: Char;
liColons, liSlashes, liSpaces, liDigits, liAlpha: Integer;
lbDisqualify: Boolean;
begin
if Length(Ps) < MIN_DATE_TIME_LEN then
begin
Result := False;
Exit;
end;
if Length(Ps) > MAX_DATE_TIME_LEN then
begin
Result := False;
Exit;
end;
lbDisqualify := False;
liColons := 0;
liSlashes := 0;
liSpaces := 0;
liDigits := 0;
liAlpha := 0;
for liLoop := 1 to Length(Ps) do
begin
Ch := Ps[liLoop];
if Ch = ':' then
Inc(liColons)
else
if Ch = AnsiForwardSlash then
Inc(liSlashes)
else
if Ch = AnsiSpace then
Inc(liSpaces)
else
if CharIsDigit(Ch) then
Inc(liDigits)
else
if CharIsAlpha(Ch) then
Inc(liAlpha)
else
begin
// no wierd punctuation in dates!
lbDisqualify := True;
Break;
end;
end;
Result := False;
if not lbDisqualify then
{ a date must have colons and slashes and spaces, but not to many of each }
if (liColons > 0) or (liSlashes > 0) or (liSpaces > 0) then
{ only 2 slashes in "dd/mm/yy" or 3 colons in "hh:mm:ss:ms" or 6 spaces "yy mm dd hh mm ss ms" }
if (liSlashes <= 2) and (liColons <= 3) and (liSpaces <= 6) then
{ must have some digits (min 3 digits, eg in "2 jan 02", max 16 dgits in "01/10/2000 10:10:10:10"
longest month name is 8 chars }
if (liDigits >= 3) and (liDigits <= 16) and (liAlpha <= 10) then
Result := True;
{ define in terms of results - if I can interpret it as a date, then I can }
if Result then
Result := (SafeStrToDateTime(PreformatDateString(Ps)) <> 0);
end;
function PreformatDateString(Ps: string): string;
var
liLoop: Integer;
begin
{ turn any month names to numbers }
{ use the StrReplace in stringfunctions -
the one in JclStrings is badly broken and brings down the app }
for liLoop := Low(LongMonthNames) to High(LongMonthNames) do
Ps := LStrReplace(Ps, LongMonthNames[liLoop], IntToStr(liLoop), False);
{ now that 'January' is gone, catch 'Jan' }
for liLoop := Low(ShortMonthNames) to High(ShortMonthNames) do
Ps := LStrReplace(Ps, ShortMonthNames[liLoop], IntToStr(liLoop), False);
{ remove redundant spaces }
Ps := LStrReplace(Ps, AnsiSpace + AnsiSpace, AnsiSpace, False);
Result := Ps;
end;
function BooleanToInteger(const Pb: Boolean): Integer;
begin
// (p3) this works as well:
// Result := Ord(Pb);
if Pb then
Result := 1
else
Result := 0;
end;
{ from my ConvertFunctions unit }
function StringToBoolean(const Ps: string): Boolean;
const
TRUE_STRINGS: array [1..5] of string = ('True', 't', 'y', 'yes', '1');
var
liLoop: Integer;
begin
Result := False;
for liLoop := Low(TRUE_STRINGS) to High(TRUE_STRINGS) do
if AnsiSameText(Ps, TRUE_STRINGS[liLoop]) then
begin
Result := True;
Break;
end;
end;
function SafeStrToDateTime(const Ps: string): TDateTime;
begin
try
Result := StrToDateTime(PreformatDateString(Ps));
except
on E: EConvertError do
Result := 0.0
else
raise;
end;
end;
function SafeStrToDate(const Ps: string): TDateTime;
begin
try
Result := StrToDate(PreformatDateString(Ps));
except
on E: EConvertError do
Result := 0.0
else
raise;
end;
end;
function SafeStrToTime(const Ps: string): TDateTime;
begin
try
Result := StrToTime(Ps)
except
on E: EConvertError do
Result := 0.0
else
raise;
end;
end;
{ imported from VCLFunctions }
procedure CenterHeight(const pc, pcParent: TControl);
begin
pc.Top := //pcParent.Top +
((pcParent.Height - pc.Height) div 2);
end;
function ToRightOf(const pc: TControl; piSpace: Integer): Integer;
begin
if pc <> nil then
Result := pc.Left + pc.Width + piSpace
else
Result := piSpace;
end;
{ have to do this as it depends what the datekind of the control is}
function DateIsNull(const pdtValue: TDateTime; const pdtKind: TdtKind): Boolean;
begin
Result := False;
case pdtKind of
dtkDateOnly:
Result := pdtValue < 1; //if date only then anything less than 1 is considered null
dtkTimeOnly:
Result := Frac(pdtValue) = NullEquivalentDate; //if time only then anything without a remainder is null
dtkDateTime:
Result := pdtValue = NullEquivalentDate;
end;
end;
function OSCheck(RetVal: Boolean): Boolean;
begin
if not RetVal then
RaiseLastOSError;
Result := RetVal;
end;
function MinimizeName(const Filename: string; Canvas: TCanvas; MaxLen: Integer): string;
var
b: array [0..MAX_PATH] of Char;
R: TRect;
begin
StrCopy(b, PChar(Filename));
R := Rect(0, 0, MaxLen, Canvas.TextHeight('Wq'));
if DrawText(Canvas.Handle, b, Length(Filename), R,
DT_SINGLELINE or DT_MODIFYSTRING or DT_PATH_ELLIPSIS or DT_CALCRECT or DT_NOPREFIX) > 0 then
Result := b
else
Result := Filename;
end;
function RunDLL32(const ModuleName, FuncName, CmdLine: string; WaitForCompletion: Boolean; CmdShow: Integer =
SW_SHOWDEFAULT): Boolean;
var
SI: TStartUpInfo;
PI: TProcessInformation;
S: string;
begin
SI.cb := SizeOf(SI);
GetStartupInfo(SI);
SI.wShowWindow := CmdShow;
S := Format('rundll32.exe %s,%s %s', [ModuleName, FuncName, CmdLine]);
Result := CreateProcess(nil, PChar(S), nil, nil, False, 0, nil, nil, SI, PI);
try
if WaitForCompletion then
Result := WaitForSingleObject(PI.hProcess, INFINITE) <> WAIT_FAILED;
finally
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end;
end;
procedure RunDll32Internal(Wnd: HWnd; const DLLName, FuncName, CmdLine: string; CmdShow: Integer = SW_SHOWDEFAULT);
var
H: THandle;
ErrMode: Cardinal;
P: TRunDLL32Proc;
begin
ErrMode := SetErrorMode(SEM_FAILCRITICALERRORS or SEM_NOOPENFILEERRORBOX);
H := LoadLibrary(PChar(DLLName));
try
if H <> INVALID_HANDLE_VALUE then
begin
P := GetProcAddress(H, PChar(FuncName));
if Assigned(P) then
P(Wnd, H, PChar(CmdLine), CmdShow);
end;
finally
SetErrorMode(ErrMode);
if H <> INVALID_HANDLE_VALUE then
FreeLibrary(H);
end;
end;
function TimeOnly(pcValue: TDateTime): TTime;
begin
Result := Frac(pcValue);
end;
function DateOnly(pcValue: TDateTime): TDate;
begin
Result := Trunc(pcValue);
end;
function HasFlag(a, b: Integer): Boolean;
begin
Result := (a and b) <> 0;
end;
{ compiled from ComCtrls.pas's implmentation section }
function ConvertStates(const State: Integer): TItemStates;
begin
Result := [];
if HasFlag(State, LVIS_ACTIVATING) then
Include(Result, isActivating);
if HasFlag(State, LVIS_CUT) then
Include(Result, isCut);
if HasFlag(State, LVIS_DROPHILITED) then
Include(Result, isDropHilited);
if HasFlag(State, LVIS_FOCUSED) then
Include(Result, isFocused);
if HasFlag(State, LVIS_SELECTED) then
Include(Result, isSelected);
end;
function ChangeHasSelect(const peOld, peNew: TItemStates): Boolean;
begin
Result := (not (isSelected in peOld)) and (isSelected in peNew);
end;
function ChangeHasDeselect(const peOld, peNew: TItemStates): Boolean;
begin
Result := (isSelected in peOld) and (not (isSelected in peNew));
end;
function ChangeHasFocus(const peOld, peNew: TItemStates): Boolean;
begin
Result := (not (isFocused in peOld)) and (isFocused in peNew);
end;
function ChangeHasDefocus(const peOld, peNew: TItemStates): Boolean;
begin
Result := (isFocused in peOld) and (not (isFocused in peNew));
end;
function GetListItemColumn(const pcItem: TListItem; piIndex: Integer): string;
begin
if pcItem = nil then
begin
Result := '';
Exit;
end;
if (piIndex < 0) or (piIndex > pcItem.SubItems.Count) then
begin
Result := '';
Exit;
end;
if piIndex = 0 then
Result := pcItem.Caption
else
Result := pcItem.SubItems[piIndex - 1];
end;
{!! from strFunctions }
function StrDeleteChars(const Ps: string; const piPos: Integer; const piCount: Integer): string;
begin
Result := StrLeft(Ps, piPos - 1) + StrRestOf(Ps, piPos + piCount);
end;
function StrDelete(const psSub, psMain: string): string;
var
liPos: Integer;
begin
Result := psMain;
if psSub = '' then
Exit;
liPos := StrIPos(psSub, psMain);
while liPos > 0 do
begin
Result := StrDeleteChars(Result, liPos, Length(psSub));
liPos := StrIPos(psSub, Result);
end;
end;
type
// (p3) from ShLwAPI
TDLLVersionInfo = packed record
cbSize: DWORD;
dwMajorVersion: DWORD;
dwMinorVersion: DWORD;
dwBuildNumber: DWORD;
dwPlatformID: DWORD;
end;
function GetDLLVersion(const DLLName: string; var pdwMajor, pdwMinor: Integer): Boolean;
var
hDLL, hr: THandle;
pDllGetVersion: function(var Dvi: TDLLVersionInfo): Integer; stdcall;
Dvi: TDLLVersionInfo;
begin
hDLL := LoadLibrary(PChar(DLLName));
if hDLL < 32 then
hDLL := 0;
if hDLL <> 0 then
begin
Result := True;
(* You must get this function explicitly
because earlier versions of the DLL's
don't implement this function.
That makes the lack of implementation
of the function a version marker in itself. *)
@pDllGetVersion := GetProcAddress(hDLL, PChar('DllGetVersion'));
if Assigned(pDllGetVersion) then
begin
FillChar(Dvi, SizeOf(Dvi), #0);
Dvi.cbSize := SizeOf(Dvi);
hr := pDllGetVersion(Dvi);
if hr = 0 then
begin
pdwMajor := Dvi.dwMajorVersion;
pdwMinor := Dvi.dwMinorVersion;
end;
end
else (* If GetProcAddress failed, the DLL is a version previous to the one shipped with IE 3.x. *)
begin
pdwMajor := 4;
pdwMinor := 0;
end;
FreeLibrary(hDLL);
Exit;
end;
Result := False;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -