CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
IBM Rational 系统开发最佳实践工具包 WebSphere MQ 最佳实践 TOP 15
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  Windows SDK/API

请问有关 窗体最小化时 显示为托盘图标的问题

楼主xkfxd(xkf)2002-12-24 16:36:24 在 Delphi / Windows SDK/API 提问

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

1 楼cg1120(代码最优化-§惟坚韧者始能遂其志§)回复于 2002-12-24 16:45:33 得分 20

转贴:  
   
  怎样建立简单的任务栏应用程序:  
          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。当然,现在文件的大小已经不是我们该十分关注的问题了。    
  Top

2 楼xkfxd(xkf)回复于 2002-12-25 09:17:46 得分 0

多谢多谢     再求一下   例子吧     哪位有的话   请赐教Top

3 楼steel1991(首席潜水员)回复于 2002-12-25 09:55:22 得分 80

基本照书搬的  
  unit   TrayIcon;  
   
  interface  
   
  uses  
      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;  
   
  interface  
   
  uses  
      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.Top

4 楼xkfxd(xkf)回复于 2002-12-25 10:03:20 得分 0

立刻去试验     成功就给分Top

5 楼xkfxd(xkf)回复于 2002-12-25 10:29:10 得分 0

成了     感谢Top

相关问题

  • 请教高手:在最小化窗体时怎样将窗体图标在托盘显示
  • 如何设置系统托盘,按窗体最小化按钮时缩小到任务栏(托盘图标保留),按关闭按钮时缩小到托盘?
  • VB6编程问题:我的窗体可以在点击窗体上的最小化按钮时,使之最小化到右下角的托盘中,但是我点击托盘中的这个图标时激发了哪个VB6事件,
  • 程序最小化时托盘图标显示的问题?
  • 怎么当窗体最小化时在系统托盘上显示呢?
  • 如何让一个窗体最小化时隐藏到系统托盘?
  • 如何给其它程序的无图标窗体添加最小化按钮?
  • 求救!!请问大侠们如何实现窗体最小化时,窗体图标隐藏在任务栏中?
  • 窗体最小化问题
  • 窗体最小化问题!

关键词

  • 函数
  • 应用程序
  • ttraynotifyicon
  • traynotifyicon
  • theicon
  • 图标
  • ficonvisible
  • popupmenu
  • 菜单
  • nif

得分解答快速导航

  • 帖主:xkfxd
  • cg1120
  • steel1991

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo