⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trayicon.pas

📁 以多个信息系统为例
💻 PAS
字号:
unit TrayIcon;interfaceuses  Windows, Messages, SysUtils, Classes, Graphics,   Controls, Forms, Dialogs, ShellAPI, Menus, StdCtrls, ExtCtrls;type  ENotifyIconError = class(Exception);  TTrayNotifyIcon = class(TComponent)  private    FDefaultIcon: THandle;    FIcon: TIcon;    FHideTask: Boolean;    FHint: string;    FIconVisible: Boolean;    FPopupMenu: TPopupMenu;    FOnClick: TNotifyEvent;    FOnDblClick: TNotifyEvent;    FNoShowClick: Boolean;    FTimer: TTimer;    Tnd: TNotifyIconData;    procedure SetIcon(Value: TIcon);    procedure SetHideTask(Value: Boolean);    procedure SetHint(Value: string);    procedure SetIconVisible(Value: Boolean);    procedure SetPopupMenu(Value: TPopupMenu);    procedure SendTrayMessage(Msg: DWORD; Flags: UINT);    function ActiveIconHandle: THandle;    procedure OnButtonTimer(Sender: TObject);  protected    procedure Loaded; override;    procedure LoadDefaultIcon; virtual;    procedure Notification(AComponent: TComponent;      Operation: TOperation); override;  public    constructor Create(AOwner: TComponent); override;    destructor Destroy; override;  published    property Icon: TIcon read FIcon write SetIcon;    property HideTask: Boolean read FHideTask write SetHideTask default False;    property Hint: String read FHint write SetHint;    property IconVisible: Boolean read FIconVisible write SetIconVisible default False;    property PopupMenu: TPopupMenu read FPopupMenu write SetPopupMenu;    property OnClick: TNotifyEvent read FOnClick write FOnClick;    property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;  end;procedure Register;implementation{ TIconManager }{ 创建一个隐藏的窗口用于处理事务 }type  TIconManager = class  private    FHWindow: HWnd;    procedure TrayWndProc(var Message: TMessage);  public    constructor Create;    destructor Destroy; override;    property HWindow: HWnd read FHWindow write FHWindow;  end;var  IconMgr: TIconManager;  DDGM_TRAYICON: Cardinal;constructor TIconManager.Create;begin  FHWindow := AllocateHWnd(TrayWndProc);end;destructor TIconManager.Destroy;begin  if FHWindow <> 0 then DeallocateHWnd(FHWindow);  inherited Destroy;end;procedure TIconManager.TrayWndProc(var Message: TMessage);{ 此进程用于处理所有托盘图表返回的消息 }var  Pt: TPoint;  TheIcon: TTrayNotifyIcon;begin  with Message do  begin    { 如果是托盘图表返回的消息 }    if (Msg = DDGM_TRAYICON) then    begin      TheIcon := TTrayNotifyIcon(WParam);      case lParam of        { enable timer on first mouse down. }        { OnClick will be fired by OnTimer method, provided }        { double click has not occurred. }        WM_LBUTTONDOWN: TheIcon.FTimer.Enabled := True;        { Set no click flag on double click.  This will supress }        { the single click. }        WM_LBUTTONDBLCLK:          begin            TheIcon.FNoShowClick := True;            if Assigned(TheIcon.FOnDblClick) then TheIcon.FOnDblClick(Self);          end;        WM_RBUTTONDOWN:          begin            if Assigned(TheIcon.FPopupMenu) then            begin              { Call to SetForegroundWindow is required by API }              SetForegroundWindow(IconMgr.HWindow);              { Popup local menu at the cursor position. }              GetCursorPos(Pt);              TheIcon.FPopupMenu.Popup(Pt.X, Pt.Y);              { Message post required by API to force task switch }              PostMessage(IconMgr.HWindow, WM_USER, 0, 0);            end;          end;      end;    end    else      { If it isn't a tray callback message, then call DefWindowProc }      Result := DefWindowProc(FHWindow, Msg, wParam, lParam);  end;end;{ TTrayNotifyIcon }constructor TTrayNotifyIcon.Create(AOwner: TComponent);begin  inherited Create(AOwner);  FIcon := TIcon.Create;  FTimer := TTimer.Create(Self);  with FTimer do  begin    Enabled := False;    Interval := GetDoubleClickTime;    OnTimer := OnButtonTimer;  end;  { Keep default windows icon handy... }  LoadDefaultIcon;end;destructor TTrayNotifyIcon.Destroy;begin  if FIconVisible then SetIconVisible(False);    // destroy icon  FIcon.Free;                                    // free stuff  FTimer.Free;  inherited Destroy;end;function TTrayNotifyIcon.ActiveIconHandle: THandle;{ Returns handle of active icon }begin  { If no icon is loaded, then return default icon }  if (FIcon.Handle <> 0) then    Result := FIcon.Handle  else    Result := FDefaultIcon;end;procedure TTrayNotifyIcon.LoadDefaultIcon;{ Loads default window icon to keep it handy. }{ This will allow the component to use the windows logo }{ icon as the default when no icon is selected in the }{ Icon property. }begin  FDefaultIcon := LoadIcon(0, IDI_WINLOGO);end;procedure TTrayNotifyIcon.Loaded;{ Called after component is loaded from stream }begin  inherited Loaded;  { if icon is supposed to be visible, create it. }  if FIconVisible then    SendTrayMessage(NIM_ADD, NIF_MESSAGE or NIF_ICON or NIF_TIP);end;procedure TTrayNotifyIcon.Notification(AComponent: TComponent;  Operation: TOperation);begin  inherited Notification(AComponent, Operation);  if (Operation = opRemove) and (AComponent = PopupMenu) then    PopupMenu := nil;end;procedure TTrayNotifyIcon.OnButtonTimer(Sender: TObject);{ Timer used to keep track of time between two clicks of a }{ double click. This delays the first click long enough to }{ ensure that a double click hasn't occurred.  The whole   }{ point of these gymnastics is to allow the component to   }{ receive OnClicks and OnDblClicks independently. }begin  { Disable timer because we only want it to fire once. }  FTimer.Enabled := False;  { if double click has not occurred, then fire single click. }  if (not FNoShowClick) and Assigned(FOnClick) then    FOnClick(Self);  FNoShowClick := False;   // reset flagend;procedure TTrayNotifyIcon.SendTrayMessage(Msg: DWORD; Flags: UINT);{ This method wraps up the call to the API's Shell_NotifyIcon }begin  { Fill up record with appropriate values }  with Tnd do  begin    cbSize := SizeOf(Tnd);    StrPLCopy(szTip, PChar(FHint), SizeOf(szTip));    uFlags := Flags;    uID := UINT(Self);    Wnd := IconMgr.HWindow;    uCallbackMessage := DDGM_TRAYICON;    hIcon  := ActiveIconHandle;  end;  Shell_NotifyIcon(Msg, @Tnd);end;procedure TTrayNotifyIcon.SetHideTask(Value: Boolean);{ 修改是否在任务栏显示属性 }const  { 设置标志,用于确定任务栏显示状态 }  ShowArray: array[Boolean] of integer = (sw_ShowNormal, sw_Hide);begin  if FHideTask <> Value then  begin    FHideTask := Value;    { 在设计期不做任何修改 }    if not (csDesigning in ComponentState) then      ShowWindow(Application.Handle, ShowArray[FHideTask]);  end;end;procedure TTrayNotifyIcon.SetHint(Value: string);{ 设置Hint属性 }begin  if FHint <> Value then  begin    FHint := Value;    if FIconVisible then      {修改图标的提示信息}      SendTrayMessage(NIM_MODIFY, NIF_TIP);  end;end;procedure TTrayNotifyIcon.SetIcon(Value: TIcon);{ Write method for Icon property. }begin  FIcon.Assign(Value);  // set new icon  { Change icon on notification tray }  if FIconVisible then SendTrayMessage(NIM_MODIFY, NIF_ICON);end;procedure TTrayNotifyIcon.SetIconVisible(Value: Boolean);{ 修改是否在任务栏显示属性 }const  { Flags to add or delete a tray notification icon }  MsgArray: array[Boolean] of DWORD = (NIM_DELETE, NIM_ADD);begin  if FIconVisible <> Value then  begin    FIconVisible := Value;    { Set icon as appropriate }    SendTrayMessage(MsgArray[Value], NIF_MESSAGE or NIF_ICON or NIF_TIP);  end;end;procedure TTrayNotifyIcon.SetPopupMenu(Value: TPopupMenu);{ Write method for PopupMenu property }begin  FPopupMenu := Value;  if Value <> nil then Value.FreeNotification(Self);end;procedure Register;begin  RegisterComponents('CYL', [TTrayNotifyIcon]);end;const  { String to identify registered window message }  TrayMsgStr = 'DDG.TrayNotifyIconMsg';initialization  { Get a unique windows message ID for tray callback }  DDGM_TRAYICON := RegisterWindowMessage(TrayMsgStr);  IconMgr := TIconManager.Create;finalization  IconMgr.Free;end. 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -