我在看 《DELPHI5开发指南》这本书   看到24章 的相应的例子 不过不是很明白 是编写了一个PAS 然后 在应用程序里面 use的  不过怎么下面的使用像是 个 object 还有什么位置??? 搞不明白  哪位老大如果也看过这本书的话 请指点指点  或者 有可以实现这样的功能的例子 也请发我一份 [email protected] 拜托可以有点详细的讲解 兄弟苯 ^^|b

解决方案 »

  1.   

    转贴:怎样建立简单的任务栏应用程序:
        Windows 95 和 Windows NT 4.0包含一个令人兴奋的特性:任务栏。这个通常位于区域任务条右面的区域能包含小的图标,这些图标能引出大的应用程序或者菜单。本篇文章主要讨论如何使用Delphi建立这样的应用程序。     在开始之前,请看下面的需要的接口方面的内容:     从技术方面来说,一个任务栏应用程序非常象普通的应用程序,它有一个消息循环,相应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做了所有的工作。     现在你应该能用Delphi创建简单的任务栏的程序了。 
          实际上,有一些免费的元件可以供您直接使用,不过,因为使用VCL,文件的大小将比较大,如果使用上面的方法,文件的大小将只要20K。当然,现在文件的大小已经不是我们该十分关注的问题了。 
      

  2.   

    基本照书搬的
    unit TrayIcon;interfaceuses
      Windows, SysUtils, Messages,  Classes, Graphics,  Forms,
      StdCtrls, ShellApi, Menus, ExtCtrls ;
    type
      ENotifyIconError = class(Exception);  TTrayNotifyIcon = class(TComponent)
      private
        FDefaultIcon : THandle;
        FIcon : TIcon;
        FHideTask : Boolean;
        FHint : string;
        FIconVisible : Boolean;
        FPopupMenu : TPopupMenu;
        FOnClick : TNotifyEvent;
        FOnDblClick : TNotifyEvent;
        FNoShowClick : Boolean;
        FTimer : TTimer;
        Tnd : TNotifyIconData;    procedure SetIcon(Value:TIcon);
        procedure SetHideTask(Value:Boolean);
        procedure SetHint(Value : string);
        procedure SetIconVisible(Value:Boolean);
        procedure SetPopupMenu(Value:TPopupMenu);
        procedure SendTrayMessage(Msg:DWORD;Flags:UINT);
        function  ActiveIconHandle : THandle;
        procedure OnButtonTimer(Sender:TObject);
      protected
        procedure Loaded ; override;
        procedure LoadDefaultIcon ; virtual;
        procedure Notification(AComponent:TComponent;Operation:TOperation);override;
      public
        constructor Create(AOwner:TComponent); override;
        Destructor  Destroy;  override;
      published
        property Icon: TIcon read FIcon write SetIcon;
        property HideTask:Boolean read FHideTask write SetHideTask default false;
        property Hint: string read FHint  write  SetHint;
        property IconVisible: boolean read FIconVisible write SetIconVisible
                     default false;
        property PopupMenu: TPopupMenu read FPopupMenu write SetPopupMenu;
        property OnClick: TNotifyEvent read FOnClick write FOnClick;
        property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;
      end;
    implementation
    type
      TIconManager=class
      private
        FHWindow: HWnd;
        procedure TrayWndProc(var Message:TMessage);
      public
        constructor create;
        destructor  destroy; override;    property HWindow : HWnd read FHWindow write  FHWindow;
      end;var
      IconMgr:TIconManager;
      DDGM_TRAYICON:integer;constructor TIconManager.create;
    begin
      FHWindow:=AllocateHWnd(TrayWndProc);
    end;destructor  TIconManager.destroy;
    begin
      if FHWindow<>0 then DeallocateHWnd(FHWindow);
      inherited destroy;
    end;procedure TIconManager.TrayWndProc(var Message:TMessage);
    var Pt:TPoint;
        TheIcon:TTrayNotifyIcon;
    begin
      with  Message do
      begin
        if (Msg=DDGM_TRAYICON) then
        begin
          TheIcon:=TTrayNotifyIcon(WParam);
          case lParam of
            WM_LBUTTONDOWN: TheIcon.FTimer.Enabled:=true;        WM_LBUTTONDBLCLK:
               begin
                 TheIcon.FNoShowClick:=true;
                 if Assigned(TheIcon.FOnDblClick) then TheIcon.FOnDblClick(self);
               end;
            WM_RBUTTONDOWN:
               begin
                 if Assigned(TheIcon.FPopupMenu) then
                 begin
                   SetForegroundWindow(Iconmgr.HWindow);
                   GetCursorPos(Pt);
                   TheIcon.FPopupMenu.Popup(Pt.x,Pt.y);
                   PostMessage(Iconmgr.HWindow,WM_USER,0,0);
                 end;           end;      end;    end
        else
          result:=DefWindowProc(FHWindow,Msg,wParam,lParam);
      end;
    end;//------------------------------------------------------------------------------constructor TTrayNotifyIcon.Create(AOwner:TComponent);
    begin
      inherited create( AOwner);
      FIcon:=TIcon.Create;
      FTimer:=TTimer.Create(self);
      with FTimer do
      begin
        enabled:=false;
        interval:=GetDoubleClicktime;
        OnTimer:=OnButtonTimer;
      end;
      LoadDefaultIcon;
    end;destructor TTrayNotifyIcon.Destroy;
    begin
      if FIconVisible then SetIconVisible(false);
      FIcon.Free;
      FTimer.Free;
      inherited destroy;
    end;function TTrayNotifyIcon.ActiveIconHandle : THandle;
    begin
      if (FIcon.Handle<>0) then result:= FIcon.Handle
      else result:=FDefaultIcon;
    end;procedure  TTrayNotifyIcon.LoadDefaultIcon;
    begin
      FDefaultIcon:=LoadIcon(0,IDI_WINLOGO);
    end;procedure  TTrayNotifyIcon.Loaded;
    begin
      inherited  Loaded;
      if FIconVisible then
         SendTrayMessage(NIM_ADD,NIF_MESSAGE or NIF_ICON or NIF_TIP);
    end;procedure  TTrayNotifyIcon.Notification(AComponent:TComponent;Operation:TOperation);
    begin
      inherited Notification(AComponent, Operation);
      if (Operation=opRemove) and (AComponent=PopupMenu) then
         PopupMenu:=nil;
    end;procedure  TTrayNotifyIcon.OnButtonTimer(Sender:TObject);
    begin
      FTimer.Enabled:=false;
      if (not FNoShowClick) and Assigned(FOnClick) then
         FOnClick(self);
      FNoShowClick:=false;
    end;procedure  TTrayNotifyIcon.SendTrayMessage(Msg:DWORD;Flags:UINT);
    begin
      with Tnd do
      begin
         cbSize:=Sizeof(Tnd);
         strPLCopy(szTip,PChar(FHint),SizeOf(szTip));
         uFlags:=Flags;
         uID:=UINT(self);
         Wnd:=IconMgr.HWindow;
         uCallBackMessage:=DDGM_TRAYICON;
         hIcon:=ActiveIconHandle;
      end;
      Shell_NotifyIcon(Msg,@Tnd);
    end;procedure  TTrayNotifyIcon.SetHideTask(value:boolean);
    const
      ShowArray:array [boolean] of integer=(sw_ShowNormal,sw_Hide);
    begin
      if FHideTask<>value then
      begin
         FHideTask:=value;
         if not (csDesigning in ComponentState) then
            ShowWindow(application.Handle,ShowArray[FHideTask]);
      end;
    end;procedure  TTrayNotifyIcon.SetHint(value:string);
    begin
      if FHint<> value then
      begin
        FHint:=value;
        if FIconVisible then
           SendTrayMessage(NIM_MODIFY,NIF_TIP);
      end;
    end;procedure  TTrayNotifyIcon.SetIcon(value:TIcon);
    begin
      FIcon.Assign(value);
      if FIconVisible then SendTrayMessage(NIM_MODIFY,NIF_ICON);
    end;procedure  TTrayNotifyIcon.SetIconVisible(value:boolean);
    const
      MsgArray:array [boolean] of DWORD =(NIM_DELETE,NIM_ADD);
    begin
      if FIconVisible<> value then
      begin
        FIconVisible:=value;
        SendTrayMessage(MsgArray[value],NIF_MESSAGE or NIF_ICON or NIF_TIP);
      end;
    end;procedure  TTrayNotifyIcon.SetPopupMenu(value:TpopupMenu);
    begin
      FPopupMenu:=value;
      if value <> nil then value.FreeNotification(self);
    end;
    const
      TrayMsgStr='DDG.TrayNotifyIconMsg';initialization
       DDGM_TRAYICON:=RegisterWindowMessage(TrayMsgStr);
       IconMgr:=TIconManager.create;
    finalization
       IconMgr.Free;
    end.//================================================================
    unit Unit_main;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs,StdCtrls,ShellApi,TrayIcon,Menus,ComCtrls;type
      TForm1 = class(TForm)
        pmiPopup: TPopupMenu;
        Properties1: TMenuItem;
        N1: TMenuItem;
        Exit: TMenuItem;
        //TrayNotifyIcon1:TTrayNotifyIcon;
        procedure NotifyIcon1Click(Sender:TObject);
        procedure NotifyIconDb1Click(Sender:TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure FormCreate(Sender: TObject);
        procedure ExitClick(Sender: TObject);
        
      private
        { Private declarations }
        //pmiPopup:TPopupMenu;    //Terminate1:TMenuItem;
        TrayNotifyIcon1:TTrayNotifyIcon;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      Action:=caNone;
      Hide;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      TrayNotifyIcon1:=TTrayNotifyIcon.Create(nil);
      TrayNotifyIcon1.Icon:=application.Icon;
      TrayNotifyIcon1.IconVisible:=true;
      TrayNotifyIcon1.Hint:='托盘测试程序';  TrayNotifyIcon1.OnClick:=NotifyIcon1Click;
      TrayNotifyIcon1.OnDblClick:=NotifyIconDb1Click;
      TrayNotifyIcon1.PopupMenu:=pmiPopup;
    end;procedure TForm1.NotifyIcon1Click(Sender:TObject);
    begin
      showmessage('steel');
    end;procedure TForm1.NotifyIconDb1Click(Sender:TObject);
    begin
      show;
    end;procedure TForm1.ExitClick(Sender: TObject);
    begin
      //TrayNotifyIcon1.IconVisible:=false;
      TrayNotifyIcon1.Free;
      Application.Terminate;
    end;end.