就象金山词霸一样,运行时在系统托盘里显示一个自己定义的小图标,左击小图标时,显示主窗口,右击时显示一个菜单。在DELPHI7.0里怎么实现啊?

解决方案 »

  1.   

    uses
      ShellAPI,...;
    var
        TrayIconData: TNotifyIconData;   //定义一个托盘图标的类procedure Tmainform.FormCreate(Sender: TObject);
    begin
      //建立托盘图标
      TrayIconData.cbSize := sizeof(TrayIconData); //TrayIconData变量的字节数
      TrayIconData.Wnd := Handle;   //主窗口句柄
      TrayIconData.uID := 1;        //内部标识,可设为任意数
      TrayIconData.hIcon := Icon.Handle;
      {要加入的图标句柄,可任意指定,此处为在Tform中Icon属性中指定的图标
      TrayIconData.hIcon := Application.Icon.Handle;
      此句使用了程序的图标,和上句程序有区别,下句亦可,但推荐使用上句,这样图标加
      入到托盘中时图标不会走样。}
      TrayIconData.hIcon := LoadIcon(0,IDI_APPLICATION);
      TrayIconData.szTip := '正在运行-\\轨道衡客户端';//图标的提示信息,即黄色的Hint
      TrayIconData.uCallbackMessage := MYTRAY_MESSAGE;
      TrayIconData.uFlags := NIF_ICON or NIF_TIP or NIF_MESSAGE; //指明哪些字段有效
      {将程序的窗口样式设为TOOL窗口,可避免在任务条上出现}
      SetWindowLong(Application.Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
      Shell_NotifyIcon(NIM_ADD, @TrayIconData); //向托盘中添加图标
    end;procedure Tmainform.FormPaint(Sender: TObject);
    begin
      Hide;
    end;procedure TMainForm.MyTrayMessage(var message: Tmessage);
    var //托盘消息处理事件
      CursorPos : TPoint;
    begin
      //在这里处理用户点击托盘图标事件,可以根据WM_MOUSEMOVE消息的不同情况产生不同的
      //回应,例如区别对待单击和双击等等
      case message.lParam of
      //
      //WM_LBUTTONDOWN :
        //if not Busy then begin    ShowWindow(Handle, SW_SHOW );  WM_RBUTTONDOWN :
      begin
        GetCursorPos(CursorPos);
        SetForegroundWindow(handle);
        //此句作用是当程序失去焦点时,弹出菜单也随之消失。
        Application.ProcessMessages;
        //取得光标当前位置
        TrayPopMenu.Popup( CursorPos.x ,CursorPos.y );
        PostMessage(Application.MainForm.Handle, WM_NULL, 0, 0);
      end;
      end;
    end; procedure Tmainform.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      TrayIconData.cbSize := sizeof(TrayIconData);   //TrayIconData变量的字节数
      TrayIconData.uID := 1;        //内部标识,与加入小图标时的数一致
      TrayIconData.Wnd := Handle;   //主窗口句柄
      //TrayIconData.uFlags := 0;
      Shell_NotifyIcon(NIM_DELETE, @TrayIconData);   //去掉小图标
    end;
      

  2.   

    //我也来抄袭一个。。仅供参考,,谁让我刚开始学df呢。
    unit TestForm;interfaceuses
    Windows, Classes, Forms, Controls, StdCtrls, ExtCtrls;typeTZoomAction = (zaMinimize, zaMaximize);TfrmTest = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormShow(Sender: TObject);
    private
    { private declaration }
    public
    { public declaration }
    end;var
    frmTest: TfrmTest;implementation{$R *.DFM}procedure ZoomEffect(theForm: TForm; theOperation: TZoomAction);
    var
    rcStart: TRect;
    rcEnd: TRect;
    rcTray: TRect;
    hwndTray : hWnd;
    hwndChild: hWnd;
    begin
    { 寻找系统托盘区的位置}
    hwndTray := FindWindow('Shell_TrayWnd', nil);
    hwndChild := FindWindowEx(hwndTray, 0, 'TrayNotifyWnd', nil);
    GetWindowRect(hwndChild, rcTray);{点击用于最大化/最小化,并切换起始/结束}
    if theOperation = zaMinimize then
    begin
    rcStart := theForm.BoundsRect;
    rcEnd := rcTray;
    end
    else
    begin
    rcEnd := theForm.BoundsRect;
    rcStart := rcTray;
    end;{ 以下是关键的部分... }
    DrawAnimatedRects(theForm.Handle, IDANI_CAPTION, rcStart, rcEnd)
    end;procedure TfrmTest.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
    ZoomEffect(Self, zaMinimize);
    end;procedure TfrmTest.FormShow(Sender: TObject);
    begin
    ZoomEffect(Self, zaMaximize);
    end;end.
      

  3.   

    http://coldel.myrice.com/html/054.htm任务栏中的托盘程序设计                                      任务栏中的托盘程序设计
                           高红岩
      在我们平常设计项目时通常把一些常驻内存或使用频率比较高的程序做成托盘的形式,一来能使程序外观得到整洁性,二来能使程序更具专业性。
      在设计任务栏中的托盘程序时主要用到了一个WIN API函数Shell_NotifyIcon,大部分功能的实现都是在此函数基础上来实现的,该函数的原型如下: 
      WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(
    DWORD dwMessage, // message identifier
    PNOTIFYICONDATA pnid // pointer to structure
                         );
      通过看到参数我们知道要传递一个dwMessage消息参数的标识类型和一个指向具体修改信息的结构pnid,第一个参数的具体取值如下:
      dwMessage
      Identifier of the message to send. This parameter can be one of these values:
      NIM_ADD Adds an icon to the status area.{添加图标}
      NIM_DELETE Deletes an icon from the status area.{删除图标}
      NIM_MODIFY Modifies an icon in the status area. {修改图标}
      即为添加一个图标,删除一个图标和修改一个图标在任务栏的右部区域中。可以通过第一个参数的内容来定制对任务栏状态区的操作,第二个参数的具体取值如下:
      pnid
      Pointer to a NOTIFYICONDATA structure. The content of the structure depends on the value of dwMessage. 
      此参数为一个指向NOTIFYICONDATA结构的指针,通过这个结构来对设计者想要的操作进行定义,结构成员定义如下:
      typedef struct _NOTIFYICONDATA { // nid 
    DWORD cbSize; {结构的大小}
    HWND hWnd; {关联状态区图标的窗口句柄,用来处理回调函数}
    UINT uID; {应用程序定义的状态区图标的标识符}
    UINT uFlags; {此成员表明NOTIFYICONDATA记录中的成员uCallbackMessage、hIcon和szTip这三者的哪些项的值有效}
    UINT uCallbackMessage; {程序定义的消息标识符,例如当鼠标在状态区图标上移动或者左右点击所发生的事情时,操作系统将向Wnd指定的那个窗口发送uCallbackMessage消息。在uCallbackMessage消息中,lParam参数包含了Windows的鼠标消息的类型,而wParam参数则包含了图标标识(即uID)。有效的鼠标消息包括以下几个:WM_LBUTTONDOWN、WM_RBUTTONDOWN、WM_MBUTTONDOWN、WM_LBUTTONUP、WM_RBUTTONUP、WM_MBUTTONUP、WM_MOUSEMOVE、WM_LBUTTONDBLCLK、WM_RBUTTONDBLCLK以及WM_MBUTTONDBLCLK。
    }
      

  4.   

    unit TrayIcon;interface  uses Windows,SysUtils,Messages,ShellAPI,Classes,Graphics,Forms,Menus,
        Stdctrls,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{TIconManager}
    {This class creates a hidden window which handles and routes}
    {tray icon messages}
    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);
    {This allows us to handle all tray callback messages}
    {form within the context of the component.}
    var
      Pt:TPoint;
      TheIcon:TTrayNotifyIcon;
    begin
      with Message do
      begin
        {if in's the tray callback message}
        if (Msg = DDGM_TRAYICON) then
        begin
          TheIcon:=TTrayNotifyIcon(WParam);
          case lParam of
          {enable timer on first mouse down.}
          {OnClick will be fired by OnTimer method,provided}
          {double click has not occurred.}
          WM_LBUTTONDOWN:TheIcon.FTimer.Enabled:=True;
          {Set no click flag on double click. This will suppress}
          {the single click.}
          WM_LBUTTONDBLCLK:
            begin
              TheIcon.FNoShowClick:=true;
              if Assigned(TheIcon.FOnDblClick) then TheIcon.FOnDblclick(Self);
            end;
          WM_RBUTTONDOWN:
            begin
              if Assigned(TheIcon.FPopupMenu) then
              begin
                {Call to SetForegroundWindow is required by API}
                SetForegroundWindow(IconMgr.HWindow);
                {Popup local menu at the cursor position.}
                GetCursorPos(Pt);
                TheIcon.FPopupMenu.Popup(Pt.X,Pt.Y);
                {Message post required by API to force task switch}
                PostMessage(IconMgr.HWindow,WM_USER,0,0);
              end;        end;
          end;
        end
        else
          {If it isn't a tray callback message,then call DefWindowProc}
          Result:= DefWindowProc(FHWindow,Msg,wParam,lParam);
      end;
    end;
    {