unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ShellApi, extctrls, ImgList , CommCtrl;

type
   TTrayInfo = record
    TrayIcon: TImage;
    Wnd: HWND;
    uID: UINT;
    uCallBack: UINT;
   end;

  TForm1 = class(TForm)
    Button1: TButton;
    ImageList1: TImageList;
    PsTray: TPanel;
    procedure CreateParams(var Params: TCreateParams); override;
    procedure FormCreate(Sender: TObject);
    procedure TrayProcDblClick(Sender: TObject);
    procedure TrayProcMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure TrayProcMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure NewTrayIcon(NID: PNotifyIconData);
    procedure Button1Click(Sender: TObject);
  private
    procedure WMCOPYDATA(var Msg: Tmessage); message WM_COPYDATA;
    //procedure DeleteTrayIcon(NID: PNotifyIconData);
    //procedure ModifyTrayIcon(NID: PNotifyIconData);
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  TrayInfo: array of TTrayInfo;

implementation

{$R *.DFM}

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
 inherited CreateParams(Params);
 Params.WinClassName := 'Shell_TrayWnd';
end;

procedure TForm1.FormCreate(Sender: TObject);
var
 WM_TASKBARCREATED: UINT;
begin

Form1.Width := Screen.Width ;
Form1.Left := 0;
Form1.top := trunc(Screen.Height/2 - Form1.Height/2 );
psTray.Width := Form1.Width - button1.Width -10;

 WM_TASKBARCREATED := RegisterWindowMessage('TaskbarCreated');
 PostMessage(HWND_BROADCAST, WM_TASKBARCREATED, 0, 0);
end;

procedure TFORM1.WMCOPYDATA(var Msg: Tmessage);
var
pcd: PCopyDataStruct;
NID: PNotifyIconData;
begin
 pcd := PCOPYDATASTRUCT(msg.lParam);
   case pcd^.dwData of
    1:
    begin
     case integer(pointer(integer(pcd.lpData)+4)^) of
        NIM_ADD: begin
                 nid := pointer(integer(pcd.lpData)+8);

                Msg.Result := longint(true);
                NewTrayIcon(nid);
                 end;
{        NIM_DELETE: begin
                    nid := pointer(integer(pcd.lpData)+8);
                Msg.Result := longint(true);
                    DeleteTrayIcon(nid);
                    end;
        NIM_MODIFY: begin
                    nid := pointer(integer(pcd.lpData)+8);
                Msg.Result := longint(true);
                    ModifyTrayIcon(nid);
                    end;}
     end;
     exit;
    end;
   end;
end;

procedure TFORM1.NewTrayIcon(NID: PNotifyIconData);
var
ind: integer;
BtIcon: TBitmap;
begin

if nid.Wnd=0 then exit;

ind:=Length(TrayInfo);
//SetLength(TrayIcon,ind+1);
SetLength(TrayInfo,ind+1);

TrayInfo[ind].TrayIcon := TImage.Create(Form1);
TrayInfo[ind].TrayIcon.parent := Form1.PsTray;
TrayInfo[ind].TrayIcon.Height := 16;
TrayInfo[ind].TrayIcon.Width := 16;
TrayInfo[ind].TrayIcon.AutoSize := false;
TrayInfo[ind].TrayIcon.Stretch := true;
TrayInfo[ind].TrayIcon.Transparent := true;
TrayInfo[ind].TrayIcon.Visible := true;

  BtIcon := TBitmap.Create;
  ImageList1.BkColor := Form1.Color;
  ImageList_ReplaceIcon(imagelist1.handle,0, nid.hIcon);
  ImageList1.GetBitmap(0, BtIcon);
  TrayInfo[ind].TrayIcon.Picture.Bitmap := BtIcon  ;
  bticon.free;

TrayInfo[ind].TrayIcon.Top := 5;
TrayInfo[ind].TrayIcon.Left := 26+(ind*20);
TrayInfo[ind].TrayIcon.ShowHint := true;
TrayInfo[ind].TrayIcon.Hint := StrPas(nid.szTip);
TrayInfo[ind].TrayIcon.Tag := ind;
TrayInfo[ind].TrayIcon.OnMouseDown := TrayProcMouseDown;
TrayInfo[ind].TrayIcon.OnMouseUp := TrayProcMouseUp;
TrayInfo[ind].TrayIcon.OnDblClick := TrayProcDblClick;

trayInfo[ind].Wnd := nid.Wnd ;
trayInfo[ind].uID := nid.uID ;
trayInfo[ind].uCallBack := nid.uCallbackMessage ;

end;


procedure TForm1.TrayProcDblClick(Sender: TObject);
var
ind: integer;
begin
ind:= (Sender as TImage).tag;

PostMessage(TrayInfo[ind].Wnd, trayInfo[ind].uCallBack,
               trayInfo[ind].uID, WM_LBUTTONDBLCLK);
end;

procedure TForm1.TrayProcMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
ind: integer;
begin
ind:= (Sender as TImage).tag;

 Case Button of
 mbLeft: PostMessage(TrayInfo[ind].Wnd, trayInfo[ind].uCallBack,
                  trayInfo[ind].uID, WM_LBUTTONDOWN);
 mbRight: PostMessage(TrayInfo[ind].Wnd, trayInfo[ind].uCallBack,
                  trayInfo[ind].uID, WM_RBUTTONDOWN);
 mbMiddle: PostMessage(TrayInfo[ind].Wnd, trayInfo[ind].uCallBack,
                  trayInfo[ind].uID, WM_MBUTTONDOWN);
 End;
end;

procedure TForm1.TrayProcMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
ind: integer;
begin
ind:= (Sender as TImage).tag;
 Case Button of
 mbLeft: PostMessage(TrayInfo[ind].Wnd, trayInfo[ind].uCallBack,
            trayInfo[ind].uID, WM_LBUTTONUP);

 mbRight: PostMessage(TrayInfo[ind].Wnd, trayInfo[ind].uCallBack,
            trayInfo[ind].uID, WM_RBUTTONUP);

 mbMiddle: PostMessage(TrayInfo[ind].Wnd, trayInfo[ind].uCallBack,
            trayInfo[ind].uID, WM_MBUTTONUP);
 end;
end;



procedure TForm1.Button1Click(Sender: TObject);
begin
ShellExecute(Handle,'open',pchar('explorer.exe'),pchar('') ,pchar(''),SW_SHOWNORMAL);

end;

end.
