Avatar billede speedy Nybegynder
23. november 2001 - 21:08 Der er 15 kommentarer og
2 løsninger

Balloon tips fra Windows XP

Hej

I kender sikkert de der balloner i Windows XP som popper op f.eks. nede i systray\'en hvis netværksstikket bliver taget ud, eller hvis CAPS-LOCK er slået til når man skal indtaste passwords.

Jeg synes personligt de er ret fede sådan nogle hints, så jeg ville jo gerne bruge dem i mit eget program. Derfor tænkte jeg på om i ikke vidste hvordan man kunne implementere sådanne hints.

/SpEeDy
Avatar billede martinlind Nybegynder
23. november 2001 - 21:15 #1
Du skal lave din egen THintwindow class og så bare bruge den, kig på hjælpen under THintWindow
Avatar billede speedy Nybegynder
23. november 2001 - 21:33 #2
lave min egen ? Når gør det jeg tror du mener får jeg jo bare sådan et rigtig grimt gult \"old-style\" hint

Jeg vil jo gerne have den der ballon-type

/SpEeDy
Avatar billede dkn Nybegynder
23. november 2001 - 21:57 #3
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.
Avatar billede martinlind Nybegynder
23. november 2001 - 22:14 #4
Når du laver dit eget kan du lave det som du har lyst til !
Avatar billede speedy Nybegynder
23. november 2001 - 22:28 #5
martinlind>>Jamen jeg vil jo som sagt gerne have den der ballon som Windows laver...den kan jeg da ikke selv gengive ved selv at tegne den ?
/SpEeDy
Avatar billede speedy Nybegynder
23. november 2001 - 22:37 #6
dkn>>Jeg har prøvet den du har skrevet der fra delphi3000.com men har ikke fået den til at virke :(

Og desuden...den der bliver skrevet om i dit eksempel vil den ikke poppe frem nede i systray ?

Jeg vil kunne placere den på min form hvor jeg vil...

/SpEeDy
Avatar billede dkn Nybegynder
24. november 2001 - 00:18 #7
jo den kommer frem i systray, men jeg trode det var det du ville.

Hvis du skal bruge een i din form, må du selv tene den. Du kunne evt. lave et billede og bruge en Timage på din form, og sætte formen til bsclear.

Det er den eneste løsning vil jeg tro :|
Avatar billede speedy Nybegynder
24. november 2001 - 13:47 #8
dkn>>Jamen det kan da ikke passe at man ikke kan bruge hintet på sin form...Det gør Windows da hvis du indtaster password med CAPS-LOCK nede ?

Men jeg kigger lige lidt på det eksempel du gav, om man ikke selv kan placere hintet hvor man vil.

/SpEeDy
Avatar billede martinlind Nybegynder
24. november 2001 - 15:03 #9
Du kan da tegne det du har lyst til, kan du ikke stjæle en screen capture at den ballon og se hvordan dan de tegner den, det skulle nok kunne lade sig gøre, du kan gemme din capture og forstøre det i et tegne program, så kan man tydeligt se hvordan den er tegnet.
Avatar billede speedy Nybegynder
24. november 2001 - 15:37 #10
martinlind>>Jo det kunne man godt, men jeg synes bare det er lidt en \"lappeløsning\". F.eks. har den ikke skygge, og hvad med transparente områder ?

Jeg har set et program som benytter sig af det, og det hedder PowerCalculator og er med i tweakXP pakken

/SpEeDy
Avatar billede stoney Nybegynder
24. november 2001 - 16:02 #11
Avatar billede martinlind Nybegynder
24. november 2001 - 20:11 #12
Jamen det bliver lige nøjagtigt så godt som DU laver det ! laver du det med skygger har du skyggger osv.

/Martin
Avatar billede speedy Nybegynder
24. november 2001 - 21:21 #13
martinlind>>For mig lyder det som om du ikke har set WindowsXP ballon hints eller skygger for den sags skyld.
Skyggerne er semi-transparente med det der er bagved, og jeg har ingen anelse om hvordan jeg skulle kunne tegne det selv.

Men jeg har fået det til at virke som dkn skrev.

Den virker som sagt dog kun nede i sys-trayen, men det kan jeg godt leve med så.

Tak for hjælpen begge 2

til stoney>>Sorry, det er ikke det jeg leder efter.

/SpEeDy
Avatar billede speedy Nybegynder
24. november 2001 - 21:28 #14
martinlind>>Og jeg kan egentlig ikke se nogen grund til selv at tegne den når Windows tilbyder at gøre det for mig...

/SpEeDy
Avatar billede martinlind Nybegynder
24. november 2001 - 23:17 #15
Fordi du vil ha\' det andre steder en i sys-trayen :)

/Martin
Avatar billede dkn Nybegynder
25. november 2001 - 00:33 #16
Det var så lidt :)
Avatar billede speedy Nybegynder
25. november 2001 - 17:02 #17
jamen Martin dog :)

Windows vil sikkert gerne hjælpe mig med at tegne den andre steder, men jeg ved bare ikke hvordan :)

/SpEeDy
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester