📄 mmutils.pas
字号:
var
Brush, OldBrush: HBrush;
begin
Brush := CreateSolidBrush(Color);
OldBrush := SelectObject(DC, Brush);
try
PatBlt(DC, aRect.Left, aRect.Top,
aRect.Right-aRect.Left,
aRect.Bottom-aRect.Top, PATCOPY);
finally
Brush := SelectObject(DC, OldBrush);
DeleteObject(Brush);
end;
end;
{=========================================================================}
function WinExecAndWaitEx(FileName: TFileName; TimeOut: DWORD): Boolean;
var
{$IFDEF WIN32}
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
ExCode,Res : DWORD;
{$ELSE}
hAppInstance: THandle;
Msg : TMsg;
aBuf : array[0..255] of Char;
{$ENDIF}
begin
Result := False;
{$IFNDEF WIN32}
hAppInstance := WinExec(StrPCopy(aBuf, FileName), SW_NORMAL);
if (hAppInstance < HINSTANCE_ERROR) then exit
else
repeat
while PeekMessage(Msg, 0, 0, 0, pm_Remove) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
until (GetModuleUsage(hAppInstance) = 0);
Result := True;
{$ELSE}
FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
with StartupInfo do
begin
cb := SizeOf(TStartupInfo);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow := SW_NORMAL;
end;
if CreateProcess(nil,PChar(FileName),nil,nil,False,NORMAL_PRIORITY_CLASS,
nil,nil,StartupInfo,ProcessInfo) then
begin
Res := WaitforSingleObject(ProcessInfo.hProcess, TIMEOUT);
if (Res = WAIT_TIMEOUT) then
begin
TerminateProcess(ProcessInfo.hProcess,0);
CloseHandle(ProcessInfo.hProcess);
Result := False;
end
else
begin
GetExitCodeProcess(ProcessInfo.hProcess, ExCode);
CloseHandle(ProcessInfo.hProcess);
Result := True;
end;
end;
{$ENDIF}
end;
{=========================================================================}
function WinExecAndWait(FileName: TFileName): Boolean;
begin
Result := WinExecAndWaitEx(FileName,INFINITE);
end;
{=========================================================================}
procedure TimeDecode(Time: Longint; var Hour, Min, Sec, MSec: Word);
Var
MinCount, MSecCount: Word;
begin
if Time > 0 then
begin
DivMod32(Time, 60000, MinCount, MSecCount);
DivMod32(MinCount, 60, Hour, Min);
DivMod32(MSecCount, 1000, Sec, MSec);
end
else
begin
Hour := 0;
Min := 0;
Sec := 0;
MSec := 0;
end;
end;
{=========================================================================}
function TimeToMask(Time: Longint): string;
begin
Result := Format('%2.2d%2.2d%5.5d',
[Time div 3600000,
Time mod 3600000 div 60000,
Time mod 60000]);
end;
{=========================================================================}
function MaskToTime(Mask: string): Longint;
begin
Result := StrToIntDef(Mask, 0);
Result := (Result div 10000000)*3600000+
((Result mod 10000000) mod 100000) +
((Result mod 10000000) div 100000) * 60000;
end;
{=========================================================================}
function CheckFloat(const S: string): string;
var
i: integer;
begin
Result := S;
for i := 1 to Length(Result) do
begin
if (Result[i] in ['.',',',';']) and
(Result[i] <> DecimalSeparator) then
Result[i] := DecimalSeparator;
end;
end;
{$IFDEF WIN32}
{=========================================================================}
function TimeToString64Ex(Time: int64; MSec: Boolean): string;
begin
if MSec then
begin
if Time >= 86400000 then
Result := Format('%d:%2.2d:%2.2d:%2.2d.%3.3d',[int64Div32(Time,86400000),
int64Div32(int64Mod32(Time,86400000),3600000),
int64Div32(int64Mod32(Time,3600000),60000),
int64Div32(int64Mod32(Time,60000),1000),
int64Mod32(Time,1000)])
else if Time >= 3600000 then
Result := Format('%d:%2.2d:%2.2d.%3.3d',[int64Div32(Time,3600000),
int64Div32(int64Mod32(Time,3600000),60000),
int64Div32(int64Mod32(Time,60000),1000),
int64Mod32(Time,1000)])
else
Result := Format('%d:%2.2d.%3.3d',[int64Div32(Time,60000),
int64Div32(int64Mod32(Time,60000),1000),
int64Mod32(Time,1000)]);
end
else
begin
if Time >= 86400000 then
Result := Format('%d:%2.2d:%2.2d:%2.2d',[int64Div32(Time,86400000),
int64Div32(int64Mod32(Time,86400000),3600000),
int64Div32(int64Mod32(Time,3600000),60000),
int64Div32(int64Mod32(Time,60000),1000)])
else if Time >= 3600000 then
Result := Format('%d:%2.2d:%2.2d',[int64Div32(Time,3600000),
int64Div32(int64Mod32(Time,3600000),60000),
int64Div32(int64Mod32(Time,60000),1000)])
else
Result := Format('%d:%2.2d',[int64Div32(Time,60000),
int64Div32(int64Mod32(Time,60000),1000)]);
end;
end;
{=========================================================================}
function TimeToString64(LowTime,HighTime: Cardinal; MSec: Boolean): string;
var
Time: int64;
begin
asm
mov dword ptr Time[0], eax
mov dword ptr Time[4], edx
end;
Result := TimeToString64Ex(Time, MSec);
end;
{$ENDIF}
{=========================================================================}
function TimeToStringEx(Time: MM_int64; MSec: Boolean): string;
begin
if MSec then
begin
{$IFDEF DELPHI4}
if Time >= 86400000 then
Result := Format('%d:%2.2d:%2.2d:%2.2d.%3.3d',[Time div 86400000,
(Time mod 86400000) div 3600000,
(Time mod 3600000) div 60000,
(Time mod 60000) div 1000,
Time mod 1000])
else
{$ENDIF}
if Time >= 3600000 then
Result := Format('%d:%2.2d:%2.2d.%3.3d',[Time div 3600000,
(Time mod 3600000) div 60000,
(Time mod 60000) div 1000,
Time mod 1000])
else
Result := Format('%d:%2.2d.%3.3d',[Time div 60000,
(Time mod 60000) div 1000,
Time mod 1000]);
end
else
begin
{$IFDEF DELPHI4}
if Time >= 86400000 then
Result := Format('%d:%2.2d:%2.2d:%2.2d',[Time div 86400000,
(Time mod 86400000) div 3600000,
(Time mod 3600000) div 60000,
(Time mod 60000) div 1000])
else
{$ENDIF}
if Time >= 3600000 then
Result := Format('%d:%2.2d:%2.2d',[Time div 3600000,
(Time mod 3600000) div 60000,
(Time mod 60000) div 1000])
else
Result := Format('%d:%2.2d',[Time div 60000,
(Time mod 60000) div 1000]);
end;
end;
{=========================================================================}
function TimeToString(Time: MM_int64): string;
begin
Result := TimeToStringEx(Time,True);
end;
{=========================================================================}
function StrToFloatEx(S: string; Limiter: Char): Extended;
var
idx: integer;
begin
case Limiter of
',': idx := Pos('.',S);
'.': idx := Pos(',',S);
else idx := -1;
end;
if (idx > 0) then
begin
if (Limiter = '.') then
S[idx] := '.'
else
S[idx] := ',';
end;
Result:= StrToFloat(S);
end;
{=========================================================================}
function DBToLin(DB: Float): Float;
begin
Result := pow(10,DB/20);
end;
{=========================================================================}
function LinToDB(lin: Float): Float;
begin
if lin < 1.0e-6 then Result := -120
else Result := log10(abs(lin))*20;
end;
{=========================================================================}
function DBToVolume(DB: Float; Base: Longint): Longint;
begin
{ if (DB = Base) then
Result := Base
else
}
Result := Round(Base/pow(10,-DB/20));
end;
{=========================================================================}
function VolumeToDB(Volume, Base: Longint): Float;
begin
if (Volume = 0) then Result := -110.0
else
begin
Result := Log10(abs(Volume)/Max(Base,1))*20;
end;
end;
{=========================================================================}
function VolumeToStringShort(Volume, Base: Longint; Precision: integer): string;
var
Value: Float;
begin
if (Volume = 0) then Result := '-Inf'
else
begin
Value := Log10(abs(Volume)/Max(Base,1))*20;
Result := Format('%2.*f',[Precision,Value]);
end;
end;
{=========================================================================}
function VolumeToString(Volume, Base: Longint; Precision: integer): string;
begin
Result := VolumeToStringShort(Volume, Base, Precision) + ' dB';
end;
{=========================================================================}
function PanningToString(Panning, Range: Longint): string;
begin
Result := Format('%d:%d',[(Range-Panning)*50 div Range,
(Panning+Range)*50 div Range]);
end;
{=========================================================================}
procedure CalcVolume(Base,Volume,Panning: Longint; var Left, Right: Longint);
begin
if Panning > 0 then
begin
Left := MulDiv((Base-Panning),Volume,Base);
Right := Volume;
end
else
begin
Left := Volume;
Right := MulDiv((Base+Panning),Volume,Base);
end;
end;
{=========================================================================}
function CombineVolume(Vol1,Vol2,Base: Longint): Longint;
begin
Result := Min(MulDiv(Vol1,Vol2,Base),Base);
end;
{=========================================================================}
function FormatBigNumber(dw: Longint): String;
begin
{ this is ugly... }
if (dw >= 1000000000) then
begin
FmtStr(Result, '%d.%3.3d.%3.3d.%3.3d',
[(dw div 1000000000),
(dw mod 1000000000) div 1000000,
(dw mod 1000000) div 1000,
(dw mod 1000)]);
end
else if (dw >= 1000000) then
begin
FmtStr(Result, '%d.%3.3d.%3.3d',
[(dw div 1000000),
(dw mod 1000000) div 1000,
(dw mod 1000)]);
end
else if (dw >= 1000) then
begin
FmtStr(Result, '%d.%3.3d',
[(dw div 1000),
(dw mod 1000)]);
end
else
begin
FmtStr(Result, '%d', [dw]);
end;
end;
{=========================================================================}
function BytesToString(Bytes: Comp): string;
var
OldSep: Char;
begin
OldSep := DecimalSeparator;
DecimalSeparator := '.';
if (Bytes >= 1024*1024*1024) then
Result := Format('%.1f Gb',[Bytes/(1024*1024*1024)])
else if (Bytes >= 1000*1024) then
Result := Format('%.1f Mb',[Bytes/(1024*1024)])
else
Result := Format('%.1f Kb',[Bytes/1024]);
DecimalSeparator := OldSep;
end;
{=========================================================================}
procedure DrawRubberband(Sender: TObject; aRect: TRect);
var
DC: HDC;
PtA, PtB: TPoint;
begin
if Sender is TControl then
with (Sender as TControl) do
begin
DC := GetDC(0);
if (aRect.Left <> 0) or (aRect.Top <> 0) or
(aRect.Right <> 0) or (aRect.Bottom <> 0) then
begin
PtA := ClientToScreen(Point(aRect.Left, aRect.Top));
PtB := ClientToScreen(Point(aRect.Right, aRect.Bottom));
{$IFDEF WIN32}
if PtA.X > PtB.X then SwapLong(PtA.X,PtB.X);
if PtA.Y > PtB.Y then SwapLong(PtA.Y,PtB.Y);
{$ELSE}
if PtA.X > PtB.X then SwapInt(PtA.X,PtB.X);
if PtA.Y > PtB.Y then SwapInt(PtA.Y,PtB.Y);
{$ENDIF}
DrawFocusRect(DC, Rect(PtA.X, PtA.Y, PtB.X, PtB.Y));
end;
ReleaseDC(0,DC);
end;
end;
{============
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -