CnTrayIcon.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. {******************************************************************************}
  2. { CnPack For Delphi/C++Builder }
  3. { 中国人自己的开放源码第三方开发包 }
  4. { (C)Copyright 2001-2018 CnPack 开发组 }
  5. { ------------------------------------ }
  6. { }
  7. { 本开发包是开源的自由软件,您可以遵照 CnPack 的发布协议来修 }
  8. { 改和重新发布这一程序。 }
  9. { }
  10. { 发布这一开发包的目的是希望它有用,但没有任何担保。甚至没有 }
  11. { 适合特定目的而隐含的担保。更详细的情况请参阅 CnPack 发布协议。 }
  12. { }
  13. { 您应该已经和开发包一起收到一份 CnPack 发布协议的副本。如果 }
  14. { 还没有,可访问我们的网站: }
  15. { }
  16. { 网站地址:http://www.cnpack.org }
  17. { 电子邮件:master@cnpack.org }
  18. { }
  19. {******************************************************************************}
  20. unit CnTrayIcon;
  21. {* |<PRE>
  22. ================================================================================
  23. * 软件名称:不可视工具组件包
  24. * 单元名称:TCnTrayIcon 单元
  25. * 单元作者:刘啸 liuxiao@cnpack.org; http://www.cnpack.org
  26. * 备 注:在 Explorer 非法结束重启后能自动恢复图标的系统托盘组件单元
  27. * 开发平台:PWin98SE + Delphi 5.0
  28. * 兼容测试:PWin9X/2000/XP + Delphi 5/6
  29. * 本 地 化:该单元中的字符串均符合本地化处理方式
  30. * 单元标识:$Id$
  31. * 修改记录:2012.06.21 V1.3
  32. * 恢复显示时加入一句BringToFront
  33. * 2005.02.05 V1.2
  34. * 修正显示气泡提示后弹出菜单和提示失效的问题
  35. * 2004.03.07 V1.1
  36. * 加入显示气泡提示和最小化时自动隐藏主窗口的功能
  37. * 2004.03.05 V1.0
  38. * 创建单元
  39. ================================================================================
  40. |</PRE>}
  41. interface
  42. {$I CnPack.inc}
  43. uses
  44. SysUtils, Classes, Messages, Windows, Forms, Menus, Controls,
  45. Graphics, ShellAPI, CnClasses, CnConsts, CnCompConsts;
  46. type
  47. EBalloonHintError = class(Exception);
  48. TMouseButtons = set of TMouseButton;
  49. TBalloonType = (btNone, btError, btInfo, btWarning);
  50. TNotifyIconDataXP = record
  51. cbSize: DWORD;
  52. Wnd: HWND;
  53. uID: UINT;
  54. uFlags: UINT;
  55. uCallbackMessage: UINT;
  56. hIcon: HICON;
  57. szTip: array [0..127] of AnsiChar;
  58. dwState: DWORD;
  59. dwStateMask: DWORD;
  60. szInfo: array [0..255] of AnsiChar;
  61. uTimeOut: DWORD;
  62. szInfoTitle: array [0..63] of AnsiChar;
  63. dwInfoFlags: DWORD;
  64. end;
  65. TCnTrayIcon = class(TCnComponent)
  66. private
  67. FHandle: HWND;
  68. FAcceptBalloons: Boolean;
  69. FActive: Boolean;
  70. FAdded: Boolean;
  71. FEnabled: Boolean;
  72. FClicked: TMouseButtons;
  73. FIconData: TNotifyIconData;
  74. FIconXP: TNotifyIconDataXP;
  75. FIcon: TIcon;
  76. FHint: string;
  77. FShowDesign: Boolean;
  78. FPopupMenu: TPopupMenu;
  79. FOnClick: TMouseEvent;
  80. FOnDblClick: TNotifyEvent;
  81. FOnMouseMove: TMouseMoveEvent;
  82. FOnMouseDown: TMouseEvent;
  83. FOnMouseUp: TMouseEvent;
  84. FOnBalloonShow: TNotifyEvent;
  85. FUseAppIcon: Boolean;
  86. FHooked: Boolean;
  87. FAutoHide: Boolean;
  88. FSaveWindowState: TWindowState;
  89. procedure ChangeIcon;
  90. procedure SendCancelMode;
  91. function CheckMenuPopup(X: Integer; Y: Integer): Boolean;
  92. function CheckDefaultMenuItem: Boolean;
  93. procedure SetHint(const Value: string);
  94. procedure SetIcon(Value: TIcon);
  95. procedure SetPopupMenu(Value: TPopupMenu);
  96. procedure Activate;
  97. procedure Deactivate;
  98. procedure HookApp;
  99. procedure UnHookApp;
  100. procedure SetActive(Value: Boolean);
  101. procedure SetShowDesign(Value: Boolean);
  102. procedure IconChanged(Sender: TObject);
  103. procedure WndProc(var Message: TMessage);
  104. procedure SetUseAppIcon(const Value: Boolean);
  105. function ApplicationHook(var Msg: TMessage): Boolean;
  106. protected
  107. procedure DblClick; dynamic;
  108. procedure DoClick(Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer); dynamic;
  109. procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer); dynamic;
  110. procedure MouseMove(Shift: TShiftState; X: Integer; Y: Integer); dynamic;
  111. procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer); dynamic;
  112. procedure Loaded; override;
  113. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  114. procedure UpdateNotifyData; virtual;
  115. procedure GetComponentInfo(var AName, Author, Email, Comment: string); override;
  116. public
  117. constructor Create(AOwner: TComponent); override;
  118. destructor Destroy; override;
  119. procedure HideIcon;
  120. procedure ShowIcon;
  121. procedure HideApplication;
  122. procedure ShowApplication;
  123. procedure BalloonHint(const Title, Value: string; BalloonType: TBalloonType = btNone;
  124. DelaySeconds: Integer = 5);
  125. property Handle: HWND read FHandle;
  126. published
  127. property Active: Boolean read FActive write SetActive default True;
  128. property AutoHide: Boolean read FAutoHide write FAutoHide;
  129. property Enabled: Boolean read FEnabled write FEnabled default True;
  130. property Hint: string read FHint write SetHint;
  131. property Icon: TIcon read FIcon write SetIcon;
  132. property PopupMenu: TPopupMenu read FPopupMenu write SetPopupMenu;
  133. property ShowDesign: Boolean read FShowDesign write SetShowDesign stored False;
  134. property UseAppIcon: Boolean read FUseAppIcon write SetUseAppIcon;
  135. property OnClick: TMouseEvent read FOnClick write FOnClick;
  136. property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;
  137. property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove;
  138. property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;
  139. property OnMouseUp: TMouseEvent read FOnMouseUp write FOnMouseUp;
  140. property OnBalloonShow: TNotifyEvent read FOnBalloonShow write FOnBalloonShow;
  141. end;
  142. implementation
  143. uses
  144. CnCommon;
  145. const
  146. SCnCreateTaskBar: string = 'TaskbarCreated';
  147. SCnTrayIcon: string = 'CnTrayIcon';
  148. NIF_STATE = $00000008;
  149. NIF_INFO = $00000010;
  150. NIIF_NONE = $00000000;
  151. NIIF_INFO = $00000001;
  152. NIIF_WARNING = $00000002;
  153. NIIF_ERROR = $00000003;
  154. NIN_BALLOONSHOW = WM_USER + 2;
  155. NIN_BALLOONHIDE = WM_USER + 3;
  156. NIN_BALLOONTIMEOUT = WM_USER + 4;
  157. NIN_BALLOONUSERCLICK = WM_USER + 5;
  158. var
  159. WM_CNCREATETASKBAR: Cardinal;
  160. WM_CNTRAYICONCALLBACK: Cardinal;
  161. procedure SwitchToWindow(Wnd: HWnd; Restore: Boolean);
  162. begin
  163. if IsWindowEnabled(Wnd) then
  164. begin
  165. SetForegroundWindow(Wnd);
  166. if Restore and IsWindowVisible(Wnd) then
  167. begin
  168. if not IsZoomed(Wnd) then
  169. SendMessage(Wnd, WM_SYSCOMMAND, SC_RESTORE, 0);
  170. SetFocus(Wnd);
  171. end;
  172. end;
  173. end;
  174. { TCnTrayIcon }
  175. procedure TCnTrayIcon.Activate;
  176. var
  177. S: string;
  178. begin
  179. Deactivate;
  180. if FIcon.Handle <> 0 then
  181. begin
  182. FClicked := [];
  183. UpdateNotifyData;
  184. FAdded := Shell_NotifyIconA(NIM_ADD, @FIconData);
  185. S := GetShortHint(FHint);
  186. if FAdded and (S <> '') then
  187. Shell_NotifyIconA(NIM_MODIFY, @FIconData);
  188. end;
  189. end;
  190. procedure TCnTrayIcon.BalloonHint(const Title, Value: string;
  191. BalloonType: TBalloonType; DelaySeconds: Integer);
  192. begin
  193. if FAcceptBalloons then
  194. begin
  195. FIconXP.cbSize := SizeOf(FIconXP);
  196. FIconXP.Wnd := FHandle;
  197. FIconXP.hIcon := FIcon.Handle;
  198. StrPLCopy(FIconXP.szInfoTitle, {$IFDEF UNICODE}AnsiString{$ENDIF}(Title), SizeOf(FIconXP.szInfoTitle) - 1);
  199. StrPLCopy(FIconXP.szInfo, {$IFDEF UNICODE}AnsiString{$ENDIF}(Value), SizeOf(FIconXP.szInfo) - 1);
  200. FIconXP.uFlags := NIF_ICON or NIF_INFO; // 此处如加其他标志会导致其他标志失效
  201. FIconXP.uTimeOut := DelaySeconds;
  202. case BalloonType of
  203. btError:
  204. FIconXP.dwInfoFlags := NIIF_ERROR;
  205. btInfo:
  206. FIconXP.dwInfoFlags := NIIF_INFO;
  207. btNone:
  208. FIconXP.dwInfoFlags := NIIF_NONE;
  209. btWarning:
  210. FIconXP.dwInfoFlags := NIIF_WARNING;
  211. end;
  212. Shell_NotifyIconA(NIM_MODIFY, @FIconXP);
  213. if Assigned(FOnBalloonShow) then
  214. FOnBalloonShow(Self);
  215. end
  216. else
  217. raise EBalloonHintError.Create('Balloon Hint not Supported.');
  218. end;
  219. procedure TCnTrayIcon.ChangeIcon;
  220. begin
  221. if FAdded then
  222. begin
  223. if FIcon.Handle <> 0 then
  224. begin
  225. UpdateNotifyData;
  226. Shell_NotifyIconA(NIM_MODIFY, @FIconData);
  227. end
  228. else
  229. Deactivate;
  230. Exit;
  231. end;
  232. if (csDesigning in ComponentState) and FShowDesign or
  233. (not (csDesigning in ComponentState) and FActive) then
  234. Activate;
  235. end;
  236. function TCnTrayIcon.CheckDefaultMenuItem: Boolean;
  237. var
  238. Item: TMenuItem;
  239. I: Integer;
  240. begin
  241. Result := False;
  242. if not (csDesigning in ComponentState) then
  243. if FActive and (FPopupMenu <> nil) then
  244. if FPopupMenu.Items <> nil then
  245. begin
  246. for I := 0 to FPopupMenu.Items.Count - 1 do
  247. begin
  248. Item := FPopupMenu.Items[I];
  249. if Item.Default and Item.Enabled then
  250. begin
  251. Item.Click;
  252. Result := True;
  253. Break;
  254. end;
  255. end;
  256. end;
  257. end;
  258. function TCnTrayIcon.CheckMenuPopup(X, Y: Integer): Boolean;
  259. begin
  260. Result := False;
  261. if not (csDesigning in ComponentState) then
  262. begin
  263. if FActive and (FPopupMenu <> nil) then
  264. begin
  265. if FPopupMenu.AutoPopup then
  266. begin
  267. FPopupMenu.PopupComponent := Self;
  268. SendCancelMode;
  269. SwitchToWindow(FHandle, False);
  270. Application.ProcessMessages;
  271. try
  272. FPopupMenu.Popup(X, Y);
  273. finally
  274. SwitchToWindow(FHandle, False);
  275. end;
  276. Result := True;
  277. end;
  278. end;
  279. end;
  280. end;
  281. constructor TCnTrayIcon.Create(AOwner: TComponent);
  282. var
  283. H: THandle;
  284. F: array[0..255] of Char;
  285. begin
  286. inherited;
  287. FHandle := AllocateHwnd(WndProc);
  288. FIcon := TIcon.Create;
  289. FIcon.OnChange := IconChanged;
  290. FActive := True;
  291. FEnabled := True;
  292. HookApp;
  293. H := LoadLibrary('Shell32.DLL');
  294. if (H <> 0) and (0 <> GetModuleFileName(H, F, SizeOf(F))) then
  295. FAcceptBalloons := GetFileVersionNumber(F).Major >= 5;
  296. end;
  297. procedure TCnTrayIcon.DblClick;
  298. begin
  299. if not CheckDefaultMenuItem and Assigned(FOnDblClick) then
  300. FOnDblClick(Self);
  301. end;
  302. procedure TCnTrayIcon.Deactivate;
  303. begin
  304. Shell_NotifyIconA(NIM_DELETE, @FIconData);
  305. FAdded := False;
  306. FClicked := [];
  307. end;
  308. destructor TCnTrayIcon.Destroy;
  309. begin
  310. Destroying;
  311. UnHookApp;
  312. FEnabled := False;
  313. FIcon.OnChange := nil;
  314. Deactivate;
  315. DeallocateHWnd(FHandle);
  316. FreeAndNil(FIcon);
  317. inherited;
  318. end;
  319. procedure TCnTrayIcon.DoClick(Button: TMouseButton; Shift: TShiftState; X,
  320. Y: Integer);
  321. begin
  322. if (Button <> mbRight) or not CheckMenuPopup(X, Y) then
  323. if Assigned(FOnClick) then
  324. FOnClick(Self, Button, Shift, X, Y);
  325. end;
  326. procedure TCnTrayIcon.HideIcon;
  327. begin
  328. Active := False;
  329. end;
  330. procedure TCnTrayIcon.HideApplication;
  331. begin
  332. if (Application.MainForm <> nil) and (Application.MainForm.WindowState <> wsMinimized) then
  333. begin
  334. FSaveWindowState := Application.MainForm.WindowState;
  335. Application.Minimize;
  336. Application.MainForm.Hide;
  337. end;
  338. ShowWindow(Application.Handle, SW_HIDE);
  339. end;
  340. procedure TCnTrayIcon.IconChanged(Sender: TObject);
  341. begin
  342. ChangeIcon;
  343. end;
  344. procedure TCnTrayIcon.Loaded;
  345. begin
  346. inherited;
  347. if FActive and not (csDesigning in ComponentState) then
  348. Activate;
  349. end;
  350. procedure TCnTrayIcon.MouseDown(Button: TMouseButton; Shift: TShiftState;
  351. X, Y: Integer);
  352. begin
  353. if Assigned(FOnMouseDown) then
  354. FOnMouseDown(Self, Button, Shift, X, Y);
  355. end;
  356. procedure TCnTrayIcon.MouseMove(Shift: TShiftState; X, Y: Integer);
  357. begin
  358. if Assigned(FOnMouseMove) then
  359. FOnMouseMove(Self, Shift, X, Y);
  360. end;
  361. procedure TCnTrayIcon.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
  362. Y: Integer);
  363. begin
  364. if Assigned(FOnMouseUp) then
  365. FOnMouseUp(Self, Button, Shift, X, Y);
  366. end;
  367. procedure TCnTrayIcon.Notification(AComponent: TComponent;
  368. Operation: TOperation);
  369. begin
  370. inherited;
  371. if (AComponent = FPopupMenu) and (Operation = opRemove) then
  372. PopupMenu := nil;
  373. end;
  374. procedure TCnTrayIcon.SendCancelMode;
  375. begin
  376. if not (csDestroying in ComponentState) then
  377. if Screen.ActiveCustomForm <> nil then
  378. if Application.MainForm <> nil then
  379. Application.MainForm.SendCancelMode(nil);
  380. end;
  381. procedure TCnTrayIcon.SetActive(Value: Boolean);
  382. begin
  383. if Value <> FActive then
  384. begin
  385. FActive := Value;
  386. if not (csDesigning in ComponentState) then
  387. begin
  388. if Value then
  389. Activate
  390. else
  391. Deactivate;
  392. end;
  393. end;
  394. end;
  395. procedure TCnTrayIcon.SetHint(const Value: string);
  396. begin
  397. if Value <> FHint then
  398. begin
  399. FHint := Value;
  400. ChangeIcon;
  401. end;
  402. end;
  403. procedure TCnTrayIcon.SetIcon(Value: TIcon);
  404. begin
  405. FIcon.Assign(Value);
  406. end;
  407. procedure TCnTrayIcon.SetPopupMenu(Value: TPopupMenu);
  408. begin
  409. FPopupMenu := Value;
  410. if Value <> nil then
  411. Value.FreeNotification(Self);
  412. end;
  413. procedure TCnTrayIcon.SetShowDesign(Value: Boolean);
  414. begin
  415. if csDesigning in ComponentState then
  416. begin
  417. if Value then
  418. Activate
  419. else
  420. Deactivate;
  421. FShowDesign := FAdded;
  422. end;
  423. end;
  424. procedure TCnTrayIcon.SetUseAppIcon(const Value: Boolean);
  425. begin
  426. FUseAppIcon := Value;
  427. if Value and (FIcon <> nil) then
  428. FIcon.Assign(Application.Icon);
  429. end;
  430. procedure TCnTrayIcon.ShowIcon;
  431. begin
  432. Active := True;
  433. end;
  434. procedure TCnTrayIcon.ShowApplication;
  435. begin
  436. ShowWindow(Application.Handle, SW_SHOW);
  437. Application.Restore;
  438. if Application.MainForm <> nil then
  439. begin
  440. if FSaveWindowState <> wsMinimized then
  441. Application.MainForm.WindowState := FSaveWindowState
  442. else
  443. Application.MainForm.WindowState := wsNormal;
  444. Application.BringToFront;
  445. Application.MainForm.Show;
  446. end;
  447. end;
  448. procedure TCnTrayIcon.UpdateNotifyData;
  449. var
  450. ShortHint: AnsiString;
  451. begin
  452. FIconData.cbSize := SizeOf(TNotifyIconData);
  453. FIconData.Wnd := FHandle;
  454. FIconData.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP or NIF_INFO;
  455. FIconData.hIcon := FIcon.Handle;
  456. ShortHint := {$IFDEF UNICODE}AnsiString{$ENDIF}(GetShortHint(FHint));
  457. {$IFDEF UNICODE}
  458. if ShortHint <> '' then
  459. CopyMemory(@FIconData.szTip, Pointer(ShortHint), 63)
  460. else
  461. FIconData.szTip[0] := #0;
  462. {$ELSE}
  463. StrPLCopy(FIconData.szTip, ShortHint, 63);
  464. {$ENDIF}
  465. FIconData.uCallbackMessage := WM_CNTRAYICONCALLBACK;
  466. FIconData.uID := 0;
  467. end;
  468. procedure TCnTrayIcon.WndProc(var Message: TMessage);
  469. function GetShiftState: TShiftState;
  470. begin
  471. Result := [];
  472. if GetKeyState(VK_SHIFT) < 0 then
  473. Include(Result, ssShift);
  474. if GetKeyState(VK_CONTROL) < 0 then
  475. Include(Result, ssCtrl);
  476. if GetKeyState(VK_MENU) < 0 then
  477. Include(Result, ssAlt);
  478. end;
  479. var
  480. P: TPoint;
  481. Shift: TShiftState;
  482. begin
  483. try
  484. if Message.Msg = WM_CNTRAYICONCALLBACK then
  485. begin
  486. if FEnabled then
  487. begin
  488. Shift := GetShiftState;
  489. case Message.lParam of
  490. WM_LBUTTONDBLCLK:
  491. begin
  492. DblClick;
  493. GetCursorPos(P);
  494. MouseDown(mbLeft, Shift, P.x, P.y);
  495. end;
  496. WM_RBUTTONDBLCLK:
  497. begin
  498. DblClick;
  499. GetCursorPos(P);
  500. MouseDown(mbRight, Shift, P.x, P.y);
  501. end;
  502. WM_MBUTTONDBLCLK:
  503. begin
  504. DblClick;
  505. GetCursorPos(P);
  506. MouseDown(mbMiddle, Shift, P.x, P.y);
  507. end;
  508. WM_MOUSEMOVE:
  509. begin
  510. GetCursorPos(P);
  511. MouseMove(Shift, P.X, P.Y);
  512. end;
  513. WM_LBUTTONDOWN:
  514. begin
  515. GetCursorPos(P);
  516. MouseDown(mbLeft, Shift, P.X, P.Y);
  517. Include(FClicked, mbLeft);
  518. end;
  519. WM_LBUTTONUP:
  520. begin
  521. GetCursorPos(P);
  522. if mbLeft in FClicked then
  523. begin
  524. Exclude(FClicked, mbLeft);
  525. DoClick(mbLeft, Shift, P.x, P.y);
  526. end;
  527. MouseUp(mbLeft, Shift, P.x, P.y);
  528. end;
  529. WM_RBUTTONDOWN:
  530. begin
  531. GetCursorPos(P);
  532. MouseDown(mbRight, Shift, P.x, P.y);
  533. Include(FClicked, mbRight);
  534. end;
  535. WM_RBUTTONUP:
  536. begin
  537. GetCursorPos(P);
  538. if mbRight in FClicked then
  539. begin
  540. Exclude(FClicked, mbRight);
  541. DoClick(mbRight, Shift, P.x, P.y);
  542. end;
  543. MouseUp(mbRight, Shift, P.X, P.Y);
  544. end;
  545. WM_MBUTTONDOWN:
  546. begin
  547. GetCursorPos(P);
  548. MouseDown(mbMiddle, Shift, P.X, P.Y);
  549. Include(FClicked, mbMiddle);
  550. end;
  551. WM_MBUTTONUP:
  552. begin
  553. GetCursorPos(P);
  554. if mbMiddle in FClicked then
  555. begin
  556. Exclude(FClicked, mbMiddle);
  557. DoClick(mbMiddle, Shift, P.x, P.y);
  558. end;
  559. MouseUp(mbMiddle, Shift, P.X, P.Y);
  560. end;
  561. NIN_BALLOONSHOW:
  562. begin
  563. end;
  564. NIN_BALLOONHIDE:
  565. begin
  566. end;
  567. NIN_BALLOONTIMEOUT:
  568. begin
  569. end;
  570. NIN_BALLOONUSERCLICK:
  571. begin
  572. end;
  573. end; // end of case
  574. end;
  575. end
  576. else if Message.Msg = WM_CNCREATETASKBAR then
  577. begin
  578. if not (csDesigning in ComponentState) and FActive then
  579. Activate;
  580. end
  581. else with Message do
  582. Result := DefWindowProc(FHandle, Msg, wParam, lParam);
  583. except
  584. Application.HandleException(Self);
  585. end;
  586. end;
  587. procedure TCnTrayIcon.HookApp;
  588. begin
  589. if FHooked then
  590. Exit;
  591. Application.HookMainWindow(ApplicationHook);
  592. FHooked := True;
  593. end;
  594. procedure TCnTrayIcon.UnHookApp;
  595. begin
  596. if not FHooked then
  597. Exit;
  598. Application.UnhookMainWindow(ApplicationHook);
  599. FHooked := False;
  600. end;
  601. function TCnTrayIcon.ApplicationHook(var Msg: TMessage): Boolean;
  602. begin
  603. if (Msg.Msg = WM_SYSCOMMAND) and (Msg.WParam = SC_MINIMIZE) and
  604. FAutoHide and FActive then
  605. if not (csDesigning in ComponentState) then
  606. HideApplication;
  607. Result := False;
  608. end;
  609. procedure TCnTrayIcon.GetComponentInfo(var AName, Author, Email,
  610. Comment: string);
  611. begin
  612. AName := SCnTrayIconName;
  613. Author := SCnPack_LiuXiao;
  614. Email := SCnPack_LiuXiaoEmail;
  615. Comment := SCnTrayIconComment;
  616. end;
  617. initialization
  618. WM_CNCREATETASKBAR := RegisterWindowMessage(PChar(SCnCreateTaskBar));
  619. WM_CNTRAYICONCALLBACK := RegisterWindowMessage(PChar(SCnTrayIcon));
  620. end.