如题??

解决方案 »

  1.   

    这几天问托盘程序的人似乎很多啊
    搜索一下吧,以前的很多
    http://expert.csdn.net/Expert/topic/1853/1853515.xml?temp=.6273462
      

  2.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, Menus,shellapi;
    const
      wm_trayicon=wm_app+0;type
      TForm1 = class(TForm)
        PopupMenu1: TPopupMenu;
        N1: TMenuItem;
        N2: TMenuItem;
        procedure FormDestroy(Sender: TObject);
        procedure N1Click(Sender: TObject);
        procedure N2Click(Sender: TObject);
        procedure FormShow(Sender: TObject);
      private
        { Private declarations }
        procedure wmtrayicon(var message:tmessage); message wm_trayicon;
        Procedure WMSysCommand(Var msg : TMessage);Message WM_SYSCOMMAND;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation
    {$R *.dfm}
    procedure modifytrayicon(action:dword);
    var
      nidata:tnotifyicondata;
    begin
      with nidata do begin
       cbsize:=sizeof(tnotifyicondata);
       uid:=0;
       uflags:=NIF_MESSAGE or NIF_ICON or NIF_TIP;
       wnd:=Form1.handle;
       ucallbackmessage:=wm_trayicon;
       hicon:=application.Icon.Handle ;
       strpcopy(sztip,application.Title );
      end;
      shell_notifyicon(action,@nidata);
    end;procedure TForm1.wmtrayicon(var message:tmessage);
    var
      mousepos:tpoint;
    begin
      case message.lParam of
        //左键按下
        WM_LBUTTONDOWN : begin
                           application.MainForm.BringToFront;   //窗体置前
                         end;
        //左键双击
        WM_LBUTTONDBLCLK : begin                                //窗体隐含或显示
                             Application.MainForm.Visible := not Application.MainForm.Visible;
                             SetForegroundWindow(Application.Handle);
                           end;
        //右键按下
        WM_RBUTTONDOWN :   begin                                //显示弹出菜单
                             setactivewindow(handle);
                             getcursorpos(mousepos);
                             popupmenu1.Popup(mousepos.X,mousepos.Y);
                           end;
       end//case
    end;procedure Tform1.WMSysCommand(var msg: TMessage);
    begin
      case Msg.WParam of
        SC_MINIMIZE: begin
                       msg.WParam:=0;
                       modifytrayicon(nim_add);
                       Application.MainForm.Visible:=false;
                     end;
        SC_CLOSE    :begin
                       msg.WParam :=0;
                       modifytrayicon(nim_add);
                       Application.MainForm.Visible:=false;
                     end;
      end;
      Inherited;
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
      modifytrayicon(nim_delete);       //删除托盘
    end;procedure TForm1.N1Click(Sender: TObject);
    begin
      Application.MainForm.Visible :=true;
    end;procedure TForm1.N2Click(Sender: TObject);
    begin
      close;
    end;procedure TForm1.FormShow(Sender: TObject);
    begin
      modifytrayicon(nim_delete);
    end;end.
      

  3.   

    希望对你有帮助:  在开始之前,请看下面的需要的接口方面的内容:   从技术方面来说,一个任务栏应用程序非常象普通的应用程序,它有一个消息循环,相应Windows的消息来完成相应的功能。 Procedure RunTrayApplication;
    Var Msg : TMsg;
    Begin
     CreateWindow;
     AddTrayIcon;
     While GetMessage(Msg,0,0,0) do Begin
      TranslateMessage(Msg);
      DispatchMessage(Msg);
     End;
     DeleteTrayIcon;
    End;
      你能看到:所有需要做的工作是创建一个窗口,注册一个图标到任务栏,设置它的消息循环,最后关闭它。当然,必须还有增加其他代码完成相应的功能,但是,它是真的不需要担心。 
      让我们从窗口的创建开始。实际上,这个窗口是不是能在任务栏上能见到的窗口。相应的,这个窗口只是处理消息循环、其它父类的工作。任务窗口(Windows 95 & NT)句柄创建消息(例如鼠标单击等)和将消息发到我们的窗口。 Procedure CreateWindow;
    Var
     WC : TWndClass;
     W : hWnd;
    Begin
     With WC do Begin
      Style := 0;
      lpfnWndProc := @WndProc;
      cbClsExtra := 0;
      cbWndExtra := 0;
      hIcon := 0;
      hCursor := 0;
      hbrBackground := 0;
      lpszMenuName := nil;
      lpszClassName := 'MyTrayIconClass';
      hInstance := System.hInstance;
     end;
     RegisterClass(WC);
     W := Windows.CreateWindow('MyTrayIconClass','MyVeryOwnTrayIconWindow',
                  ws_OverlappedWindow,0,0,0,0,0,0,hInstance,nil);
     ShowWindow(W,sw_Hide);
     UpdateWindow(W);
     MainWindow := W;
    End;
      这个窗口使用普通的窗口函数创建。注意这个窗口的类型是“ws_OverlappedWindow”,但是这个尺寸是0,并且它是隐藏的,所有,它将不会显示出来。 
      下一步是加(注册)我们的图标。这将需要使用Shell_NotifyIcon这个API函数,这个函数实际上可以完成三个功能,这里只需要它的增加的特性。 Procedure AddTrayIcon;
    Var IconData : TNotifyIconData;
    Begin
     With IconData do Begin
      cbSize := SizeOf(IconData);
      Wnd := MainWindow;
      uID := 0;
      uFlags := nif_Icon Or nif_Message Or nif_Tip;
      uCallBackMessage := wm_MyCallBack;
      hIcon := LoadIcon(hInstance,'MYICON');
      StrCopy(szTip,PChar(TrayIconTip));
     End;
     Shell_NotifyIcon(nim_Add,@IconData);
    End;
      这个最重要的事情是TNotifyIconData的数据结构,它是一个设置Window句柄的数据结构,是一个记录参数,对我们来说,我们需要设置这个图标的窗口句柄(这将定义哪个窗口处理消息循环),回调消息号,图标,工具提示等。一旦这个数据设置了,我们就可以增加一个图标到任务栏上了。为了完成这个工作,使用nim_Add程序。 
      现行我们已经加了我们的图标到任务栏,下面需要决定如何处理消息。 Const
     wm_MyCallback = wm_User+1000;
     cm_Exit    = 100; { we worry about... }
     cm_About   = 101; { ...these later  }
      这个实际的窗口处理过程也是相当普通。几个窗口消息(如wm_NCCreate)必须处理。然而,对我们来说,更重要的事情是处理wm_MyCallback和wm_Command消息: 
    Function WndProc(Window : hWnd; Msg,WParam,LParam : Integer): Integer; StdCall;
    Begin
     Result := 0;
     Case Msg of
      wm_NCCreate  : Result := 1;
      wm_Destroy  : PostQuitMessage(0);
      wm_Command  : Begin { a command was chosen from the popup menu }
               If (WParam = cm_Exit) Then
                PostMessage(Window,wm_Destroy,0,0)
               Else If (WParam = cm_About) Then
                MessageBox(0,'Shell Test Copyright ?'+
                      'Jani J鋜vinen 1996.',
                      'About Shell Test',mb_OK)
               Else OpenDesktopIcon(WParam-cm_About);
              End;
      wm_MyCallback : Begin { our icon was clicked }
               If (LParam = wm_LButtonDown) Then
                ShowIconPopupMenu
               Else If (LParam = wm_RButtonDown) Then
                ShowAboutPopupMenu;
              End;
      Else Result := DefWindowProc(Window,Msg,WParam,LParam);
     End;
    End;
      就象你看到的一样,当用户单击图标时,Windows提示我们。注意我们不使用通常使用的wm_LButtonDown 消息,而使用wm_MyCallback message,详细的消息信息存储在LParam参数中。 
      当用户单击鼠标右键,我们创建一个菜单在桌面上。 Type
     TIconData = Array[1..100] of String;
    Var
     IconData  : TIconData;
    Procedure ShowIconPopupMenu;
    Var
     ShellFolder : IShellFolder;
     EnumIDList : IEnumIDList;
     Result   : hResult;
     Dummy    : ULong;
     ItemIDList : TItemIDList;
     Pntr    : PItemIDList;
     StrRet   : TStrRet;
     PopupMenu  : hMenu;
     ItemID   : Integer;
     Pos     : TPoint;
     Procedure AddToMenu(Item : String);
     Var S : String;
     Begin
      IconData[ItemID-cm_About] := Item;
      S := ExtractFileName(Item);
      If (System.Pos('.',S) <> 0) Then SetLength(S,System.Pos('.',S)-1);
      AppendMenu(PopupMenu,mf_Enabled Or mf_String,ItemID,PChar(S));
      Inc(ItemID);
     End;
    begin
     PopupMenu := CreatePopupMenu;
     ItemID := cm_About+1;
     SHGetDesktopFolder(ShellFolder);
     ShellFolder.EnumObjects(MainWindow,SHCONTF_NONFOLDERS,EnumIDList);
     Pntr := @ItemIDList;
     Result := EnumIDList.Next(1,Pntr,Dummy);
     While (Result = NoError) do Begin
      ShellFolder.GetDisplayNameOf(Pntr,SHGDN_FORPARSING,@StrRet);
      With StrRet do AddToMenu(String(CStr));
      Result := EnumIDList.Next(1,Pntr,Dummy);
     End;
     EnumIDList.Release;
     ShellFolder.Release;
     GetCursorPos(Pos);
     AppendMenu(PopupMenu,mf_Separator,0,'');
     AppendMenu(PopupMenu,mf_Enabled Or mf_String,cm_Exit,'E&xit');
     SetForegroundWindow(MainWindow);
     TrackPopupMenu(PopupMenu,tpm_LeftAlign Or tpm_LeftButton,
             Pos.X,Pos.Y,0,MainWindow,nil);
     DestroyMenu(PopupMenu);
    end;
      上面的程序看起来有点复杂,你可以将它分成两个部分来看:创建和显示菜单。 
      列举创建菜单是用Windows的外壳接口完成的。首先,我们使用SHGetDesktopForlder函数得到使用桌面的IShellFolder接口。使用这个接口,我们能得到另一个接口的实例:IEnumIDList。这个接口通常实现实际的列举工作。我们简单的重复调用这个函数直到错误值返回(例如:所有的菜单被列举)。当我们得到一个菜单,我们使用AddToMenu函数加它。   当所有的菜单被列举和创建后,现在我们需要运行这个菜单。我们将找到的菜单保存到一个全局的List变量中,每一个菜单都拥有它的菜单号。这确保我们能得到它的索引。 
     
       OpenDesktopIcon(WParam-cm_About) 当然,WParam中储存了用户单击鼠标的菜单的菜单号(ID)。   下面我们将处理运行用户选择的菜单。 Procedure OpenDesktopIcon(Number : Integer);
    Var
     S : String;
     I : Integer;
    begin
     S := IconData[Number];
     I := ShellExecute(0,nil,PChar(S),nil,nil,sw_ShowNormal);
     If (I < 32) Then Begin
      S := 'Could not open selected item "'+S+'". '+
         'Result was: '+IntToStr(I)+'.';
      MessageBox(0,PChar(S),'Shell Test',mb_OK);
     End;
    end;
      上面,Win 32 API函数ShellExecute做了所有的工作。 
      

  4.   

    有现成的控件TTrayIcon,自己去网上找一下吧