📄 rxshell.pas
字号:
{*******************************************************}
{ }
{ Delphi VCL Extensions (RX) }
{ }
{ Copyright (c) 1995, 1996 AO ROSNO }
{ Copyright (c) 1997 Master-Bank }
{ }
{ Patched by Polaris Software }
{*******************************************************}
{.$DEFINE USE_TIMER}
{ - Use Windows timer instead thread to the animated TrayIcon }
unit RXShell;
{$I RX.INC}
{$P+,W-,R-}
interface
uses
Windows, Messages,
Classes, Graphics, SysUtils, Forms, Controls, Menus, ShellAPI,
{$IFDEF USE_TIMER} ExtCtrls, {$ENDIF} rxIcoList;
type
TMouseButtons = set of TMouseButton;
{ TRxTrayIcon }
TRxTrayIcon = class(TComponent)
private
FHandle: HWnd;
FActive: Boolean;
FAdded: Boolean;
FAnimated: Boolean;
FEnabled: Boolean;
FClicked: TMouseButtons;
FIconIndex: Integer;
FInterval: Word;
FIconData: TNotifyIconData;
FIcon: TIcon;
FIconList: TIconList;
{$IFDEF USE_TIMER}
FTimer: TTimer;
{$ELSE}
FTimer: TThread;
{$ENDIF}
FHint: string;
FShowDesign: Boolean;
FPopupMenu: TPopupMenu;
FOnClick: TMouseEvent;
FOnDblClick: TNotifyEvent;
FOnMouseMove: TMouseMoveEvent;
FOnMouseDown: TMouseEvent;
FOnMouseUp: TMouseEvent;
procedure ChangeIcon;
{$IFDEF USE_TIMER}
procedure Timer(Sender: TObject);
{$ELSE}
procedure Timer;
{$ENDIF}
procedure SendCancelMode;
function CheckMenuPopup(X, Y: Integer): Boolean;
function CheckDefaultMenuItem: Boolean;
procedure SetHint(const Value: string);
procedure SetIcon(Value: TIcon);
procedure SetIconList(Value: TIconList);
procedure SetPopupMenu(Value: TPopupMenu);
procedure Activate;
procedure Deactivate;
procedure SetActive(Value: Boolean);
function GetAnimated: Boolean;
procedure SetAnimated(Value: Boolean);
procedure SetShowDesign(Value: Boolean);
procedure SetInterval(Value: Word);
procedure IconChanged(Sender: TObject);
procedure WndProc(var Message: TMessage);
function GetActiveIcon: TIcon;
protected
procedure DblClick; dynamic;
procedure DoClick(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); dynamic;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); dynamic;
procedure MouseMove(Shift: TShiftState; X, Y: Integer); dynamic;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); dynamic;
procedure Loaded; override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure UpdateNotifyData; virtual;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Hide;
procedure Show;
property Handle: HWnd read FHandle;
published
property Active: Boolean read FActive write SetActive default True;
property Enabled: Boolean read FEnabled write FEnabled default True;
property Hint: string read FHint write SetHint;
property Icon: TIcon read FIcon write SetIcon;
property Icons: TIconList read FIconList write SetIconList;
{ Ensure Icons is declared before Animated }
property Animated: Boolean read GetAnimated write SetAnimated default False;
property Interval: Word read FInterval write SetInterval default 150;
property PopupMenu: TPopupMenu read FPopupMenu write SetPopupMenu;
property ShowDesign: Boolean read FShowDesign write SetShowDesign stored False;
property OnClick: TMouseEvent read FOnClick write FOnClick;
property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;
property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove;
property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;
property OnMouseUp: TMouseEvent read FOnMouseUp write FOnMouseUp;
end;
function IconExtract(const FileName: string; Id: Integer): TIcon;
procedure WinAbout(const AppName, Stuff: string);
type
TExecState = (esNormal, esMinimized, esMaximized, esHidden);
function FileExecute(const FileName, Params, StartDir: string;
InitialState: TExecState): THandle;
function FileExecuteWait(const FileName, Params, StartDir: string;
InitialState: TExecState): Integer;
implementation
uses
RxConst, RxCConst, rxVCLUtils, rxMaxMin;
procedure WinAbout(const AppName, Stuff: string);
var
Wnd: HWnd;
Icon: HIcon;
begin
if Application.MainForm <> nil then Wnd := Application.MainForm.Handle
else Wnd := 0;
Icon := Application.Icon.Handle;
if Icon = 0 then Icon := LoadIcon(0, IDI_APPLICATION);
ShellAbout(Wnd, PChar(AppName), PChar(Stuff), Icon);
end;
function IconExtract(const FileName: string; Id: Integer): TIcon;
var
S: array[0..255] of char;
IconHandle: HIcon;
Index: Word;
begin
Result := TIcon.Create;
try
StrPLCopy(S, FileName, SizeOf(S) - 1);
IconHandle := ExtractIcon(hInstance, S, Id);
if IconHandle < 2 then begin
Index := Id;
IconHandle := ExtractAssociatedIcon(hInstance, S, Index);
end;
if IconHandle < 2 then begin
if IconHandle = 1 then
raise EResNotFound.Create(LoadStr(SFileNotExec))
else begin
Result.Free;
Result := nil;
end;
end else Result.Handle := IconHandle;
except
Result.Free;
raise;
end;
end;
const
ShowCommands: array[TExecState] of Integer =
(SW_SHOWNORMAL, SW_MINIMIZE, SW_SHOWMAXIMIZED, SW_HIDE);
function FileExecute(const FileName, Params, StartDir: string;
InitialState: TExecState): THandle;
begin
Result := ShellExecute(Application.Handle, nil, PChar(FileName),
PChar(Params), PChar(StartDir), ShowCommands[InitialState]);
end;
function FileExecuteWait(const FileName, Params, StartDir: string;
InitialState: TExecState): Integer;
var
Info: TShellExecuteInfo;
ExitCode: DWORD;
begin
FillChar(Info, SizeOf(Info), 0);
Info.cbSize := SizeOf(TShellExecuteInfo);
with Info do begin
fMask := SEE_MASK_NOCLOSEPROCESS;
Wnd := Application.Handle;
lpFile := PChar(FileName);
lpParameters := PChar(Params);
lpDirectory := PChar(StartDir);
nShow := ShowCommands[InitialState];
end;
if ShellExecuteEx(@Info) then begin
repeat
Application.ProcessMessages;
GetExitCodeProcess(Info.hProcess, ExitCode);
until (ExitCode <> STILL_ACTIVE) or Application.Terminated;
Result := ExitCode;
end
else Result := -1;
end;
{$IFNDEF USE_TIMER}
{ TTimerThread }
type
TTimerThread = class(TThread)
private
FOwnerTray: TRxTrayIcon;
protected
procedure Execute; override;
public
constructor Create(TrayIcon: TRxTrayIcon; CreateSuspended: Boolean);
end;
constructor TTimerThread.Create(TrayIcon: TRxTrayIcon; CreateSuspended: Boolean);
begin
FOwnerTray := TrayIcon;
inherited Create(CreateSuspended);
FreeOnTerminate := True;
end;
procedure TTimerThread.Execute;
function ThreadClosed: Boolean;
begin
Result := Terminated or Application.Terminated or (FOwnerTray = nil);
end;
begin
while not Terminated do begin
if not ThreadClosed then
if SleepEx(FOwnerTray.FInterval, False) = 0 then begin
if not ThreadClosed and FOwnerTray.Animated then
FOwnerTray.Timer;
end;
end;
end;
{$ENDIF USE_TIMER}
{ TRxTrayIcon }
constructor TRxTrayIcon.Create(AOwner: Tcomponent);
begin
inherited Create(AOwner);
FHandle := {$IFDEF RX_D6}Classes.{$ENDIF}AllocateHWnd(WndProc); // Polaris
FIcon := TIcon.Create;
FIcon.OnChange := IconChanged;
FIconList := TIconList.Create;
FIconList.OnChange := IconChanged;
FIconIndex := -1;
FEnabled := True;
FInterval := 150;
FActive := True;
end;
destructor TRxTrayIcon.Destroy;
begin
Destroying;
FEnabled := False;
FIconList.OnChange := nil;
FIcon.OnChange := nil;
SetAnimated(False);
Deactivate;
{$IFDEF RX_D6}Classes.{$ENDIF}DeallocateHWnd(FHandle); // Polaris
FIcon.Free;
FIcon := nil;
FIconList.Free;
FIconList := nil;
inherited Destroy;
end;
procedure TRxTrayIcon.Loaded;
begin
inherited Loaded;
if FActive and not (csDesigning in ComponentState) then Activate;
end;
procedure TRxTrayIcon.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (AComponent = PopupMenu) and (Operation = opRemove) then
PopupMenu := nil;
end;
procedure TRxTrayIcon.SetPopupMenu(Value: TPopupMenu);
begin
FPopupMenu := Value;
if Value <> nil then Value.FreeNotification(Self);
end;
procedure TRxTrayIcon.SendCancelMode;
var
F: TForm;
begin
if not (csDestroying in ComponentState) then begin
F := Screen.ActiveForm;
if F = nil then F := Application.MainForm;
if F <> nil then F.SendCancelMode(nil);
end;
end;
function TRxTrayIcon.CheckMenuPopup(X, Y: Integer): Boolean;
begin
Result := False;
if not (csDesigning in ComponentState) and Active and
(PopupMenu <> nil) and PopupMenu.AutoPopup then
begin
PopupMenu.PopupComponent := Self;
SendCancelMode;
SwitchToWindow(FHandle, False);
Application.ProcessMessages;
try
PopupMenu.Popup(X, Y);
finally
SwitchToWindow(FHandle, False);
end;
Result := True;
end;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -