📄 vclutils.pas
字号:
Animation: Boolean;
begin
Animation := GetAnimation;
if Animation then SetAnimation(False);
ShowWindow(Handle, CmdShow);
if Animation then SetAnimation(True);
end;
{$ELSE}
procedure ShowWinNoAnimate(Handle: HWnd; CmdShow: Integer);
begin
ShowWindow(Handle, CmdShow);
end;
procedure SwitchToThisWindow(Wnd: HWnd; Restore: Bool); far; external 'USER'
index 172;
{$ENDIF WIN32}
procedure SwitchToWindow(Wnd: HWnd; Restore: Boolean);
begin
if IsWindowEnabled(Wnd) then begin
{$IFDEF WIN32}
SetForegroundWindow(Wnd);
if Restore and IsWindowVisible(Wnd) then begin
if not IsZoomed(Wnd) then
SendMessage(Wnd, WM_SYSCOMMAND, SC_RESTORE, 0);
SetFocus(Wnd);
end;
{$ELSE}
SwitchToThisWindow(Wnd, Restore);
{$ENDIF}
end;
end;
function GetWindowParent(Wnd: HWnd): HWnd;
begin
{$IFDEF WIN32}
Result := GetWindowLong(Wnd, GWL_HWNDPARENT);
{$ELSE}
Result := GetWindowWord(Wnd, GWW_HWNDPARENT);
{$ENDIF}
end;
procedure ActivateWindow(Wnd: HWnd);
begin
if Wnd <> 0 then begin
ShowWinNoAnimate(Wnd, SW_SHOW);
{$IFDEF WIN32}
SetForegroundWindow(Wnd);
{$ELSE}
SwitchToThisWindow(Wnd, True);
{$ENDIF}
end;
end;
{$IFDEF CBUILDER}
function FindPrevInstance(const MainFormClass: ShortString;
const ATitle: string): HWnd;
{$ELSE}
function FindPrevInstance(const MainFormClass, ATitle: string): HWnd;
{$ENDIF CBUILDER}
var
BufClass, BufTitle: PChar;
begin
Result := 0;
if (MainFormClass = '') and (ATitle = '') then Exit;
BufClass := nil; BufTitle := nil;
if (MainFormClass <> '') then BufClass := StrPAlloc(MainFormClass);
if (ATitle <> '') then BufTitle := StrPAlloc(ATitle);
try
Result := FindWindow(BufClass, BufTitle);
finally
StrDispose(BufTitle);
StrDispose(BufClass);
end;
end;
{$IFDEF WIN32}
function WindowsEnum(Handle: HWnd; Param: Longint): Bool; export; stdcall;
begin
if WindowClassName(Handle) = 'TAppBuilder' then begin
Result := False;
PLongint(Param)^ := 1;
end
else Result := True;
end;
{$ENDIF}
{$IFDEF CBUILDER}
function ActivatePrevInstance(const MainFormClass: ShortString;
const ATitle: string): Boolean;
{$ELSE}
function ActivatePrevInstance(const MainFormClass, ATitle: string): Boolean;
{$ENDIF CBUILDER}
var
PrevWnd, PopupWnd, ParentWnd: HWnd;
{$IFDEF WIN32}
IsDelphi: Longint;
{$ELSE}
S: array[0..255] of Char;
{$ENDIF}
begin
Result := False;
PrevWnd := FindPrevInstance(MainFormClass, ATitle);
if PrevWnd <> 0 then begin
ParentWnd := GetWindowParent(PrevWnd);
while (ParentWnd <> GetDesktopWindow) and (ParentWnd <> 0) do begin
PrevWnd := ParentWnd;
ParentWnd := GetWindowParent(PrevWnd);
end;
if WindowClassName(PrevWnd) = 'TApplication' then begin
{$IFDEF WIN32}
IsDelphi := 0;
EnumThreadWindows(GetWindowTask(PrevWnd), @WindowsEnum,
LPARAM(@IsDelphi));
if Boolean(IsDelphi) then Exit;
{$ELSE}
GetModuleFileName(GetWindowTask(PrevWnd), S, SizeOf(S) - 1);
if AnsiUpperCase(ExtractFileName(StrPas(S))) = 'DELPHI.EXE' then Exit;
{$ENDIF}
if IsIconic(PrevWnd) then begin { application is minimized }
SendMessage(PrevWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
Result := True;
Exit;
end
else ShowWinNoAnimate(PrevWnd, SW_SHOWNOACTIVATE);
end
else ActivateWindow(PrevWnd);
PopupWnd := GetLastActivePopup(PrevWnd);
if (PrevWnd <> PopupWnd) and IsWindowVisible(PopupWnd) and
IsWindowEnabled(PopupWnd) then
begin
{$IFDEF WIN32}
SetForegroundWindow(PopupWnd);
{$ELSE}
BringWindowToTop(PopupWnd);
{$ENDIF}
end
else ActivateWindow(PopupWnd);
Result := True;
end;
end;
{ Standard Windows MessageBox function }
function MsgBox(const Caption, Text: string; Flags: Integer): Integer;
begin
Result := Application.MessageBox(PChar(Text), PChar(Caption), Flags);
end;
function MsgDlg(const Msg: string; AType: TMsgDlgType; AButtons: TMsgDlgButtons; HelpCtx: Longint): Word;
begin
Result := MessageDlg(Msg, AType, AButtons, HelpCtx);
end;
{ Gradient fill procedure - displays a gradient beginning with a chosen }
{ color and ending with another chosen color. Based on TGradientFill }
{ component source code written by Curtis White, cwhite@teleport.com. }
procedure GradientFillRect(Canvas: TCanvas; ARect: TRect; StartColor,
EndColor: TColor; Direction: TFillDirection; Colors: Byte);
var
StartRGB: array[0..2] of Byte; { Start RGB values }
RGBDelta: array[0..2] of Integer; { Difference between start and end RGB values }
ColorBand: TRect; { Color band rectangular coordinates }
I, Delta: Integer;
Brush: HBrush;
begin
if IsRectEmpty(ARect) then Exit;
if Colors < 2 then begin
Brush := CreateSolidBrush(ColorToRGB(StartColor));
FillRect(Canvas.Handle, ARect, Brush);
DeleteObject(Brush);
Exit;
end;
StartColor := ColorToRGB(StartColor);
EndColor := ColorToRGB(EndColor);
case Direction of
fdTopToBottom, fdLeftToRight: begin
{ Set the Red, Green and Blue colors }
StartRGB[0] := GetRValue(StartColor);
StartRGB[1] := GetGValue(StartColor);
StartRGB[2] := GetBValue(StartColor);
{ Calculate the difference between begin and end RGB values }
RGBDelta[0] := GetRValue(EndColor) - StartRGB[0];
RGBDelta[1] := GetGValue(EndColor) - StartRGB[1];
RGBDelta[2] := GetBValue(EndColor) - StartRGB[2];
end;
fdBottomToTop, fdRightToLeft: begin
{ Set the Red, Green and Blue colors }
{ Reverse of TopToBottom and LeftToRight directions }
StartRGB[0] := GetRValue(EndColor);
StartRGB[1] := GetGValue(EndColor);
StartRGB[2] := GetBValue(EndColor);
{ Calculate the difference between begin and end RGB values }
{ Reverse of TopToBottom and LeftToRight directions }
RGBDelta[0] := GetRValue(StartColor) - StartRGB[0];
RGBDelta[1] := GetGValue(StartColor) - StartRGB[1];
RGBDelta[2] := GetBValue(StartColor) - StartRGB[2];
end;
end; {case}
{ Calculate the color band's coordinates }
ColorBand := ARect;
if Direction in [fdTopToBottom, fdBottomToTop] then begin
Colors := Max(2, Min(Colors, HeightOf(ARect)));
Delta := HeightOf(ARect) div Colors;
end
else begin
Colors := Max(2, Min(Colors, WidthOf(ARect)));
Delta := WidthOf(ARect) div Colors;
end;
with Canvas.Pen do begin { Set the pen style and mode }
Style := psSolid;
Mode := pmCopy;
end;
{ Perform the fill }
if Delta > 0 then begin
for I := 0 to Colors do begin
case Direction of
{ Calculate the color band's top and bottom coordinates }
fdTopToBottom, fdBottomToTop: begin
ColorBand.Top := ARect.Top + I * Delta;
ColorBand.Bottom := ColorBand.Top + Delta;
end;
{ Calculate the color band's left and right coordinates }
fdLeftToRight, fdRightToLeft: begin
ColorBand.Left := ARect.Left + I * Delta;
ColorBand.Right := ColorBand.Left + Delta;
end;
end; {case}
{ Calculate the color band's color }
Brush := CreateSolidBrush(RGB(
StartRGB[0] + MulDiv(I, RGBDelta[0], Colors - 1),
StartRGB[1] + MulDiv(I, RGBDelta[1], Colors - 1),
StartRGB[2] + MulDiv(I, RGBDelta[2], Colors - 1)));
FillRect(Canvas.Handle, ColorBand, Brush);
DeleteObject(Brush);
end;
end;
if Direction in [fdTopToBottom, fdBottomToTop] then
Delta := HeightOf(ARect) mod Colors
else Delta := WidthOf(ARect) mod Colors;
if Delta > 0 then begin
case Direction of
{ Calculate the color band's top and bottom coordinates }
fdTopToBottom, fdBottomToTop: begin
ColorBand.Top := ARect.Bottom - Delta;
ColorBand.Bottom := ColorBand.Top + Delta;
end;
{ Calculate the color band's left and right coordinates }
fdLeftToRight, fdRightToLeft: begin
ColorBand.Left := ARect.Right - Delta;
ColorBand.Right := ColorBand.Left + Delta;
end;
end; {case}
case Direction of
fdTopToBottom, fdLeftToRight:
Brush := CreateSolidBrush(EndColor);
else {fdBottomToTop, fdRightToLeft }
Brush := CreateSolidBrush(StartColor);
end;
FillRect(Canvas.Handle, ColorBand, Brush);
DeleteObject(Brush);
end;
end;
function MinimizeText(const Text: string; Canvas: TCanvas;
MaxWidth: Integer): string;
var
I: Integer;
begin
Result := Text;
I := 1;
while (I <= Length(Text)) and (Canvas.TextWidth(Result) > MaxWidth) do begin
Inc(I);
Result := Copy(Text, 1, Max(0, Length(Text) - I)) + '...';
end;
end;
function GetAveCharSize(Canvas: TCanvas): TPoint;
var
I: Integer;
Buffer: array[0..51] of Char;
begin
for I := 0 to 25 do Buffer[I] := Chr(I + Ord('A'));
for I := 0 to 25 do Buffer[I + 26] := Chr(I + Ord('a'));
GetTextExtentPoint(Canvas.Handle, Buffer, 52, TSize(Result));
Result.X := Result.X div 52;
end;
{ Memory routines }
function AllocMemo(Size: Longint): Pointer;
begin
if Size > 0 then
Result := GlobalAllocPtr(HeapAllocFlags or GMEM_ZEROINIT, Size)
else Result := nil;
end;
function ReallocMemo(fpBlock: Pointer; Size: Longint): Pointer;
begin
Result := GlobalReallocPtr(fpBlock, Size,
HeapAllocFlags or GMEM_ZEROINIT);
end;
procedure FreeMemo(var fpBlock: Pointer);
begin
if fpBlock <> nil then begin
GlobalFreePtr(fpBlock);
fpBlock := nil;
end;
end;
function GetMemoSize(fpBlock: Pointer): Longint;
var
hMem: THandle;
begin
Result := 0;
if fpBlock <> nil then begin
{$IFDEF WIN32}
hMem := GlobalHandle(fpBlock);
{$ELSE}
hMem := LoWord(GlobalHandle(SelectorOf(fpBlock)));
{$ENDIF}
if hMem <> 0 then Result := GlobalSize(hMem);
end;
end;
function CompareMem(fpBlock1, fpBlock2: Pointer; Size: Cardinal): Boolean; assembler;
asm
{$IFDEF WIN32}
PUSH ESI
PUSH EDI
MOV ESI,fpBlock1
MOV EDI,fpBlock2
MOV ECX,Size
MOV EDX,ECX
XOR EAX,EAX
AND EDX,3
SHR ECX,2
REPE CMPSD
JNE @@2
MOV ECX,EDX
REPE CMPSB
JNE @@2
@@1: INC EAX
@@2: POP EDI
POP ESI
{$ELSE}
PUSH DS
LDS SI,fpBlock1
LES DI,fpBlock2
MOV CX,Size
XOR AX,AX
CLD
REPE CMPSB
JNE @@1
INC AX
@@1: POP DS
{$ENDIF}
end;
{$IFNDEF RX_D5}
procedure FreeAndNil(var Obj);
var
P: TObject;
begin
P := TObject(Obj);
TObject(Obj) := nil;
P.Free;
end;
{$ENDIF}
{ Manipulate huge pointers routines by Ray Lischner, The Waite Group, Inc. }
{$IFDEF WIN32}
procedure HugeInc(var HugePtr: Pointer; Amount: Longint);
begin
HugePtr := PChar(HugePtr) + Amount;
end;
procedure HugeDec(var HugePtr: Pointer; Amount: Longint);
begin
HugePtr := PChar(HugePtr) - Amount;
end;
function HugeOffset(HugePtr: Pointer; Amount: Longint): Pointer;
begin
Result := PChar(HugePtr) + Amount;
end;
procedure HMemCpy(DstPtr, SrcPtr: Pointer; Amount: Longint);
begin
Move(SrcPtr^, DstPtr^, Amount);
end;
procedure HugeMove(Base: Pointer; Dst, Src, Size: Longint);
var
SrcPtr, DstPtr: PChar;
begin
SrcPtr := PChar(Base) + Src * SizeOf(Pointer);
DstPtr := PChar(Base) + Dst * SizeOf(Pointer);
Move(SrcPtr^, DstPtr^, Size * SizeOf(Pointer));
end;
{$ELSE}
procedure __AHSHIFT; far; external 'KERNEL' index 113;
{ Increment a huge pointer }
procedure HugeInc(var HugePtr: Pointer; Amount: Longint); assembler;
asm
MOV AX,Amount.Word[0]
MOV DX,Amount.Word[2]
LES BX,HugePtr
ADD AX,ES:[BX]
ADC DX,0
MOV CX,Offset __AHSHIFT
SHL DX,CL
ADD ES:[BX+2],DX
MOV ES:[BX],AX
end;
{ Decrement a huge pointer }
procedure HugeDec(var HugePtr: Pointer; Amount: Longint); assembler;
asm
LES BX,HugePtr
MOV AX,ES:[BX]
SUB AX,Amount.Word[0]
MOV DX,Amount.Word[2]
ADC DX,0
MOV CX,OFFSET __AHSHIFT
SHL DX,CL
SUB ES:[BX+2],DX
MOV ES:[BX],AX
end;
{ ADD an offset to a huge pointer and return the result }
function HugeOffset(HugePtr: Pointer; Amount: Longint): Pointer; assembler;
asm
MOV AX,Amount.Word[0]
MOV DX,Amount.Word[2]
ADD AX,HugePtr.Word[0]
ADC DX,0
MOV CX,OFFSET __AHSHIFT
SHL DX,CL
ADD DX,HugePtr.Word[2]
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -