关于托盘 ,为什么图标出不来(100分)

Z

zhb2002

Unregistered / Unconfirmed
GUEST, unregistred user!
托盘里的图标出不来什么原因<br>有源程序提供则万分感谢
 
给个VERY BIG(可以COPY使用的) 的给你,慢慢看吧! 呵呵 :)!(可记得要给分哦![8D])<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; { Define user-defined message sent by the trayicon. We avoid low user-defined<br>&nbsp; &nbsp; messages that are used by Windows itself (eg. WM_USER+1 = DM_SETDEFID). }<br>&nbsp; WM_TRAYNOTIFY = WM_USER + 1024;<br>&nbsp; // Constant used for recreating trayicon on system traybar recover<br>&nbsp; IconID = 1;<br>&nbsp; // Constants used for balloon hint feature<br>&nbsp; WM_RESETTOOLTIP = WM_USER + 1025;<br>&nbsp; NIIF_NONE &nbsp; &nbsp;= $00000000;<br>&nbsp; NIIF_INFO &nbsp; &nbsp;= $00000001;<br>&nbsp; NIIF_WARNING = $00000002;<br>&nbsp; NIIF_ERROR &nbsp; = $00000003;<br>&nbsp; NIF_INFO &nbsp; &nbsp; = $00000010;<br><br>var<br>&nbsp; WM_TASKBARCREATED: Cardinal;<br><br>type<br>&nbsp; { You can use the TNotifyIconData record structure defined in shellapi.pas.<br>&nbsp; &nbsp; However, WinME, Win2000, and WinXP have expanded this structure. We define<br>&nbsp; &nbsp; a similar structure, TNotifyIconDataEx. }<br>&nbsp; TNotifyIconDataEx = record<br>&nbsp; &nbsp; cbSize: DWORD;<br>&nbsp; &nbsp; Wnd: HWND;<br>&nbsp; &nbsp; uID: UINT;<br>&nbsp; &nbsp; uFlags: UINT;<br>&nbsp; &nbsp; uCallbackMessage: UINT;<br>&nbsp; &nbsp; hIcon: HICON;<br>// &nbsp; &nbsp;szTip: array[0..63] of AnsiChar;<br>&nbsp; &nbsp; szTip: array[0..127] of AnsiChar; &nbsp; &nbsp; &nbsp;// 0..63 of WideChar in stead?<br>&nbsp; &nbsp; dwState: DWORD;<br>&nbsp; &nbsp; dwStateMask: DWORD;<br>&nbsp; &nbsp; szInfo: array[0..255] of AnsiChar;<br>&nbsp; &nbsp; uTimeout: UINT; // union with uVersion: UINT;<br>&nbsp; &nbsp; szInfoTitle: array[0..63] of AnsiChar;<br>&nbsp; &nbsp; dwInfoFlags: DWORD;<br>&nbsp; end;<br><br>&nbsp; TBalloonHintIcon = (bitNone, bitInfo, bitWarning, bitError);<br>&nbsp; TBalloonHintTimeOut = 10..60; &nbsp; // Windows defines 10-60 secs. as min-max<br><br>&nbsp; TCycleEvent = procedure(Sender: TObject; NextIndex: 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; FClickStart: Boolean;<br>&nbsp; &nbsp; CycleTimer: TTimer; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// For icon cycling<br>&nbsp; &nbsp; FIconIndex: Integer; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Current index in imagelist<br>&nbsp; &nbsp; FDesignPreview: Boolean;<br>&nbsp; &nbsp; SettingPreview: Boolean; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Internal status flag<br>&nbsp; &nbsp; SettingMDIForm: Boolean; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Internal status flag<br>&nbsp; &nbsp; FIconList: TImageList;<br>&nbsp; &nbsp; FCycleIcons: Boolean;<br>&nbsp; &nbsp; FCycleInterval: Cardinal;<br>&nbsp; &nbsp; OldAppProc, NewAppProc: Pointer; &nbsp; // Procedure variables<br>&nbsp; &nbsp; OldWndProc, NewWndProc: Pointer; &nbsp; // Procedure variables<br>&nbsp; &nbsp; FWindowHandle: HWND; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Window handle (not general handle)<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 SetIconList(Value: TImageList);<br>&nbsp; &nbsp; procedure SetIconIndex(Value: Integer);<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 Msg: TMessage);<br>&nbsp; &nbsp; procedure HookParent;<br>&nbsp; &nbsp; procedure UnhookParent;<br>&nbsp; &nbsp; procedure HookWndProc(var Msg: TMessage);<br>&nbsp; protected<br>&nbsp; &nbsp; IconData: TNotifyIconDataEx; &nbsp; &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; property WindowHandle: HWND read FWindowHandle;<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; function Refresh: Boolean;<br>&nbsp; &nbsp; function ShowBalloonHint(Title: String; Text: String; IconType: TBalloonHintIcon;<br>&nbsp; &nbsp; &nbsp; TimeoutSecs: TBalloonHintTimeOut): Boolean;<br>&nbsp; &nbsp; function BitmapToIcon(const Bitmap: TBitmap; const Icon: TIcon;<br>&nbsp; &nbsp; &nbsp; MaskColor: TColor): Boolean;<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 SetIconList;<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; &nbsp; default True;<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 IconIndex: Integer read FIconIndex write SetIconIndex;<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 app. 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; SettingMDIForm := True;<br>&nbsp; FIconVisible := True; &nbsp; &nbsp; &nbsp;// Visible by default<br>&nbsp; FEnabled := True; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Enabled by default<br>&nbsp; FShowHint := True; &nbsp; &nbsp; &nbsp; &nbsp; // Show hint by default<br>&nbsp; SettingPreview := False;<br><br>&nbsp; // Use the TaskbarCreated message available from Win98/IE4+<br>&nbsp; WM_TASKBARCREATED := RegisterWindowMessage('TaskbarCreated');<br><br>&nbsp; FIcon := TIcon.Create;<br>&nbsp; IconData.cbSize := SizeOf(TNotifyIconDataEx);<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 by default<br>&nbsp; IconData.uFlags := NIF_ICON + NIF_MESSAGE + NIF_TIP;<br>&nbsp; // Message to send to IconData.wnd when event occurs<br>&nbsp; IconData.uCallbackMessage := WM_TRAYNOTIFY;<br><br>&nbsp; FWindowHandle := GetWindowLong(IconData.wnd, GWL_HWNDPARENT);<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><br>&nbsp; // Hook into the main form's message handling<br>&nbsp; if not (csDesigning in ComponentState) then<br>&nbsp; &nbsp; HookParent;<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; if not (csDesigning in ComponentState) then<br>&nbsp; &nbsp; UnhookParent;<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 is about<br>&nbsp; &nbsp; to be deleted }<br>&nbsp; if (AComponent = IconList) and (Operation = opRemove) then<br>&nbsp; begin<br>&nbsp; &nbsp; FIconList := nil;<br>&nbsp; &nbsp; IconList := nil;<br>&nbsp; end;<br>&nbsp; if (AComponent = PopupMenu) and (Operation = opRemove) then<br>&nbsp; begin<br>&nbsp; &nbsp; FPopupMenu := nil;<br>&nbsp; &nbsp; PopupMenu := nil;<br>&nbsp; end;<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 solution is to hook into the app.'s message handling (via HookApp).<br>&nbsp; You can then catch any message that goes through the app. and still<br>&nbsp; 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 Msg: TMessage);<br>begin<br>&nbsp; case Msg.Msg of<br><br>&nbsp; &nbsp; WM_SIZE:<br>&nbsp; &nbsp; &nbsp; // Handle MinimizeToTray by capturing app's minimize events<br>&nbsp; &nbsp; &nbsp; if Msg.wParam = SIZE_MINIMIZED then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; if FMinimizeToTray then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DoMinimizeToTray;<br>&nbsp; &nbsp; &nbsp; &nbsp; { You could insert a call to a custom minimize event here, but it<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; would behave exactly like Application.OnMinimize, so I see no<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; need for it. }<br>&nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; WM_WINDOWPOSCHANGED: begin<br>&nbsp; &nbsp; &nbsp; { Handle MDI forms (MDI children cause app. to be redisplayed on<br>&nbsp; &nbsp; &nbsp; &nbsp; taskbar. We hide it again. This may cause a quick flicker (?)). }<br>&nbsp; &nbsp; &nbsp; if SettingMDIForm then<br>&nbsp; &nbsp; &nbsp; &nbsp; if Application.MainForm &lt;&gt; nil then &nbsp; &nbsp; &nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Application.MainForm.FormStyle = fsMDIForm then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if FStartMinimized then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ShowWindow(Application.Handle, SW_HIDE);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SettingMDIForm := False; &nbsp; // So we only do this once<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br><br>&nbsp; end; &nbsp; <br><br>&nbsp; { Show the tray icon if the taskbar has been re-created after an<br>&nbsp; &nbsp; Explorer crash. }<br>&nbsp; if Msg.Msg = WM_TASKBARCREATED then<br>&nbsp; &nbsp; if FIconVisible then<br>&nbsp; &nbsp; &nbsp; ShowIcon;<br><br>&nbsp; // Pass the message on<br>&nbsp; Msg.Result := CallWindowProc(OldAppProc, Application.Handle,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Msg.Msg, Msg.wParam, Msg.lParam);<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.<br>&nbsp; This is necessary in order to properly handle when the user minimizes<br>&nbsp; the form using the TASKBAR icon. }<br><br>procedure TCoolTrayIcon.HookParent;<br>begin<br>&nbsp; if (Owner as TWinControl) &lt;&gt; nil 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>{ All main form messages pass through HookWndProc. You can override the<br>&nbsp; messages by not passing them along to Windows (via CallWindowProc).<br>&nbsp; You should be careful with the graphical messages, though. }<br><br>procedure TCoolTrayIcon.HookWndProc(var Msg: TMessage);<br>begin<br>&nbsp; case Msg.Msg of<br><br>&nbsp; &nbsp; WM_SHOWWINDOW: begin<br>&nbsp; &nbsp; &nbsp; if (Msg.lParam = 0) and (Msg.wParam = 1) then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; // Show the taskbar icon (Windows may have shown it already)<br>&nbsp; &nbsp; &nbsp; &nbsp; ShowWindow(Application.Handle, SW_RESTORE);<br>&nbsp; &nbsp; &nbsp; &nbsp; // Bring the taskbar icon and the main form to the foreground<br>&nbsp; &nbsp; &nbsp; &nbsp; SetForegroundWindow(Application.Handle);<br>&nbsp; &nbsp; &nbsp; &nbsp; SetForegroundWindow((Owner as TWinControl).Handle);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>{<br>&nbsp; &nbsp; WM_WINDOWPOSCHANGED: begin<br>&nbsp; &nbsp; &nbsp; // Bring any modal forms owned by the main form to the foreground<br>&nbsp; &nbsp; &nbsp; if Assigned(Screen.ActiveControl) then<br>&nbsp; &nbsp; &nbsp; &nbsp; SetFocus(Screen.ActiveControl.Handle);<br>&nbsp; &nbsp; end;<br>}<br>&nbsp; &nbsp; WM_ACTIVATE: begin<br>&nbsp; &nbsp; &nbsp; // Bring any modal forms owned by the main form to the foreground<br>&nbsp; &nbsp; &nbsp; if Assigned(Screen.ActiveControl) then<br>&nbsp; &nbsp; &nbsp; &nbsp; if (Msg.WParamLo = WA_ACTIVE) or (Msg.WParamLo = WA_CLICKACTIVE) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Assigned(Screen.ActiveControl.Parent) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Control on modal form is active<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if HWND(Msg.lParam) &lt;&gt; Screen.ActiveControl.Parent.Handle then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetFocus(Screen.ActiveControl.Handle);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Modal form itself is active<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if HWND(Msg.lParam) &lt;&gt; Screen.ActiveControl.Handle then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetFocus(Screen.ActiveControl.Handle);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br><br>&nbsp; end;<br>&nbsp; // Pass the message on<br>&nbsp; Msg.Result := CallWindowProc(OldWndProc, (Owner as TWinControl).Handle,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Msg.Msg, Msg.wParam, Msg.lParam);<br>end;<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; In these cases use lParam to get the actual message, eg. WM_MOUSEMOVE.<br>&nbsp; The method sends the usual Delphi events for the mouse messages. It also<br>&nbsp; interpolates the OnClick event when the user clicks the left button, and<br>&nbsp; makes the 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 GetAsyncKeyState(VK_SHIFT) &lt; 0 then<br>&nbsp; &nbsp; &nbsp; Include(Result, ssShift);<br>&nbsp; &nbsp; if GetAsyncKeyState(VK_CONTROL) &lt; 0 then<br>&nbsp; &nbsp; &nbsp; Include(Result, ssCtrl);<br>&nbsp; &nbsp; if GetAsyncKeyState(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; &nbsp; WM_MOUSEMOVE:<br>&nbsp; &nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Shift := ShiftState;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(Pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MouseMove(Shift, Pt.X, Pt.Y);<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; WM_LBUTTONDOWN:<br>&nbsp; &nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Shift := ShiftState + [ssLeft];<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(Pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MouseDown(mbLeft, Shift, Pt.X, Pt.Y);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FClickStart := True;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if FLeftPopup then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PopupAtCursor;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; WM_RBUTTONDOWN:<br>&nbsp; &nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Shift := ShiftState + [ssRight];<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(Pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MouseDown(mbRight, Shift, Pt.X, Pt.Y);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PopupAtCursor;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; WM_MBUTTONDOWN:<br>&nbsp; &nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Shift := ShiftState + [ssMiddle];<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(Pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MouseDown(mbMiddle, Shift, Pt.X, Pt.Y);<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; WM_LBUTTONUP:<br>&nbsp; &nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Shift := ShiftState + [ssLeft];<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(Pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if FClickStart then &nbsp; &nbsp; &nbsp; // Then WM_LBUTTONDOWN was called before<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FClickStart := False;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Click; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// We have a click<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MouseUp(mbLeft, Shift, Pt.X, Pt.Y);<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; WM_RBUTTONUP:<br>&nbsp; &nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Shift := ShiftState + [ssRight];<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(Pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MouseUp(mbRight, Shift, Pt.X, Pt.Y);<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; WM_MBUTTONUP:<br>&nbsp; &nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Shift := ShiftState + [ssMiddle];<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(Pt);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MouseUp(mbMiddle, Shift, Pt.X, Pt.Y);<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; WM_LBUTTONDBLCLK:<br>&nbsp; &nbsp; &nbsp; &nbsp; if FEnabled then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DblClick;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { Handle default menu items. But only if LeftPopup is false,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; or it will conflict with the popupmenu, when it is called<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; by a click event. }<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; M := nil;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Assigned(FPopupMenu) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (FPopupMenu.AutoPopup) and (not FLeftPopup) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for I := PopupMenu.Items.Count -1 downto 0 do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if PopupMenu.Items.Default then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; M := PopupMenu.Items;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if M &lt;&gt; nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; M.Click;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &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; { Windows sends us a WM_QUERYENDSESSION message when it prepares<br>&nbsp; &nbsp; &nbsp; &nbsp; for shutdown. Msg.Result must not return 0, or the system will<br>&nbsp; &nbsp; &nbsp; &nbsp; be unable to shut down. }<br>&nbsp; &nbsp; &nbsp; WM_QUERYENDSESSION: begin<br>//showmessage('WM_QUERYENDSESSION');<br>// &nbsp; &nbsp; &nbsp; &nbsp;PostQuitMessage(0);<br>&nbsp; &nbsp; &nbsp; &nbsp; Msg.Result := 1;<br>&nbsp; &nbsp; &nbsp; end;<br>{<br>&nbsp; &nbsp; &nbsp; WM_DESTROY: begin<br>showmessage('WM_DESTROY');<br>&nbsp; &nbsp; &nbsp; &nbsp; PostQuitMessage(0);<br>&nbsp; &nbsp; &nbsp; &nbsp; Msg.Result := 0;<br>&nbsp; &nbsp; &nbsp; end;<br>}<br>{<br>&nbsp; &nbsp; &nbsp; WM_ENDSESSION: begin<br>//showmessage('WM_ENDSESSION');<br>&nbsp; &nbsp; &nbsp; &nbsp; Msg.Result := 0;<br>&nbsp; &nbsp; &nbsp; end;<br>}<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; SetIconIndex(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.SetIconList(Value: TImageList);<br>begin<br>&nbsp; FIconList := Value;<br>{<br>&nbsp; // Set CycleIcons = false if IconList is nil<br>&nbsp; if Value = nil then<br>&nbsp; &nbsp; SetCycleIcons(False);<br>}<br>&nbsp; SetIconIndex(0);<br>end;<br><br><br>procedure TCoolTrayIcon.SetIconIndex(Value: Integer);<br>begin<br>&nbsp; if FIconList &lt;&gt; nil then<br>&nbsp; begin<br>&nbsp; &nbsp; FIconIndex := Value;<br>&nbsp; &nbsp; if Value &gt;= FIconList.Count then<br>&nbsp; &nbsp; &nbsp; FIconIndex := FIconList.Count -1;<br>&nbsp; &nbsp; FIconList.GetIcon(FIconIndex, FIcon);<br>&nbsp; end<br>&nbsp; else<br>&nbsp; &nbsp; FIconIndex := 0;<br><br>&nbsp; ModifyIcon;<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)-1)<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(FIconIndex, 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 FIconIndex &lt; FIconList.Count-1 then<br>&nbsp; &nbsp; &nbsp; SetIconIndex(FIconIndex+1)<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; SetIconIndex(0);<br>&nbsp; end;<br>end;<br><br><br>procedure TCoolTrayIcon.ShowMainForm;<br>begin<br>&nbsp; if Application.MainForm &lt;&gt; nil then<br>&nbsp; begin<br>&nbsp; &nbsp; // Show application's TASKBAR icon (not the traybar icon)<br>&nbsp; &nbsp; ShowWindow(Application.Handle, SW_RESTORE);<br>// &nbsp; &nbsp;ShowWindow(Application.Handle, SW_SHOWNORMAL);<br>// &nbsp; &nbsp;Application.Restore;<br>&nbsp; &nbsp; // Show the form itself<br>&nbsp; &nbsp; Application.MainForm.Visible := True;<br>// &nbsp; &nbsp;ShowWindow((Owner as TWinControl).Handle, SW_RESTORE);<br>&nbsp; end;<br>end;<br><br><br>procedure TCoolTrayIcon.HideMainForm;<br>begin<br>&nbsp; if Application.MainForm &lt;&gt; nil then<br>&nbsp; begin<br>&nbsp; &nbsp; // Hide the form itself (and thus any child windows)<br>&nbsp; &nbsp; Application.MainForm.Visible := False;<br>&nbsp; &nbsp; { Hide application's TASKBAR icon (not the traybar icon).<br>&nbsp; &nbsp; &nbsp; Do this AFTER the mainform is hidden, or any child windows<br>&nbsp; &nbsp; &nbsp; will redisplay the taskbar icon if they are visible. }<br>&nbsp; &nbsp; ShowWindow(Application.Handle, SW_HIDE);<br>&nbsp; end;<br>end;<br><br><br>function TCoolTrayIcon.ShowBalloonHint(Title: String; Text: String;<br>&nbsp; IconType: TBalloonHintIcon; TimeoutSecs: TBalloonHintTimeOut): Boolean;<br>// Show balloon hint. Return false if error.<br>const<br>&nbsp; aBalloonIconTypes: array[TBalloonHintIcon] of Byte =<br>&nbsp; &nbsp; (NIIF_NONE, NIIF_INFO, NIIF_WARNING, NIIF_ERROR);<br>begin<br>&nbsp; if FEnabled then<br>&nbsp; begin<br>&nbsp; &nbsp; // Remove old balloon hint<br>&nbsp; &nbsp; with IconData do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; uFlags := uFlags or NIF_INFO;<br>&nbsp; &nbsp; &nbsp; StrPCopy(szInfo, '');<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; ModifyIcon;<br>&nbsp; &nbsp; // Display new balloon hint<br>&nbsp; &nbsp; with IconData do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; uFlags := uFlags or NIF_INFO;<br>&nbsp; &nbsp; &nbsp; StrPCopy(szInfo, Text);<br>&nbsp; &nbsp; &nbsp; StrPCopy(szInfoTitle, Title);<br>&nbsp; &nbsp; &nbsp; uTimeout := TimeoutSecs * 1000;<br>&nbsp; &nbsp; &nbsp; dwInfoFlags := aBalloonIconTypes[IconType];<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; Result := ModifyIcon;<br>&nbsp; &nbsp; { Remove NIF_INFO before next call to ModifyIcon (or else the balloon hint<br>&nbsp; &nbsp; &nbsp; will redisplay itself) }<br>&nbsp; &nbsp; with IconData do<br>&nbsp; &nbsp; &nbsp; uFlags := NIF_ICON + NIF_MESSAGE + NIF_TIP;<br>&nbsp; end<br>&nbsp; else<br>&nbsp; &nbsp; Result := True;<br>end;<br><br><br>function TCoolTrayIcon.BitmapToIcon(const Bitmap: TBitmap;<br>&nbsp; const Icon: TIcon; MaskColor: TColor): Boolean;<br>{ Render an icon from a 16x16 bitmap. Return false if error.<br>&nbsp; MaskColor is a color that will be rendered transparently. Use clNone for<br>&nbsp; no transparency. }<br>var<br>&nbsp; BitmapImageList: TImageList;<br>begin<br>&nbsp; BitmapImageList := TImageList.CreateSize(16, 16);<br>&nbsp; try<br>&nbsp; &nbsp; Result := False;<br>&nbsp; &nbsp; BitmapImageList.AddMasked(Bitmap, MaskColor);<br>&nbsp; &nbsp; BitmapImageList.GetIcon(0, Icon);<br>&nbsp; &nbsp; Result := True;<br>&nbsp; finally<br>&nbsp; &nbsp; BitmapImageList.Free;<br>&nbsp; end;<br>end;<br><br><br>function TCoolTrayIcon.Refresh: Boolean;<br>// Refresh the icon<br>begin<br>&nbsp; Result := 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 in succession). The<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; menu will flicker annoyingly. Calling ProcessMessages fixes this. }<br>&nbsp; &nbsp; &nbsp; &nbsp; Application.ProcessMessages;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; { Bring the main form or its modal dialog to the foreground.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; This also ensures the popup menu closes after it loses focus. }<br>&nbsp; &nbsp; &nbsp; &nbsp; SetForegroundWindow((Owner as TWinControl).Handle);<br>{<br>This seems unnecessary(?):<br>&nbsp; &nbsp; &nbsp; &nbsp; if Screen.ActiveControl &lt;&gt; nil then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (Screen.ActiveControl.Owner is TWinControl) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetForegroundWindow((Screen.ActiveControl.Owner as TWinControl).Handle);<br>}<br>&nbsp; &nbsp; &nbsp; &nbsp; // Now make the menu pop up<br>&nbsp; &nbsp; &nbsp; &nbsp; PopupMenu.PopupComponent := Self;<br>&nbsp; &nbsp; &nbsp; &nbsp; PopupMenu.Popup(CursorPos.X, CursorPos.Y);<br>&nbsp; &nbsp; &nbsp; &nbsp; // Post an empty message to make the popup menu disappear<br>&nbsp; &nbsp; &nbsp; &nbsp; PostMessage((Owner as TWinControl).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>var<br>&nbsp; NextIconIndex: Integer;<br>begin<br>&nbsp; // Execute user-assigned method<br>&nbsp; NextIconIndex := 0;<br>&nbsp; if FIconList &lt;&gt; nil then<br>&nbsp; &nbsp; if FIconIndex &lt; FIconList.Count then<br>&nbsp; &nbsp; &nbsp; NextIconIndex := FIconIndex +1;<br><br>&nbsp; if Assigned(FOnCycle) then<br>&nbsp; &nbsp; FOnCycle(Self, NextIconIndex);<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('Custom', [TCoolTrayIcon]);<br>end;<br><br>end.<br>
 
到http://delphi.mychangshu.com/<br>查找"托盘",有一个很好的例子,<br>按照这个例子应该可以明白一些问题了。
 
多人接受答案了。
 

Similar threads

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