Mega Code Archive

 
Categories / Delphi / Graphic
 

How to use those Balloon style hints with Tray icons in Win2K

Title: How to use those Balloon-style hints with Tray icons in Win2K Question: Ever seen Win2K pop balloons over tray icons? When connecting through the Dial-Up Networking, for example... Windows pops a balloon over the connection icon that states speed and connection type. This is how to produce those cool balloons in your code. Answer: Please note: The author assumes you are familiar with simple operations of inserting and removing your icons to / from the "Tray". If you are not, I suggest studying either, or both, of the following: 1. How to create a TrayIcon ! (ID 1567) by Bernhard Angerer 2. In the end of this article, I provide my own functions for these tasks. Now, back to the balloons. I found out that the format of the NotifyIconData structure used to operate icons in the Tray (which, by the way, is called by Microsoft "The Taskbar Notification Area" :) changed significantly in Windows 2000. Those changes are NOT reflected in ShellAPI.pas unit of Delphi 5. Therefore I got the original SHELLAPI.H and translated the required declarations. Here they are: uses Windows; type NotifyIconData_50 = record // defined in shellapi.h cbSize: DWORD; Wnd: HWND; uID: UINT; uFlags: UINT; uCallbackMessage: UINT; hIcon: HICON; szTip: array[0..MAXCHAR] of AnsiChar; dwState: DWORD; dwStateMask: DWORD; szInfo: array[0..MAXBYTE] of AnsiChar; uTimeout: UINT; // union with uVersion: UINT; szInfoTitle: array[0..63] of AnsiChar; dwInfoFlags: DWORD; end{record}; const NIF_INFO = $00000010; NIIF_NONE = $00000000; NIIF_INFO = $00000001; NIIF_WARNING = $00000002; NIIF_ERROR = $00000003; Here is a couple of types I think to be helpful: type TBalloonTimeout = 10..30{seconds}; TBalloonIconType = (bitNone, // no icon bitInfo, // information icon (blue) bitWarning, // exclamation icon (yellow) bitError); // error icon (red) Now we're ready to BALLOON! This is the function I use: uses SysUtils, Windows, ShellAPI; function DZBalloonTrayIcon(const Window: HWND; const IconID: Byte; const Timeout: TBalloonTimeout; const BalloonText, BalloonTitle: String; const BalloonIconType: TBalloonIconType): Boolean; const aBalloonIconTypes : array[TBalloonIconType] of Byte = (NIIF_NONE, NIIF_INFO, NIIF_WARNING, NIIF_ERROR); var NID_50 : NotifyIconData_50; begin FillChar(NID_50, SizeOf(NotifyIconData_50), 0); with NID_50 do begin cbSize := SizeOf(NotifyIconData_50); Wnd := Window; uID := IconID; uFlags := NIF_INFO; StrPCopy(szInfo, BalloonText); uTimeout := Timeout * 1000; StrPCopy(szInfoTitle, BalloonTitle); dwInfoFlags := aBalloonIconTypes[BalloonIconType]; end{with}; Result := Shell_NotifyIcon(NIM_MODIFY, @NID_50); end; And this is how to employ it: DZBalloonTrayIcon(Form1.Handle, 1, 10, 'this is the balloon text', 'title', bitWarning); The icon has to be already added, of course, with the same window handle and IconID (in this example, Form1.Handle and 1). Try all three types of the inside-the-balloon-icons, they are cool! ======THE END OF THE BALLOON ARTICLE====== P.S. Now the functions I promised for adding/removing tray icons: uses SysUtils, Windows, ShellAPI; {just adds an icon} function DZAddTrayIcon(const Window: HWND; const IconID: Byte; const Icon: HICON; const Hint: String = ''): Boolean; var NID : NotifyIconData; begin FillChar(NID, SizeOf(NotifyIconData), 0); with NID do begin cbSize := SizeOf(NotifyIconData); Wnd := Window; uID := IconID; if Hint = '' then begin uFlags := NIF_ICON; end{if} else begin uFlags := NIF_ICON or NIF_TIP; StrPCopy(szTip, Hint); end{else}; hIcon := Icon; end{with}; Result := Shell_NotifyIcon(NIM_ADD, @NID); end; {adds an icon with a call-back message} function DZAddTrayIconMsg(const Window: HWND; const IconID: Byte; const Icon: HICON; const Msg: Cardinal; const Hint: String = ''): Boolean; var NID : NotifyIconData; begin FillChar(NID, SizeOf(NotifyIconData), 0); with NID do begin cbSize := SizeOf(NotifyIconData); Wnd := Window; uID := IconID; if Hint = '' then begin uFlags := NIF_ICON or NIF_MESSAGE; end{if} else begin uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP; StrPCopy(szTip, Hint); end{else}; uCallbackMessage := Msg; hIcon := Icon; end{with}; Result := Shell_NotifyIcon(NIM_ADD, @NID); end; {removes an icon} function DZRemoveTrayIcon(const Window: HWND; const IconID: Byte): Boolean; var NID : NotifyIconData; begin FillChar(NID, SizeOf(NotifyIconData), 0); with NID do begin cbSize := SizeOf(NotifyIconData); Wnd := Window; uID := IconID; end{with}; Result := Shell_NotifyIcon(NIM_DELETE, @NID); end; A few final notes: 1. There's absolutely no need to use the larger ver.5.0 structure NotifyIconData_50 to add or remove icons, the old smaller structure NotifyIconData is perfect for that, even if you want to balloon them. 2. For the callback message, I suggest using WM_APP + something. 3. Using different IconIDs, it is easy to add many different icons to tray from a single parent window and operate them by their IconIDs.