高手请进:如何将系统托盘上的某个图标删除?(100分)

F

feng_me

Unregistered / Unconfirmed
GUEST, unregistred user!
看了以往的帖子,发现需要得到TNotifyIconData中的handle和uID属性。<br>不知有没有高手能够解决?<br>谢谢
 
给你一个控件:<br>{<br>This is a component for placing icons in the notification area<br>of the Windows taskbar (aka. the traybar).<br><br>The component is freeware. Feel free to use and improve it.<br>I would be pleased to hear what you think.<br><br>Troels Jakobsen - tjak@get2net.dk<br>}<br>unit CoolTrayIcon;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,<br>&nbsp; Menus, ShellApi, extctrls;<br><br>const<br>&nbsp; { User-defined message sent from the icon. Some low user-defined<br>&nbsp; &nbsp; messages are used by Windows itself! (WM_USER+1 = DM_SETDEFID). }<br>&nbsp; WM_TRAYNOTIFY = WM_USER + 1024;<br>&nbsp; IconID = 1;<br><br>type<br>&nbsp; TCycleEvent = procedure(Sender: TObject; Current: Integer) of object;<br><br>&nbsp; TCoolTrayIcon = class(TComponent)<br>&nbsp; private<br>&nbsp; &nbsp; FEnabled: Boolean;<br>&nbsp; &nbsp; FIcon: TIcon;<br>&nbsp; &nbsp; FIconVisible: Boolean;<br>&nbsp; &nbsp; FHint: String;<br>&nbsp; &nbsp; FShowHint: Boolean;<br>&nbsp; &nbsp; FPopupMenu: TPopupMenu;<br>&nbsp; &nbsp; FLeftPopup: Boolean;<br>&nbsp; &nbsp; FOnClick,<br>&nbsp; &nbsp; FOnDblClick: TNotifyEvent;<br>&nbsp; &nbsp; FOnCycle: TCycleEvent;<br>&nbsp; &nbsp; FOnMouseDown,<br>&nbsp; &nbsp; FOnMouseUp: TMouseEvent;<br>&nbsp; &nbsp; FOnMouseMove: TMouseMoveEvent;<br>&nbsp; &nbsp; FStartMinimized: Boolean;<br>&nbsp; &nbsp; FMinimizeToTray: Boolean;<br>&nbsp; &nbsp; FClicked: Boolean;<br>&nbsp; &nbsp; CycleTimer: TTimer; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // For icon cycling<br>&nbsp; &nbsp; FDesignPreview: Boolean;<br>&nbsp; &nbsp; SettingPreview: Boolean;<br>&nbsp; &nbsp; FIconList: TImageList;<br>&nbsp; &nbsp; FCycleIcons: Boolean;<br>&nbsp; &nbsp; FCycleInterval: Cardinal;<br>&nbsp; &nbsp; IconIndex: Integer; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Current index in imagelist<br>&nbsp; &nbsp; OldAppProc, NewAppProc: Pointer; &nbsp; // Procedure variables<br>&nbsp; &nbsp; procedure SetCycleIcons(Value: Boolean);<br>&nbsp; &nbsp; procedure SetDesignPreview(Value: Boolean);<br>&nbsp; &nbsp; procedure SetCycleInterval(Value: Cardinal);<br>&nbsp; &nbsp; procedure TimerCycle(Sender: TObject);<br>&nbsp; &nbsp; procedure HandleIconMessage(var Msg: TMessage);<br>&nbsp; &nbsp; function InitIcon: Boolean;<br>&nbsp; &nbsp; procedure SetIcon(Value: TIcon);<br>&nbsp; &nbsp; procedure SetIconVisible(Value: Boolean);<br>&nbsp; &nbsp; procedure SetHint(Value: String);<br>&nbsp; &nbsp; procedure SetShowHint(Value: Boolean);<br>&nbsp; &nbsp; procedure PopupAtCursor;<br>&nbsp; &nbsp; procedure HookApp;<br>&nbsp; &nbsp; procedure UnhookApp;<br>&nbsp; &nbsp; procedure HookAppProc(var Message: TMessage);<br>&nbsp; protected<br>&nbsp; &nbsp; IconData: TNotifyIconData; &nbsp; &nbsp;// Data of the tray icon wnd.<br>&nbsp; &nbsp; procedure Loaded; override;<br>&nbsp; &nbsp; function ShowIcon: Boolean; virtual;<br>&nbsp; &nbsp; function HideIcon: Boolean; virtual;<br>&nbsp; &nbsp; function ModifyIcon: Boolean; virtual;<br>&nbsp; &nbsp; procedure Click; dynamic;<br>&nbsp; &nbsp; procedure DblClick; dynamic;<br>&nbsp; &nbsp; procedure CycleIcon; dynamic;<br>&nbsp; &nbsp; procedure MouseDown(Button: TMouseButton; Shift: TShiftState;<br>&nbsp; &nbsp; &nbsp; X, Y: Integer); dynamic;<br>&nbsp; &nbsp; procedure MouseUp(Button: TMouseButton; Shift: TShiftState;<br>&nbsp; &nbsp; &nbsp; X, Y: Integer); dynamic;<br>&nbsp; &nbsp; procedure MouseMove(Shift: TShiftState; X, Y: Integer); dynamic;<br>&nbsp; &nbsp; procedure DoMinimizeToTray; dynamic;<br>&nbsp; &nbsp; procedure Notification(AComponent: TComponent; Operation: TOperation);<br>&nbsp; &nbsp; &nbsp; override;<br>&nbsp; public<br>{$IFDEF DFS_CPPB_3_UP}<br>&nbsp; &nbsp; property Handle: HWND read IconData.hwnd;<br>{$ELSE}<br>&nbsp; &nbsp; property Handle: HWND read IconData.wnd;<br>{$ENDIF}<br>&nbsp; &nbsp; constructor Create(AOwner: TComponent); override;<br>&nbsp; &nbsp; destructor Destroy; override;<br>&nbsp; &nbsp; procedure ShowMainForm;<br>&nbsp; &nbsp; procedure HideMainForm;<br>&nbsp; &nbsp; procedure Refresh;<br>&nbsp; published<br>&nbsp; &nbsp; // Properties:<br>&nbsp; &nbsp; property DesignPreview: Boolean read FDesignPreview<br>&nbsp; &nbsp; &nbsp; write SetDesignPreview default False;<br>&nbsp; &nbsp; property IconList: TImageList read FIconList write FIconList;<br>&nbsp; &nbsp; property CycleIcons: Boolean read FCycleIcons write SetCycleIcons<br>&nbsp; &nbsp; &nbsp; default False;<br>&nbsp; &nbsp; property CycleInterval: Cardinal read FCycleInterval<br>&nbsp; &nbsp; &nbsp; write SetCycleInterval;<br>&nbsp; &nbsp; property Enabled: Boolean read FEnabled write FEnabled default True;<br>&nbsp; &nbsp; property Hint: String read FHint write SetHint;<br>&nbsp; &nbsp; property ShowHint: Boolean read FShowHint write SetShowHint;<br>&nbsp; &nbsp; property Icon: TIcon read FIcon write SetIcon stored True;<br>&nbsp; &nbsp; property IconVisible: Boolean read FIconVisible write SetIconVisible<br>&nbsp; &nbsp; &nbsp; default True;<br>&nbsp; &nbsp; property PopupMenu: TPopupMenu read FPopupMenu write FPopupMenu;<br>&nbsp; &nbsp; property LeftPopup: Boolean read FLeftPopup write FLeftPopup<br>&nbsp; &nbsp; &nbsp; default False;<br>&nbsp; &nbsp; property StartMinimized: Boolean read FStartMinimized write FStartMinimized<br>&nbsp; &nbsp; &nbsp; default False; &nbsp; &nbsp; &nbsp; &nbsp; // Main form minimized on appl. start-up?<br>&nbsp; &nbsp; property MinimizeToTray: Boolean read FMinimizeToTray write FMinimizeToTray<br>&nbsp; &nbsp; &nbsp; default False; &nbsp; &nbsp; &nbsp; &nbsp; // Minimize main form to tray when minimizing?<br>&nbsp; &nbsp; // Events:<br>&nbsp; &nbsp; property OnClick: TNotifyEvent read FOnClick write FOnClick;<br>&nbsp; &nbsp; property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;<br>&nbsp; &nbsp; property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;<br>&nbsp; &nbsp; property OnMouseUp: TMouseEvent read FOnMouseUp write FOnMouseUp;<br>&nbsp; &nbsp; property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove;<br>&nbsp; &nbsp; property OnCycle: TCycleEvent read FOnCycle write FOnCycle;<br>&nbsp; end;<br><br>procedure Register;<br><br>implementation<br><br>{--------------------- TCoolTrayIcon ----------------------}<br><br>constructor TCoolTrayIcon.Create(AOwner: TComponent);<br>begin<br>&nbsp; inherited Create(AOwner);<br>&nbsp; FIconVisible := True; &nbsp; &nbsp; &nbsp;// Visible by default<br>&nbsp; FEnabled := True; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Enabled by default<br>&nbsp; SettingPreview := False;<br><br>&nbsp; FIcon := TIcon.Create;<br>&nbsp; IconData.cbSize := SizeOf(TNotifyIconData);<br>&nbsp; // IconData.wnd points to procedure to receive callback messages from the icon<br>&nbsp; IconData.wnd := AllocateHWnd(HandleIconMessage);<br>&nbsp; // Add an id for the tray icon<br>&nbsp; IconData.uId := IconID;<br>&nbsp; // We want icon, message handling, and tooltips<br>&nbsp; IconData.uFlags := NIF_ICON + NIF_MESSAGE + NIF_TIP;<br>&nbsp; // Message to send to IconData.wnd when mouse event occurs<br>&nbsp; IconData.uCallbackMessage := WM_TRAYNOTIFY;<br><br>&nbsp; CycleTimer := TTimer.Create(Self);<br>&nbsp; CycleTimer.Enabled := False;<br>&nbsp; CycleTimer.Interval := FCycleInterval;<br>&nbsp; CycleTimer.OnTimer := TimerCycle;<br><br>&nbsp; // Hook into the app.'s message handling<br>&nbsp; if not (csDesigning in ComponentState) then<br>&nbsp; &nbsp; HookApp;<br>end;<br><br><br>destructor TCoolTrayIcon.Destroy;<br>begin<br>&nbsp; SetIconVisible(False); &nbsp; &nbsp; // Remove the icon from the tray<br>&nbsp; FIcon.Free; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Free the icon<br>&nbsp; DeallocateHWnd(IconData.Wnd); &nbsp; // Free the tray window<br>&nbsp; CycleTimer.Free;<br>&nbsp; // It is important to unhook any hooked processes<br>&nbsp; if not (csDesigning in ComponentState) then<br>&nbsp; &nbsp; UnhookApp;<br>&nbsp; inherited Destroy;<br>end;<br><br><br>procedure TCoolTrayIcon.Loaded;<br>{ This method is called when all properties of the component have been<br>&nbsp; initialized. The method SetIconVisible must be called here, after the<br>&nbsp; tray icon (FIcon) has loaded itself. Otherwise, the tray icon will<br>&nbsp; be blank (no icon image). }<br>begin<br>&nbsp; inherited Loaded; &nbsp; &nbsp; // Always call inherited Loaded first<br>&nbsp; if (FStartMinimized) and not (csDesigning in ComponentState) then<br>&nbsp; begin<br>&nbsp; &nbsp; Application.ShowMainForm := False;<br>&nbsp; &nbsp; ShowWindow(Application.Handle, SW_HIDE);<br>&nbsp; end;<br>&nbsp; ModifyIcon;<br>&nbsp; SetIconVisible(FIconVisible);<br>end;<br><br><br>procedure TCoolTrayIcon.Notification(AComponent: TComponent;<br>&nbsp; Operation: TOperation);<br>begin<br>&nbsp; inherited Notification(AComponent, Operation);<br>&nbsp; { Check if either the imagelist or the popup menu<br>&nbsp; &nbsp; is about to be deleted }<br>&nbsp; if (AComponent = IconList) and (Operation = opRemove) then<br>&nbsp; &nbsp; IconList := nil;<br>&nbsp; if (AComponent = PopupMenu) and (Operation = opRemove) then<br>&nbsp; &nbsp; PopupMenu := nil;<br>end;<br><br><br>{ For MinimizeToTray to work, we need to know when the form is minimized<br>&nbsp; (happens when either the application or the main form minimizes).<br>&nbsp; The straight-forward way is to make TCoolTrayIcon trap the<br>&nbsp; Application.OnMinimize event. However, if you also make use of this<br>&nbsp; event in the application, the OnMinimize code used by TCoolTrayIcon<br>&nbsp; is discarded.<br>&nbsp; The alternative is to hook into the app.'s message handling (via<br>&nbsp; HookApp). You can then catch any message that goes through the app.<br>&nbsp; and still use the OnMinimize event. }<br><br>procedure TCoolTrayIcon.HookApp;<br>begin<br>&nbsp; // Hook the application<br>&nbsp; OldAppProc := Pointer(GetWindowLong(Application.Handle, GWL_WNDPROC));<br>&nbsp; NewAppProc := MakeObjectInstance(HookAppProc);<br>&nbsp; SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(NewAppProc));<br>end;<br><br><br>procedure TCoolTrayIcon.UnhookApp;<br>begin<br>&nbsp; if Assigned(OldAppProc) then<br>&nbsp; &nbsp; SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(OldAppProc));<br>&nbsp; if Assigned(NewAppProc) then<br>&nbsp; &nbsp; FreeObjectInstance(NewAppProc);<br>&nbsp; NewAppProc := nil;<br>&nbsp; OldAppProc := nil;<br>end;<br><br><br>{ All app. messages pass through HookAppProc. You can override the<br>&nbsp; messages by not passing them along to Windows (via CallWindowProc). }<br><br>procedure TCoolTrayIcon.HookAppProc(var Message: TMessage);<br>begin<br>&nbsp; with Message do<br>&nbsp; begin<br>&nbsp; &nbsp; case Msg of<br>&nbsp; &nbsp; &nbsp; WM_SIZE:<br>&nbsp; &nbsp; &nbsp; &nbsp; if wParam = SIZE_MINIMIZED then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if FMinimizeToTray then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DoMinimizeToTray;<br>{ It is tempting to insert a minimize event here, but it would behave<br>&nbsp; exactly like Application.OnMinimize, so I see no need for it. }<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; Result := CallWindowProc(OldAppProc, Application.Handle, Msg, wParam, lParam);<br>&nbsp; end;<br>end;<br><br><br>{ You can hook into the main form (or any other window) just as easily<br>&nbsp; as hooking into the app., allowing you to handle any message that<br>&nbsp; window processes. Uncomment the procedures HookParent and UnhookParent<br>&nbsp; below if you want to hook the main form. Remember to unhook when the<br>&nbsp; app. terminates, or Bad Things may happen. }<br>{<br>procedure TCoolTrayIcon.HookParent;<br>begin<br>&nbsp; if Assigned(Owner as TWinControl) then<br>&nbsp; begin<br>&nbsp; &nbsp; // Hook the parent window<br>&nbsp; &nbsp; OldWndProc := Pointer(GetWindowLong((Owner as TWinControl).Handle, GWL_WNDPROC));<br>&nbsp; &nbsp; NewWndProc := MakeObjectInstance(HookWndProc);<br>&nbsp; &nbsp; SetWindowLong((Owner as TWinControl).Handle, GWL_WNDPROC, LongInt(NewWndProc));<br>&nbsp; end;<br>end;<br><br><br>procedure TCoolTrayIcon.UnhookParent;<br>begin<br>&nbsp; if ((Owner as TWinControl) &lt;&gt; nil) and Assigned(OldWndProc) then<br>&nbsp; &nbsp; SetWindowLong((Owner as TWinControl).Handle, GWL_WNDPROC, LongInt(OldWndProc));<br>&nbsp; if Assigned(NewWndProc) then<br>&nbsp; &nbsp; FreeObjectInstance(NewWndProc);<br>&nbsp; NewWndProc := nil;<br>&nbsp; OldWndProc := nil;<br>end;<br>}<br><br><br>{ HandleIconMessage handles messages that go to the shell notification<br>&nbsp; window (tray icon) itself. Most messages are passed through WM_TRAYNOTIFY.<br>&nbsp; Use lParam to get the actual message, eg. WM_MOUSEMOVE.<br>&nbsp; Sends the usual Delphi events for the mouse messages. Also interpolates<br>&nbsp; the OnClick event when the user clicks the left button, and makes the<br>&nbsp; menu (if any) popup on left and right mouse down events. }<br><br>procedure TCoolTrayIcon.HandleIconMessage(var Msg: TMessage);<br><br>&nbsp; function ShiftState: TShiftState;<br>&nbsp; // Return the state of the shift, ctrl, and alt keys<br>&nbsp; begin<br>&nbsp; &nbsp; Result := [];<br>&nbsp; &nbsp; if GetKeyState(VK_SHIFT) &lt; 0 then<br>&nbsp; &nbsp; &nbsp; Include(Result, ssShift);<br>&nbsp; &nbsp; if GetKeyState(VK_CONTROL) &lt; 0 then<br>&nbsp; &nbsp; &nbsp; Include(Result, ssCtrl);<br>&nbsp; &nbsp; if GetKeyState(VK_MENU) &lt; 0 then<br>&nbsp; &nbsp; &nbsp; Include(Result, ssAlt);<br>&nbsp; end;<br><br>var<br>&nbsp; Pt: TPoint;<br>&nbsp; Shift: TShiftState;<br>&nbsp; I: Integer;<br>&nbsp; M: TMenuItem;<br>begin<br>&nbsp; if Msg.Msg = WM_TRAYNOTIFY then<br>&nbsp; // Take action if a message from the icon comes through<br>&nbsp; begin<br>&nbsp; &nbsp; case Msg.lParam of<br><br>&nbsp; &nbsp; WM_MOUSEMOVE:<br>&nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Shift := ShiftState;<br>&nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(Pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; MouseMove(Shift, Pt.X, Pt.Y);<br>&nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; WM_LBUTTONDOWN:<br>&nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Shift := ShiftState + [ssLeft];<br>&nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(Pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; MouseDown(mbLeft, Shift, Pt.X, Pt.Y);<br>&nbsp; &nbsp; &nbsp; &nbsp; FClicked := True;<br>&nbsp; &nbsp; &nbsp; &nbsp; if FLeftPopup then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PopupAtCursor;<br>&nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; WM_RBUTTONDOWN:<br>&nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Shift := ShiftState + [ssRight];<br>&nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(Pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; MouseDown(mbRight, Shift, Pt.X, Pt.Y);<br>&nbsp; &nbsp; &nbsp; &nbsp; PopupAtCursor;<br>&nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; WM_MBUTTONDOWN:<br>&nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Shift := ShiftState + [ssMiddle];<br>&nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(Pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; MouseDown(mbMiddle, Shift, Pt.X, Pt.Y);<br>&nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; WM_LBUTTONUP:<br>&nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Shift := ShiftState + [ssLeft];<br>&nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(Pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; if FClicked then &nbsp; &nbsp; // Then WM_LBUTTONDOWN was called before<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FClicked := False;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Click;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; MouseUp(mbLeft, Shift, Pt.X, Pt.Y);<br>&nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; WM_RBUTTONUP:<br>&nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Shift := ShiftState + [ssRight];<br>&nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(Pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; MouseUp(mbRight, Shift, Pt.X, Pt.Y);<br>&nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; WM_MBUTTONUP:<br>&nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Shift := ShiftState + [ssMiddle];<br>&nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(Pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; MouseUp(mbMiddle, Shift, Pt.X, Pt.Y);<br>&nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; WM_LBUTTONDBLCLK:<br>&nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; DblClick;<br>&nbsp; &nbsp; &nbsp; &nbsp; { Handle default menu items. But only if LeftPopup is false,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; or it will conflict with the popupmenu, when it is called<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; by a click event. }<br>&nbsp; &nbsp; &nbsp; &nbsp; M := nil;<br>&nbsp; &nbsp; &nbsp; &nbsp; if Assigned(FPopupMenu) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (FPopupMenu.AutoPopup) and (not FLeftPopup) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for I := PopupMenu.Items.Count -1 downto 0 do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if PopupMenu.Items.Default then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; M := PopupMenu.Items;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; if M &lt;&gt; nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; M.Click;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>&nbsp; end<br><br>&nbsp; else &nbsp; &nbsp; &nbsp; &nbsp;// Messages that didn't go through the icon<br>&nbsp; &nbsp; case Msg.Msg of<br>&nbsp; &nbsp; &nbsp; WM_QUERYENDSESSION: Msg.Result := 1;<br>&nbsp; &nbsp; &nbsp; { Evaluate WM_QUERYENDSESSION message to tell Windows that the<br>&nbsp; &nbsp; &nbsp; &nbsp; icon will stop executing if user requests a shutdown (Msg.Result<br>&nbsp; &nbsp; &nbsp; &nbsp; must not return 0, or the system will not be able to shut down). }<br>&nbsp; &nbsp; else &nbsp; &nbsp; &nbsp;// Handle all other messages with the default handler<br>&nbsp; &nbsp; &nbsp; Msg.Result := DefWindowProc(IconData.Wnd, Msg.Msg, Msg.wParam, Msg.lParam);<br>&nbsp; &nbsp; end;<br>end;<br><br><br>procedure TCoolTrayIcon.SetIcon(Value: TIcon);<br>begin<br>&nbsp; FIcon.Assign(Value);<br>&nbsp; ModifyIcon;<br>end;<br><br><br>procedure TCoolTrayIcon.SetIconVisible(Value: Boolean);<br>begin<br>&nbsp; if Value then<br>&nbsp; &nbsp; ShowIcon<br>&nbsp; else<br>&nbsp; &nbsp; HideIcon;<br>end;<br><br><br>procedure TCoolTrayIcon.SetDesignPreview(Value: Boolean);<br>begin<br>&nbsp; FDesignPreview := Value;<br>&nbsp; SettingPreview := True; &nbsp; &nbsp; &nbsp; &nbsp; // Raise flag<br>&nbsp; SetIconVisible(Value);<br>&nbsp; SettingPreview := False; &nbsp; &nbsp; &nbsp; &nbsp;// Clear flag<br>end;<br><br><br>procedure TCoolTrayIcon.SetCycleIcons(Value: Boolean);<br>begin<br>&nbsp; FCycleIcons := Value;<br>&nbsp; if Value then<br>&nbsp; &nbsp; IconIndex := 0;<br>&nbsp; CycleTimer.Enabled := Value;<br>end;<br><br><br>procedure TCoolTrayIcon.SetCycleInterval(Value: Cardinal);<br>begin<br>&nbsp; FCycleInterval := Value;<br>&nbsp; CycleTimer.Interval := FCycleInterval;<br>end;<br><br><br>procedure TCoolTrayIcon.SetHint(Value: String);<br>begin<br>&nbsp; FHint := Value;<br>&nbsp; ModifyIcon;<br>end;<br><br><br>procedure TCoolTrayIcon.SetShowHint(Value: Boolean);<br>begin<br>&nbsp; FShowHint := Value;<br>&nbsp; ModifyIcon;<br>end;<br><br><br>function TCoolTrayIcon.InitIcon: Boolean;<br>// Set icon and tooltip<br>var<br>&nbsp; ok: Boolean;<br>begin<br>&nbsp; Result := False;<br>&nbsp; ok := True;<br>&nbsp; if (csDesigning in ComponentState) {or<br>&nbsp; &nbsp; &nbsp;(csLoading in ComponentState)} then<br>&nbsp; begin<br>&nbsp; &nbsp; if SettingPreview then<br>&nbsp; &nbsp; &nbsp; ok := True<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; ok := FDesignPreview<br>&nbsp; end;<br><br>&nbsp; if ok then<br>&nbsp; begin<br>&nbsp; &nbsp; IconData.hIcon := FIcon.Handle;<br>&nbsp; &nbsp; if (FHint &lt;&gt; '') and (FShowHint) then<br>&nbsp; &nbsp; &nbsp; StrLCopy(IconData.szTip, PChar(FHint), SizeOf(IconData.szTip))<br>&nbsp; &nbsp; &nbsp; // StrLCopy must be used since szTip is only 64 bytes<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; IconData.szTip := '';<br>&nbsp; &nbsp; Result := True;<br>&nbsp; end;<br>end;<br><br><br>function TCoolTrayIcon.ShowIcon: Boolean;<br>// Add/show the icon on the tray<br>begin<br>&nbsp; Result := False;<br>&nbsp; if not SettingPreview then<br>&nbsp; &nbsp; FIconVisible := True;<br>&nbsp; begin<br>&nbsp; &nbsp; if (csDesigning in ComponentState) {or<br>&nbsp; &nbsp; &nbsp;(csLoading in ComponentState)} then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if SettingPreview then<br>&nbsp; &nbsp; &nbsp; &nbsp; if InitIcon then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := Shell_NotifyIcon(NIM_ADD, @IconData);<br>&nbsp; &nbsp; end<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; if InitIcon then<br>&nbsp; &nbsp; &nbsp; Result := Shell_NotifyIcon(NIM_ADD, @IconData);<br>&nbsp; end;<br>end;<br><br><br>function TCoolTrayIcon.HideIcon: Boolean;<br>// Remove/hide the icon from the tray<br>begin<br>&nbsp; Result := False;<br>&nbsp; if not SettingPreview then<br>&nbsp; &nbsp; FIconVisible := False;<br>&nbsp; begin<br>&nbsp; &nbsp; if (csDesigning in ComponentState) {or<br>&nbsp; &nbsp; &nbsp;(csLoading in ComponentState)} then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if SettingPreview then<br>&nbsp; &nbsp; &nbsp; &nbsp; if InitIcon then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := Shell_NotifyIcon(NIM_DELETE, @IconData);<br>&nbsp; &nbsp; end<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; if InitIcon then<br>&nbsp; &nbsp; &nbsp; Result := Shell_NotifyIcon(NIM_DELETE, @IconData);<br>&nbsp; end;<br>end;<br><br><br>function TCoolTrayIcon.ModifyIcon: Boolean;<br>// Change icon or tooltip if icon already placed<br>begin<br>&nbsp; Result := False;<br>&nbsp; if InitIcon then<br>&nbsp; &nbsp; Result := Shell_NotifyIcon(NIM_MODIFY, @IconData);<br>end;<br><br><br>procedure TCoolTrayIcon.TimerCycle(Sender: TObject);<br>begin<br>&nbsp; if Assigned(FIconList) then<br>&nbsp; begin<br>&nbsp; &nbsp; FIconList.GetIcon(IconIndex, FIcon);<br>&nbsp; &nbsp; CycleIcon; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Call event method<br>&nbsp; &nbsp; ModifyIcon;<br><br>&nbsp; &nbsp; if IconIndex &lt; FIconList.Count-1 then<br>&nbsp; &nbsp; &nbsp; Inc(IconIndex)<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; IconIndex := 0;<br>&nbsp; end;<br>end;<br><br>(*<br>procedure TCoolTrayIcon.ShowMainForm;<br>var<br>&nbsp; I, J: Integer;<br>begin<br>// &nbsp;Application.ProcessMessages;<br>&nbsp; // Show application's TASKBAR icon (not the traybar icon)<br>&nbsp; ShowWindow(Application.Handle, SW_RESTORE);<br>// &nbsp;Application.Restore;<br>&nbsp; // Show the form itself<br>&nbsp; ShowWindow(Application.MainForm.Handle, SW_RESTORE);<br>// &nbsp;Application.MainForm.BringToFront;<br><br>&nbsp; { If the main form has not been shown before (if StartMinimized<br>&nbsp; &nbsp; was true (Application.ShowMainForm was false on startup)),<br>&nbsp; &nbsp; it's necessary to force the form's controls to show, as they<br>&nbsp; &nbsp; have been created invisible (regardless of the value of their<br>&nbsp; &nbsp; Visible property). This is done via ShowWindow and a lot of<br>&nbsp; &nbsp; loops. }<br>&nbsp; { By the way: TForm.Position has no effect if StartMinimized<br>&nbsp; &nbsp; is true. Kind of stupid. }<br>{<br>&nbsp; if not HasShown then &nbsp; &nbsp; &nbsp; // This block is only executed once<br>&nbsp; begin<br>&nbsp; &nbsp; for I := 0 to Application.MainForm.ComponentCount -1 do<br>&nbsp; &nbsp; &nbsp; if Application.MainForm.Components is TWinControl then<br>&nbsp; &nbsp; &nbsp; &nbsp; with Application.MainForm.Components as TWinControl do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Visible then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Show this control<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ShowWindow(Handle, SW_SHOWDEFAULT);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Now show child controls owned by this control<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for J := 0 to ComponentCount -1 do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Components[J] is TWinControl then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ShowWindow((Components[J] as TWinControl).Handle, SW_SHOWDEFAULT);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; HasShown := True; &nbsp; &nbsp; &nbsp; &nbsp;// The main form has now been shown<br>&nbsp; end;<br>}<br>end;<br>*)<br><br>procedure TCoolTrayIcon.ShowMainForm;<br>begin<br>&nbsp; // Show application's TASKBAR icon (not the traybar icon)<br>&nbsp; ShowWindow(Application.Handle, SW_RESTORE);<br>// &nbsp;Application.Restore;<br>&nbsp; // Show the form itself<br>&nbsp; Application.MainForm.Visible := True;<br>&nbsp; ShowWindow(Application.MainForm.Handle, SW_RESTORE);<br>end;<br><br><br>procedure TCoolTrayIcon.HideMainForm;<br>begin<br>&nbsp; // Hide application's TASKBAR icon (not the traybar icon)<br>&nbsp; ShowWindow(Application.Handle, SW_HIDE);<br>&nbsp; // Hide the form itself<br>&nbsp; ShowWindow(Application.MainForm.Handle, SW_HIDE);<br>end;<br><br><br>procedure TCoolTrayIcon.Refresh;<br>// Refresh the icon<br>begin<br>&nbsp; ModifyIcon;<br>end;<br><br><br>procedure TCoolTrayIcon.PopupAtCursor;<br>var<br>&nbsp; CursorPos: TPoint;<br>begin<br>&nbsp; if Assigned(PopupMenu) then<br>&nbsp; &nbsp; if PopupMenu.AutoPopup then<br>&nbsp; &nbsp; &nbsp; if GetCursorPos(CursorPos) then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; { Win98 (but not Win95/WinNT) seems to empty a popup menu before<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; closing it. This is a problem when the menu is about to display<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while it already is active (two click-events following each<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; other). The menu will flicker annoyingly.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Calling ProcessMessages fixes this. }<br>&nbsp; &nbsp; &nbsp; &nbsp; Application.ProcessMessages;<br>&nbsp; &nbsp; &nbsp; &nbsp; // Bring the main form to the foreground<br>&nbsp; &nbsp; &nbsp; &nbsp; SetForegroundWindow(Application.MainForm.Handle);<br>&nbsp; &nbsp; &nbsp; &nbsp; // Bring any modal forms owned by the main form to the foregound<br>&nbsp; &nbsp; &nbsp; &nbsp; if Assigned(Screen.ActiveControl) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetFocus(Screen.ActiveControl.Handle);<br>&nbsp; &nbsp; &nbsp; &nbsp; // Now make the menu pop up &nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; PopupMenu.PopupComponent := Self;<br>&nbsp; &nbsp; &nbsp; &nbsp; PopupMenu.Popup(CursorPos.X, CursorPos.Y);<br>&nbsp; &nbsp; &nbsp; &nbsp; PostMessage(Application.MainForm.Handle, WM_NULL, 0, 0);<br>&nbsp; &nbsp; &nbsp; end;<br>end;<br><br><br>procedure TCoolTrayIcon.Click;<br>begin<br>&nbsp; // Execute user-assigned method<br>&nbsp; if Assigned(FOnClick) then<br>&nbsp; &nbsp; FOnClick(Self);<br>end;<br><br><br>procedure TCoolTrayIcon.DblClick;<br>begin<br>&nbsp; // Execute user-assigned method<br>&nbsp; if Assigned(FOnDblClick) then<br>&nbsp; &nbsp; FOnDblClick(Self);<br>end;<br><br><br>procedure TCoolTrayIcon.MouseDown(Button: TMouseButton; Shift: TShiftState;<br>&nbsp; X, Y: Integer);<br>begin<br>&nbsp; // Execute user-assigned method<br>&nbsp; if Assigned(FOnMouseDown) then<br>&nbsp; &nbsp; FOnMouseDown(Self, Button, Shift, X, Y);<br>end;<br><br><br>procedure TCoolTrayIcon.MouseUp(Button: TMouseButton; Shift: TShiftState;<br>&nbsp; X, Y: Integer);<br>begin<br>&nbsp; // Execute user-assigned method<br>&nbsp; if Assigned(FOnMouseUp) then<br>&nbsp; &nbsp; FOnMouseUp(Self, Button, Shift, X, Y);<br>end;<br><br><br>procedure TCoolTrayIcon.MouseMove(Shift: TShiftState; X, Y: Integer);<br>begin<br>&nbsp; // Execute user-assigned method<br>&nbsp; if Assigned(FOnMouseMove) then<br>&nbsp; &nbsp; FOnMouseMove(Self, Shift, X, Y);<br>end;<br><br><br>procedure TCoolTrayIcon.CycleIcon;<br>begin<br>&nbsp; // Execute user-assigned method<br>&nbsp; if Assigned(FOnCycle) then<br>&nbsp; &nbsp; FOnCycle(Self, IconIndex);<br>end;<br><br><br>procedure TCoolTrayIcon.DoMinimizeToTray;<br>begin<br>&nbsp; // Override this method to change automatic tray minimizing behavior<br>&nbsp; HideMainForm;<br>&nbsp; IconVisible := True;<br>end;<br><br><br>procedure Register;<br>begin<br>&nbsp; RegisterComponents('MyVCL', [TCoolTrayIcon]);<br>end;<br><br>end.<br>
 
感谢这位大哥提供给我这个控件,希望别人能用到。<br><br>这种在SystemTray中添加,删除自己程序的图标的技术我不需要。我自己也能实现<br>我需要的是如何枚举系统托盘中各项图标的控制窗体的句柄,以及其图标的uID的方法。<br><br>哪位知道??<br><br>不会真的自己枚举吧??42亿个uID啊~~~哭。<br>
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
404
import
I
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
顶部