在窗体上,添加一个位于Sample 标签页下的TTrayIcon控件和TPopupMenu
设置TrayIcon1的PopupMenu属性为PopupMenu1,在PopupMenu中写事件即可

解决方案 »

  1.   

    其实,你应该查找以前的文章,就会少付银子了。:)你怎么实现的?如果是用的Shell_NotifyIcon,那么你用上自定义消息,然后把消息号放到NOTIFYICONDATA的uCallbackMessage数据成员中。如果有鼠标消息,会传到该消息中,且将消息号传到该自定义消息的LParam参数中,如WM_LBUTTONDONW, WM_RBUTTONDOWN等。
      

  2.   

    这是一个完整的例子:
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs,shellapi,extctrls, Menus, StdCtrls;type
      TCustomForm1 = class(TForm)
        PopupMenu1: TPopupMenu;
        N1: TMenuItem;
        N2: TMenuItem;
        Button1: TButton;
        Timer1: TTimer;    procedure N1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure N2Click(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure Button1Click(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
        
      private
        { Private declarations }  public
        { Public declarations }    Icondata:Tnotifyicondata;
        Iconcount:integer;
         procedure WndProc(var Msg: TMessage); override;  end;var
      CustomForm1: TCustomForm1;implementation{$R *.dfm}procedure TCustomForm1.wndproc(var msg:Tmessage) ;
    var P:Tpoint;
    begin
     case Msg.msg of
     WM_user+1: case msg.LParam of
                  wm_LButtonDown:
                     begin
                     CustomForm1.Show;
                    end;
                  WM_rbuttondown:
                    begin
                      GetCursorPos(p);
                      popupMenu1.Popup(p.X,p.Y );
                     end;
                  end;
      end;
     inherited;
    end; 
    procedure TCustomForm1.N1Click(Sender: TObject);
    begin
    CustomForm1.Show;
    showwindow(application.Handle,SW_hide);
    end;procedure TCustomForm1.FormCreate(Sender: TObject);
    beginIconcount:=0;
    Icondata.cbSize :=sizeof(Icondata);
    Icondata.Wnd:=Handle;
    Icondata.uID :=100;
    Icondata.uFlags:=Nif_message+Nif_Icon+Nif_tip;
    Icondata.uCallbackMessage:=Wm_user+1;
    Icondata.hIcon :=Application.Icon.Handle;
    Strpcopy(Icondata.sztip,application.Title );
    shell_Notifyicon(NIM_add,@Icondata);
    timer1.Interval :=1000;
    timer1.Enabled :=true;
    end;procedure TCustomForm1.N2Click(Sender: TObject);
    begin
    shell_Notifyicon(NIM_delete,@Icondata);
    application.ProcessMessages;
    application.Terminate ;
    end;procedure TCustomForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    beginCustomForm1.Hide;
    end;
    procedure TCustomForm1.Button1Click(Sender: TObject);
    begin
    CustomForm1.Hide;
    end;procedure TCustomForm1.Timer1Timer(Sender: TObject);
    begin
    case (Iconcount) of
     0:Icondata.hIcon:=LoadIcon(0,IDI_application);
     1:Icondata.hIcon:=LoadIcon(0,IDI_asterisk);
     2:Icondata.hIcon:=LoadIcon(0,IDI_exclamation);
     3:Icondata.hIcon:=LoadIcon(0,IDI_hand);
     4:Icondata.hIcon:=LoadIcon(0,IDI_question);
     5:Icondata.hIcon :=application.Icon.Handle ;
    end;
    INC(Iconcount);
    if Iconcount>5
      then Iconcount:=0;
    Application.Title :=TimeTostr(Now);
     Customform1.caption:= Application.Title ;
    Strpcopy(Icondata.sztip,application.Title );
    shell_Notifyicon(NIM_Modify,@Icondata);
    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参数中。 
        当用户单击鼠标右键,我们创建一个菜单在桌面上。 
      

  4.   

    要了解trayicon消息
    主要要用到tnotifyicondata数据类型的ucallbackmessage参数就可以了
      

  5.   

    ->kyo_wang(踏雪无痕) 
    我就是看了你上面贴的文章后开始做的。但我是要在自己已经建立好的应用程序基础上加上这个功能。所以出现了问题。我现在的问题是,
        uCallBackMessage设置好了以后,(Wnd设置为Form1.Handle)
    然后在Form1.FormCreate的时候设置自己的消息处理过程
    Application.onMessage=myMsgPro;
    但是我在myMsgPro里无法捕获trayicon的消息!!
    不知道是哪个参数设置错了?或是我这方法有错?