Delphi托盘编程实战演练_白芒果_新浪博客

 Delphi托盘编程实战演练         DavidLove(原作)      
       
  关键字           RAD   托盘编程   任务栏   消息机制    
       
   
   
          很多人认为Delphi是一个RAD工具,包括我本人在上学的时候对Delphi也有偏见,现在走出了“象牙塔”,涉及的面广了,遇到的问题多了,慢慢地也有了自己的一点心得体会。其实,Delphi是基于Object   Pascal   语言的开发工具,也就是说Delphi本质上是一种语言工具,并且是真正的面向对象的。下面我举的例子就是用Delphi实现的一个托盘小程序。程序短小精悍,脉络分明,我将对关键部分进行详细讲解。就象候俊杰先生把MFC一层一层地剥开一样,今天我也来一次“庖丁解牛”。  
   
        在Delphi中涉及到系统编程的方面毫无例外都要调用API函数,在ShellAPI.pas单元中有要用到的API函数的原型。  
   
  实战演练:  
   
  一.新建一个应用程序:File->New   Applicaton   在Interface部分定义一个消息常量:const   WM_NID=WM_USER+1000;   系统规定从WM_USER开始为用户自定义消息。  
   
  二.定义一个全局变量:   NotifyIcon:TNotifyIconData,NotifyIcon是非常重要的一个变量,整个程序基本上是围着这个变量在转。TNotifyIconData是一个记录类型,按住Ctrl键,在TNotifyIconData   双击即进入ShellAPI.pas单元。(注:在Delphi中,这是一个非常好的对源代码进行分析的方法,源代码说明一切,你要想知道程序背后的内幕,{zh0}的方法就是分析源代码!)此时出现了以下赋值语句:  
   
  TNotifyIconData   =   TNotifyIconDataA,这个意思很明显,就是说TNotifyIconData和TNotifyIconDataA是同种数据类型,接着往下看有:  
   
  TNotifyIconDataA   =   _NOTIFYICONDATAA,意思与刚才的一样,再往下看:      
   
  type  
   
  _NOTIFYICONDATAA   =   record  
   
                cbSize:   DWORD;  
   
                Wnd:   HWND;  
   
                uID:   UINT;  
   
                uFlags:   UINT;  
   
                uCallbackMessage:   UINT;  
   
                hIcon:   HICON;  
   
  szTip:   array   [0..63]   of   AnsiChar;  
   
  end;  
   
  这可真是“千呼万唤始出来,犹抱琵琶半遮面”。现在大家很清楚了,我们刚才定义的全局变量NotifyIcon其实是一个包含有7个成分的记录类型变量,就相当于C/C++中的结构体变量(C/C++的程序员应该是再熟悉不过了)。下面我们逐个来解释记录类型中的7个部分各有什么功能。  
   
  1>                 cbSize就是你定义的NotifyIcon变量的大小,用SizeOf(TNotifyIconData)可以取得,如果你是一个熟练的C/C++程序员,你应该不会陌生。在C/C++中,每当要为一个结构体变量分配内存的时候都要:通过   SizeOf(Struct   type)   来获知存放一个这样的结构体变量要多少内存。  
   
  2>                 Wnd是一个句柄,你希望托盘程序产生的消息有哪个窗体来处理就让Wnd指向那个窗体。  
   
  例如:你准备在任务栏的托盘小图标上单击时窗体是窗体在“显示”和“隐藏”之间切换,则把Wnd指向主窗体。  
   
  3>     uID:如果你要创建多个托盘小程序,那么怎么区分它们呢?就是靠这个ID号来区分。  
   
  3>                 uFlags是一个标志位,它表示当前所创建的托盘程序具有哪些性质:  
   
  NIF_ICON                     表示当前所设置的图标(即hIcon的值)是有效的    
   
  NIF_MESSAGE                       表示当前所设置的系统消息(即uCallBackMessage的值)是有效的  
   
  NIF_TIP                           表示当前所设置的提示条(即szTip的值)是有效的。  
   
  4>                 uCallBackMessage这是7个部分里面最重要的一个。这里指定一个回调消息,也就是说这里定义一个消息名,当你单击或者右击托盘图标的时候就会向你在Wnd所指向的窗体发送一个在uCallBackMessage中定义的消息名,然后你在程序中定义一个消息出来函数来处理这个消息。这样就把Windows关于消息的整套流程都处理好了。    
   
  6>       hIcon为托盘图标的句柄,根据这个句柄你就可以增加、修改、删除图标。  
   
  7>               szTip就是当你的鼠标放到任务栏托盘的小图标上的时候弹出来的提示信息。  
   
  在这里我花了大量的笔墨介绍TNotifyIconData的内幕,把这部分搞清楚了,后面的东西就顺理成章了。  
   
  三.   双击主窗体,进入FormCreate的代码区域:  
   
  TForm1.FormCreate(Sender:TObject);  
   
  Begin  
    //NotifyIcon为全局变量,在程序的开头已经定义了  
    with   NotifyIcon   do  
          begin  
                cbSize:=SizeOf(TNotifyIconData);  
                Wnd:=Handle;       //指向当前窗体Form1的句柄  
                uID:=1;  
                uFlags:=NIF_ICON   or   NIF_MESSAGE   or   NIF_TIP;  
                uCallBackMessage:=WM_NID;//自定义消息  
                hIcon:=Application.Icon.Handle;  
                szTip:=”张家恶少”;  
          end;  
  //把设置好的变量NotifyIcon加入到系统中以便处理  
        Shell_NotifyIcon(NIM_ADD,@NotifyIcon);  
  End;  
   
  四.接下来就是定义一个消息处理函数:系统给窗体发来了一个消息,就由下面这个函数来处理。每个消息处理函数都是处理某一类消息的,大家仔细地看看下面函数体的定义和一般的函数定义有什么不一样:消息处理函数要在后面加上消息的名称,这样当系统发来WM_NID消息时,就是自动触发WMNID消息处理函数。  
   
  procedure   WMNID(var   msg:TMessage);message   WM_NID;  
   
                begin  
   
                  case   msg.LParam   of  
   
                          WM_LBUTTONUp:   Form1.Visible:=not   Form1.Visible;  
   
                        WM_RBUTTONUP:   ShowMessage(‘您点击的是右键’);  
   
                  End;  
   
  End;  
   
  好了,一个最简单的程序诞生了,大家自己设置好自己喜欢的图标.  
   
  Project->Options,选中Application页面,在Icon项中加载自己喜欢的图标,这样程序运行时,在任务栏里显示的就是你喜欢的图标了。当你单击图标时,窗体Form1会在可见与不可见之间切换,也就是说单击一下显示,再单击一下又隐藏。当你右击图标的时候会弹出一条消息:“你点击的是右键”。  
   
  五.{zh1}要记住在关闭应用程序的时候要释放掉建立的托盘程序,否则会占用系统资源。  
   
  TForm1.FormDestroy(Sender:TObject);  
   
  Begin  
   
      Shell_NotifyIcon(NIM_DELETE,@NotifyIcon);  
   
  End;    
   
  毕业快半年了,很多东西在学校总理解不了,认识不够深刻;出到社会,接触了不少道中朋友,受益非浅,每有心得体会,总想写成文字,一来总结自己学的东西,二来和大家共同交流。  

//托盘可使用TrayIcon控件  
  procedure   wmsyscommand(var   Msg:   TWMSysCommand);   message   WM_SYSCOMMAND;  
   
  procedure   TForm1.wmsyscommand(var   Msg:   TWMSysCommand);  
  begin  
      if   Msg.CmdType   =   SC_MINIMIZE   then  
      inherited;  
  end;  
  这些是我找到的:  
   
  给你一篇参考资料:  
  怎样建立简单的任务栏应用程序:  
       
          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;  
          你能看到:所有需要做的工作是创建一个窗口,注册一个图标到任务栏,设置它的消息循环,{zh1}关闭它。当然,必须还有增加其他代码完成相应的功能,但是,它是真的不需要担心。    
          让我们从窗口的创建开始。实际上,这个窗口是不是能在任务栏上能见到的窗口。相应的,这个窗口只是处理消息循环、其它父类的工作。任务窗口(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;   
 

//  Delphi中任务栏状态区的编程    
  西安交通大学    
  刘明华    
  ----     在Windows桌面的任务栏上有一个凹陷的区域,其中显示着系统时钟以及一些图标,这个长方形的区  
  域便是Windows的任务栏状态区(taskbar   status   area)。本文将介绍使用Borland   Delphi进行任务栏状态  
  区的编程,即怎样将应用程序的图标显示在任务栏状态区中。    
   
  ----   实现原理    
   
  ----   任务栏状态区的图标添加、删除、以及修改是通过Windows   API函数Shell_NotifyIcon来实现的,该函  
  数是由Windows的SHELL32.DLL动态联接库提供的。在Delphi中,Shell_NotifyIcon函数是在ShellAPI单元  
  声明的,其    
   
  ----   函数原型如下:    
   
  ----   function   Shell_NotifyIcon(dwMessage:   DWORD;   lpData:   PNotifyIconData):   BOOL;   stdcall;    
   
  ----   其中参数dwMessage的取值决定函数Shell_NotifyIcon所要进行的操作的类型,它的取值可以是以下三  
  者之一:    
   
  ----   NIM_ADD(值为0):在任务栏状态区插入一个图标。    
   
  ----   NIM_DELETE(值为1):从任务栏状态区删除一个图标。    
   
  ----   NIM_MODIFY(值为2):修改任务栏状态区的图标、提示信息、或者通知消息。    
   
  ----   参数lpData   是一个记录类型(结构类型)的指针,记录类型NotifyIconData的定义如下:    
   
      NOTIFYICONDATA   =   record  
          cbSize:   DWORD;  
          Wnd:   HWND;  
          uID:   UINT;  
          uFlags:   UINT;  
          uCallbackMessage:   UINT;  
          hIcon:   HICON;  
          szTip:   array   [0..63]   of   AnsiChar;  
      end;  
  ----   cbSize:NOTIFYICONDATA记录的大小。    
  ----   Wnd:与此状态区图标相关联的窗口句柄,此窗口将负责处理uCallbackMessage消息。    
   
  ----   uID:程序自定义的状态区图标的标识符。    
   
  ----   uFlags:这个字段指明NOTIFYICONDATA记录中的成员uCallbackMessage、hIcon和szTip这三者的哪些  
  项的值有效。它的取值可以是下列三者的组合(or运算):    
   
  ----   NIF_MESSAGE   (值为1):uCallbackMessage项包含了有效的信息。    
   
  ----   NIF_ICON(值为2):hIcon项包含了有效的信息。    
   
  ----   NIF_TIP(值为4):   szTip项包含了有效的信息。    
   
  ----   uCallbackMessage:程序定义的消息标识符(32位的整数)。当鼠标在状态区图标上移动或者点击(  
  即,发生了鼠标事件)时,操作系统将向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。    
   
  ----   hIcon:指定一个图标句柄。    
   
  ----   szTip:显示在图标上的提示信息(少于63个字符)。    
   
  ----   Delphi中的实现    
   
  ----   通过上面的介绍中,我们不难看出,任务栏状态区的编程主要是处理两方面的工作:添加、删除、修改  
  图标;以及处理通知消息。对于图标的添加、删除、修改操作,可以通过调用Shell_NotifyIcon函数来实现。  
  而对于自定义的通知消息,我们就应该在消息循环中给予处理了。    
   
   
  ----   下面的示例给出了状态区图标的添加、修改和删除操作的例子,以及图标的通知消息的基本处理框架。  
     
   
  unit   Unit1;  
   
  interface  
   
  uses  
      Windows,   Messages,   SysUtils,   Classes,   Graphics,  
      Controls,   Forms,   Dialogs,   ExtCtrls,   ShellAPI;  
   
  const  
      WM_TRAYNOTIFY=WM_USER+1;//定义通知消息  
   
  type  
      TForm1   =   class(TForm)  
          Timer1:   TTimer;  
          procedure   FormCreate(Sender:   TObject);  
          procedure   Timer1Timer(Sender:   TObject);  
          procedure   FormDestroy(Sender:   TObject);  
      private  
          {   Private   declarations   }  
      public  
          {   Public   declarations   }  
          procedure   WndProc(var   Msg:   TMessage);   override;  
      end;  
   
  var  
      Form1:   TForm1;  
      nd0,   nd1:NotifyIconData;  
      hs:array[0..9]of   LongWord;  
   
  implementation  
  {$R   *.DFM}  
   
  procedure   TForm1.FormCreate(Sender:   TObject);  
  begin  
      //加载Icon0..Icon9这10个图标资源,  
  并且保存它们的句柄。  
      //图标Icon0..Icon9分别对应与0..9这9个数字。  
      hs[0]:=LoadIcon(hInstance,   'Icon0');  
      hs[1]:=LoadIcon(hInstance,   'Icon1');  
      hs[2]:=LoadIcon(hInstance,   'Icon2');  
      hs[3]:=LoadIcon(hInstance,   'Icon3');  
      hs[4]:=LoadIcon(hInstance,   'Icon4');  
      hs[5]:=LoadIcon(hInstance,   'Icon5');  
      hs[6]:=LoadIcon(hInstance,   'Icon6');  
      hs[7]:=LoadIcon(hInstance,   'Icon7');  
      hs[8]:=LoadIcon(hInstance,   'Icon8');  
      hs[9]:=LoadIcon(hInstance,   'Icon9');  
   
      //填充NotifyIconData记录型变量nd0  
      nd0.cbSize   :=   sizeof(NotifyIconData);  
      nd0.Wnd   :=   handle;  
      nd0.uID   :=   0;  
      nd0.uFlags   :=   NIF_MESSAGE   or   NIF_ICON   or   NIF_TIP;  
      nd0.uCallbackMessage   :=   WM_TRAYNOTIFY;  
      nd0.hIcon   :=   hs[0];  
      StrPLCopy(nd0.szTip,   'Hello,   World!',   63);  
   
      //填充NotifyIconData记录型变量nd1  
      nd1.cbSize   :=   sizeof(NotifyIconData);  
      nd1.Wnd   :=   handle;  
      nd1.uID   :=   1;  
      nd1.uFlags   :=   NIF_MESSAGE   or   NIF_ICON   or   NIF_TIP;  
      nd1.uCallbackMessage   :=   WM_TRAYNOTIFY;  
      nd1.hIcon   :=   hs[0];  
      StrPLCopy(nd1.szTip,   'Simon   Loves   Daisy',   63);  
   
      //在任务栏状态区添加图标  
      Shell_NotifyIcon(NIM_ADD,   @nd0);  
      Shell_NotifyIcon(NIM_ADD,   @nd1);  
  end;  
   
  procedure   TForm1.Timer1Timer(Sender:   TObject);  
  var  
      st:SystemTime;  
  begin  
      //每秒钟更新一次图标:图标0显示秒数的十位,  
  图标1显示秒数的个位。  
      GetLocalTime(st);  
      nd0.hIcon   :=   hs[st.wSecond   div   10];  
      nd1.hIcon   :=   hs[st.wSecond   mod   10];  
      //修改任务栏状态区的图标  
      Shell_NotifyIcon(NIM_MODIFY,   @nd0);  
      Shell_NotifyIcon(NIM_MODIFY,   @nd1);  
  end;  
   
  procedure   TForm1.FormDestroy(Sender:   TObject);  
  begin  
      //将图标从任务栏状态区删除  
      Shell_NotifyIcon(NIM_DELETE,   @nd0);  
      Shell_NotifyIcon(NIM_DELETE,   @nd1);  
  end;  
   
  //处理   通知消息  
  procedure   TForm1.WndProc(var   Msg:   TMessage);  
  var  
      IconID:integer;  
      pt:TPOINT;  
  begin  
      if   msg.Msg   =   WM_TRAYNOTIFY   then  
      begin  
      {  
      在通知消息中,wParam参数为图标的uID,  
      lParam参数为鼠标事件的类型。  
      }  
          iconID   :=   msg.WParam;  
          //获取鼠标的在屏幕上的位置  
          GetCursorPos(pt);  
   
      //通知消息的处理的基本框架结构如下:  
          case   msg.lParam   of  
              WM_LBUTTONDOWN:  
              begin  
                  //鼠标右键被按下  
              end;  
              WM_RBUTTONDOWN:  
              begin  
                  //鼠标左键被按下  
              end;  
              WM_LBUTTONUP:  
              begin  
                  //释放鼠标左键  
              end;  
              WM_RBUTTONUP:  
              begin  
                  //释放鼠标右键  
              end;  
              WM_MOUSEMOVE:  
              begin  
                  //鼠标在图标上移动  
              end;  
              WM_LBUTTONDBLCLK:  
              begin  
                  //鼠标左键双击  
              end;  
              WM_RBUTTONDBLCLK:  
              begin  
                  //鼠标右键双击  
              end;  
          end;   //end   case  
      end  
      else//调用父类的WndProc方法处理其它消息  
          inherited;  
  end;  
   
  end.

已投稿到:
郑重声明:资讯 【Delphi托盘编程实战演练_白芒果_新浪博客】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——