jeg bad egentlig bare om et par linjers kode, plus en forklaring hvorfor de virker, ikke et component
Hej,
Når du skal ha' et ikon ned i taskbar'en skal du bruge shell'en.
Du kommunikere med taskbaren vha. "Shell_NotifyIcon" funktionen samt en "callback message".
Du har 3 forskellige metoder til rådighed via. Shell_NotifyIcon:
NIM_ADD, NIM_DELETE og NIM_MODIFY.
Hver af disse metoder kan opertte/slette/opdatere både ikon og tooltip.
For at sende disse informationer/kommandoer skal du også bruge strukturen "TNotifyIconData".
Denne struktur indeholder alle informationer omkring callback, ikon, tooltip osv.
Jeg har skrevet et stykke kode som viser hvordan du selv kan opdatere et trayicon.
Det er skrevet direkte ind her, så der kan være fejl forskellige steder men du burde
få et nogenlunde overblik/idé om hvordan det kan gøres. Alt funktionaliteten som taskbaren
stiller til rådighed er ikke med da det ville være alt for stort et område at gennemgå lige nu.
Koden er en klasse som kan oprette/slette og opdatere et trayicon samt sætte tooltip og få
beskeder når brugeren trykker med musen på ikonet.
unit tray;
uses
Windows, Messages, ShellAPI;
const
WM_TRAY_NOTIFY = WM_USER+1; // callback beskeden som vi vil bruge.
type
TWM_TrayMessage = Record // Windows message from the tray...
Msg: Cardinal; // Beskeden fra Trayet.
Id : Integer; // Id på den ikon som har genereret beskeden.
WM_Value : Integer; // WM beskeden som er genereret af ikonet.
Result : Integer; // resultatet.
end;
// typer til håndtering af mouse events fra taskbaren.
TTIMouse = (msLeftClick,msRightClick,msLeftDoubleClick,msRightDoubleClick);
TTIOnMouseDown = procedure (Sender : TObject; Mouse : TTIMouse;
MousePos : TPoint) of object;
TTray = class(TObject)
private
FTip : String;
FTray : TNotifyIconData;
FWND : HWND;
FIconHandle : HICON;
FAttached : Boolean;
FOnEvent : TTIOnMouseDown;
protected
procedure Update;
procedure Detach;
procedure Attach;
procedure RaiseEvent(aMouse : TTIMouse; aMousePos : TPoint);
// "Set" funktioner til nedenstående properties.
procedure SetTip(aTip : String);
procedure SetOwner(aOwner : HWND);
procedure SetIcon(aIcon : HICON);
procedure SetActive(aActive : Boolea);
public
constructor Create;
destructor Destroy;
function IsIconMessage(aMessage : TMessage) : Boolean;
property Tip : String read FTip write SetTip;
property Owner : HWND read FWND write SetOwner;
property Icon : HICON read FIconHandle write SetIcon;
property Active : Boolean read FAttached write SetActive;
property OnEvent : TTIOnMouseDown read FOnEvent write FOnEvent;
end;
implementation
uses
SysUtils;
(***********************************************
initialisere data i vores klasse.
***********************************************)
constructor TTray.Create;
begin
FTip := '';
FillChar(FTray, SizeOf(TNotifyIconData), 0);
FWND := 0;
FIconHandle := 0;
FAttached := False;
FOnEvent := nil;
end;
(***********************************************
Ryd op i klassen og afmeld os fra taskbaren hvis det er
nødvendigt.
***********************************************)
destructor TTray.Destroy;
begin
FOnEvent := nil;
Detach; // husk altid at fjerne ikonet fra taskbaren når der afsluttes.
inherited Destroy;
end;
(***********************************************
Sender ikon, tooltip og callback til taskbaren.
Denne funktion bruges kun når der skal oprettes en ikon
i taskbaren (brug "update" hvis vi allerede har oprettet
ikonen).
***********************************************)
procedure TTray.Attach;
begin
if (FAttached = False) then
begin
FTray.cbSize := SizeOf(TNotifyIconData);
FTray.wnd := FWND; // callback vindue
FTray.uID := 1; // id på ikonen (altid 1, med mindre der skal være flere ikoner).
FTray.uCallBackMessage := WM_TRAY_NOTIFY; // vores callback besked.
FTray.hIcon := FIconHandle; // handle på ikonet som skal vises.
StrLCopy(FTray.szTip, PChar(FTip),63); // kopiere tooltip
FTray.uFlags := nif_Message or nif_Icon or nif_Tip; // sæt hvilke ting vi vil oprette.
// Send besked til Taskbaren.
Shell_NotifyIcon (NIM_ADD, @FTray);
FAttached := True;
end;
end;
(***********************************************
Fjerner ikonet fra taskbaren samt alt notifikation.
***********************************************)
procedure TTray.Detach;
begin
if (FAttached) then
begin
FTray.cbSize := SizeOf(TNotifyIconData);
FTray.wnd := FWND;
FTray.uID := 1;
FTray.uFlags := 0;
// Send besked til Taskbaren.
Shell_NotifyIcon (NIM_DELETE, @FTray);
FAttached := False;
end;
end;
(***********************************************
Opdatere ændringer fortaget via properties.
Disse er:
- Tooltip
- Callback
- Ikon
***********************************************)
procedure TTray.Update;
begin
if (FAttached) then
begin
FTray.cbSize := SizeOf(TNotifyIconData);
FTray.wnd := FWND;
FTray.uID := 1;
FTray.uCallBackMessage := WM_TRAY_NOTIFY;
FTray.hIcon := FIconHandle;
StrLCopy(FTray.szTip, PChar(FTip),63);
FTray.uFlags := nif_Message or nif_Icon or nif_Tip;
Shell_NotifyIcon (NIM_MODIFY, @FTray);
end;
end;
(***********************************************
Sæt tooltip og opdatere taskbaren, hvis vi er aktiv.
***********************************************)
procedure TTray.SetTip(aTip : String);
begin
if (aTip <> FTip) then
begin
FTip := aTip;
if (FAttached) then
Update; // Update trayicon med vores nye tooltip.
end;
end;
(***********************************************
Sæt callback og opdatere taskbaren, hvis vi er aktiv.
***********************************************)
procedure TTray.SetOwner(aOwner : HWND);
begin
if (aOwner <> FWND) then
begin
FWND := aOwner;
if (FAttached) then
Update; // Update trayicon med vores nye callback.
end;
end;
(***********************************************
Sæt ikon og opdatere taskbaren, hvis vi er aktiv.
***********************************************)
procedure TTray.SetIcon(aIcon : HICON);
begin
if (aIcon <> FIconHandle) then
begin
FIconHandle := aIcon;
if (FAttached) then
Update; // Update trayicon med vores nye ikon.
end;
end;
(***********************************************
Tilmeld aller afmeld os til/fra taskbaren.
***********************************************)
procedure TTray.SetActive(aActive : Boolea);
begin
if (aActive) then
Attach
else
Detach;
end;
(***********************************************
Sender eventet til brugeren.
***********************************************)
procedure TTray.RaiseEvent(aMouse : TTIMouse; aMousePos : TPoint);
begin
if Assigned(FOnClick) then
begin
try
FOnClick(Self, aMouse, aMousePos);
except
end;
end;
end;
(***********************************************
Skal kaldes fra brugerens WndProc eller i en
event-procedure. Hvis beskeden tilhører os så rejs et
event til brugeren som angiver hvad der er sket.
***********************************************)
function TTray.IsIconMessage(aMessage : TMessage) : Boolean;
var
L : TPoint;
begin
GetCursorPos(L); // hent musens position.
Result := (aMessage.Msg = WM_TRAY_NOTIFY); // se om det er en besked til os.
if (Result) then
begin // der er det, så analyser beskeden og rejs det tilsvarende event.
case Msg.Command of
WM_RButtonDown:
RaiseEvent(msRightClick, L);
WM_RButtonDblClk:
RaiseEvent(msRightDoubleClick, L);
WM_LButtonDown:
RaiseEvent(msLeftClick, L);
WM_LButtonDblClk:
RaiseEvent(msLeftDoubleClick, L);
else
Result := False;
end;
end;
end;
end.
For at bruge klasse kan du gøre følgende:
// HUSK at tilføje "tray" til din uses.
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FTray : TTray;
protected
procedure OnTray(Sender : TObject; Mouse : TTIMouse; MousePos : TPoint);
public
procedure WndProc(var Message : TMessage); override;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FTray := TTray.Create;
FTray.Tip := 'Udvikleren support';
FTray.Owner := Handle; // så får vi beskederne fra taskbaren.
FTray.OnEvent := OnTray;
FTray.Icon := LoadIcon(HInstance, 'MAINICON'); // brug din apps. default ikon.
FTray.Active := True;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FTray.Free;
end;
procedure TForm1.OnTray(Sender : TObject; Mouse : TTIMouse; MousePos : TPoint);
begin
ShowMessage('Mouseevent at ('+inttostr(Mousepos.x)+', '+inttostr(mousepos.y)+')');
end;
procedure TForm1.WndProc(var Message : TMessage);
begin
if (FTray <> nil) then
begin
if (FTray.Active) then
if (FTray.IsIconMessage(Message)) then
Exit;
end;
inherited WndProc(Message);
end;
Jeg håber det giver dig en lidt størrer indsigt i hvordan det skal gøres.
mvh
Michael.