精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● Delphi>>Windows API函数>>任务栏>>How to use those Balloon-style hints with Tray icons in Win2K

主题:How to use those Balloon-style hints with Tray icons in Win2K
发信人: xmzw()
整理人: teleme(2001-03-24 00:51:52), 站内信件
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.

[关闭][返回]