⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 034.htm

📁 Delphi书籍--Delphi网上教程
💻 HTM
字号:
<HTML><HEAD><meta http-equiv="Content-Type" content="text/html; charset=GB2312"><TITLE>-->DELPHI专题文档-程序应用-->怎样建立简单的任务栏应用程序</TITLE>
<META NAME="keywords" CONTENT=" DELPHI专题文档-程序应用 怎样建立简单的任务栏应用程序">
<META NAME="description" CONTENT=" - DELPHI专题文档-程序应用 - 怎样建立简单的任务栏应用程序">

<style>
<!--
#page {position:absolute; z-index:0; left:0px; top:0px}
.tt3 {font: 9pt/12pt "宋体"}
.tt2 {font: 12pt/15pt "宋体"}
a {text-decoration:none}
a:hover {color: blue;text-decoration:underline}
-->
</style>
</HEAD>
<a href="index6.html">返回</a>

<body text="#000000" aLink=#9900ff link=#006699 vLink=#006699 bgcolor="#FFFFFF" leftmargin="3" topmargin="3" marginheight="3" marginwidth="3">
<TABLE WIDTH="100%" CELLPADDING=10 CELLSPACING=0 BORDER=0>
<TR>

<TD class="tt2" bgcolor="#F5F8F8" width="84%"><center><B><FONT style="FONT-SIZE: 16.5pt" COLOR="#FF6666" FACE="楷体_GB2312">怎样建立简单的任务栏应用程序</FONT></B></center>
<hr color="#EE9B73" size="1" width="94%">
<p class="tt2"><span>Windows 95 和 Windows NT 4.0包含一个令人兴奋的特性:任务栏。这个通常位于区域任务条右面的区域能包含小的图标,这些图标能引出大的应用程序或者菜单。本篇文章主要讨论如何使用Delphi建立这样的应用程序。 
<br> 
&nbsp;&nbsp;&nbsp; 在开始之前,请看下面的需要的接口方面的内容: <br> 
&nbsp;&nbsp;&nbsp; 
从技术方面来说,一个任务栏应用程序非常象普通的应用程序,它有一个消息循环,相应Windows的消息来完成相应的功能。<br> 
Procedure RunTrayApplication;<br> 
Var Msg : TMsg;<br> 
Begin <br> 
&nbsp; CreateWindow;<br> 
&nbsp; AddTrayIcon; <br> 
&nbsp; While GetMessage(Msg,0,0,0) do <br> 
Begin &nbsp;<br> 
&nbsp;&nbsp; TranslateMessage(Msg);<br> 
&nbsp;&nbsp;&nbsp; DispatchMessage(Msg);<br> 
&nbsp; End; &nbsp; DeleteTrayIcon; <br> 
End; <br> 
<br> 
&nbsp;&nbsp;&nbsp; 
你能看到:所有需要做的工作是创建一个窗口,注册一个图标到任务栏,设置它的消息循环,最后关闭它。当然,必须还有增加其他代码完成相应的功能,但是,它是真的不需要担心。 
<br> 
&nbsp;&nbsp;&nbsp; 
让我们从窗口的创建开始。实际上,这个窗口是不是能在任务栏上能见到的窗口。相应的,这个窗口只是处理消息循环、其它父类的工作。任务窗口(Windows 
95 &amp; NT)句柄创建消息(例如鼠标单击等)和将消息发到我们的窗口。 
<br> 
<br> 
Procedure CreateWindow;<br> 
Var &nbsp; WC : TWndClass;<br> 
&nbsp; W&nbsp; : hWnd;<br> 
Begin <br> 
&nbsp; With WC do <br> 
Begin<br> 
&nbsp;&nbsp;&nbsp; Style := 0;<br> 
&nbsp;&nbsp;&nbsp; lpfnWndProc := @WndProc;<br> 
&nbsp;&nbsp;&nbsp; cbClsExtra := 0;<br> 
&nbsp;&nbsp;&nbsp; cbWndExtra := 0;<br> 
&nbsp;&nbsp;&nbsp; hIcon := 0;<br> 
&nbsp;&nbsp;&nbsp; hCursor := 0;<br> 
&nbsp;&nbsp;&nbsp; hbrBackground := 0;<br> 
&nbsp;&nbsp;&nbsp; lpszMenuName := nil;<br> 
&nbsp;&nbsp;&nbsp; lpszClassName := 'MyTrayIconClass';<br> 
&nbsp;&nbsp;&nbsp; hInstance := System.hInstance;<br> 
&nbsp; end;<br> 
&nbsp; RegisterClass(WC);<br> 
&nbsp; W := Windows.CreateWindow('MyTrayIconClass','MyVeryOwnTrayIconWindow', 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
ws_OverlappedWindow,0,0,0,0,0,0,hInstance,nil);<br> 
&nbsp; ShowWindow(W,sw_Hide);<br> 
&nbsp; UpdateWindow(W);<br> 
&nbsp; MainWindow := W;<br> 
End; <br> 
&nbsp;&nbsp;&nbsp; 
这个窗口使用普通的窗口函数创建。注意这个窗口的类型是“ws_OverlappedWindow”,但是这个尺寸是0,并且它是隐藏的,所有,它将不会显示出来。 
<br> 
&nbsp;&nbsp;&nbsp; 下一步是加(注册)我们的图标。这将需要使用Shell_NotifyIcon这个API函数,这个函数实际上可以完成三个功能,这里只需要它的增加的特性。 
</span></p> 
<p class="p2"><span>Procedure AddTrayIcon;<br> 
Var IconData : TNotifyIconData;<br> 
Begin<br> 
&nbsp; With IconData do<br> 
Begin<br> 
&nbsp;&nbsp;&nbsp; cbSize := SizeOf(IconData)<br> 
; &nbsp;&nbsp;&nbsp; Wnd := MainWindow;<br> 
&nbsp;&nbsp;&nbsp; uID := 0;<br> 
&nbsp;&nbsp;&nbsp; uFlags := nif_Icon Or nif_Message Or nif_Tip;<br> 
&nbsp;&nbsp;&nbsp; uCallBackMessage := wm_MyCallBack;<br> 
&nbsp;&nbsp;&nbsp; hIcon := LoadIcon(hInstance,'MYICON');<br> 
&nbsp;&nbsp;&nbsp; StrCopy(szTip,PChar(TrayIconTip));<br> 
&nbsp; End;<br> 
&nbsp; Shell_NotifyIcon(nim_Add,@IconData);<br> 
End; <br> 
<br> 
&nbsp;&nbsp;&nbsp; 这个最重要的事情是TNotifyIconData的数据结构,它是一个设置Window句柄的数据结构,是一个记录参数,对我们来说,我们需要设置这个图标的窗口句柄(这将定义哪个窗口处理消息循环),回调消息号,图标,工具提示等。一旦这个数据设置了,我们就可以增加一个图标到任务栏上了。为了完成这个工作,使用nim_Add程序。 
<br> 
&nbsp;&nbsp;&nbsp; 
现行我们已经加了我们的图标到任务栏,下面需要决定如何处理消息。 
<br> 
<br> 
Const &nbsp; wm_MyCallback = wm_User+1000;<br> 
&nbsp; cm_Exit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 100;<br> 
{ we worry about... }<br> 
&nbsp; cm_About&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 101;<br> 
{ ...these later&nbsp;&nbsp;&nbsp; } <br> 
<br> 
&nbsp;&nbsp; 这个实际的窗口处理过程也是相当普通。几个窗口消息(如wm_NCCreate)必须处理。然而,对我们来说,更重要的事情是处理wm_MyCallback和wm_Command消息: 
<br> 
<br> 
Function WndProc(Window : hWnd; Msg,WParam,LParam : Integer): Integer; StdCall;<br> 
Begin<br> 
&nbsp; Result := 0;<br> 
&nbsp; Case Msg of &nbsp;&nbsp;&nbsp; wm_NCCreate&nbsp;&nbsp; :<br> 
Result := 1;<br> 
&nbsp;&nbsp;&nbsp; wm_Destroy&nbsp;&nbsp;&nbsp; : PostQuitMessage(0);<br> 
&nbsp;&nbsp;&nbsp; wm_Command&nbsp;&nbsp;&nbsp; :<br> 
Begin { a command was chosen from the popup menu }<br> 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
If (WParam = cm_Exit) Then <br> 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
PostMessage(Window,wm_Destroy,0,0)<br> 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
Else If (WParam = cm_About) Then<br> 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
MessageBox(0,'Shell Test Copyright ?'+ 'Jani J鋜vinen 1996.', &nbsp; 'About Shell 
Test',mb_OK)<br> 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Else 
OpenDesktopIcon(WParam-cm_About);<br> 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
End;<br> 
&nbsp;&nbsp;&nbsp; wm_MyCallback : Begin { our icon was clicked } <br> 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
If (LParam = wm_LButtonDown) Then <br> 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
ShowIconPopupMenu<br> 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
Else If (LParam = wm_RButtonDown) Then<br> 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
ShowAboutPopupMenu;<br> 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
End;<br> 
&nbsp;&nbsp;&nbsp; Else<br> 
Result := DefWindowProc(Window,Msg,WParam,LParam);<br> 
&nbsp; End;<br> 
End; <br> 
<br> 
&nbsp;&nbsp;&nbsp; 就象你看到的一样,当用户单击图标时,Windows提示我们。注意我们不使用通常使用的wm_LButtonDown 
消息,而使用wm_MyCallback message,详细的消息信息存储在LParam参数中。 
<br> 
&nbsp;&nbsp;&nbsp; 当用户单击鼠标右键,我们创建一个菜单在桌面上。 <br> 
<br> 
Type &nbsp; TIconData = Array[1..100] of String;<br> 
Var &nbsp; IconData&nbsp;&nbsp; : TIconData;<br> 
Procedure ShowIconPopupMenu;<br> 
Var &nbsp; ShellFolder : IShellFolder;<br> 
&nbsp; EnumIDList&nbsp; : IEnumIDList;<br> 
&nbsp; Result&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : hResult;<br> 
&nbsp; Dummy&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : ULong;<br> 
&nbsp; ItemIDList&nbsp; : TItemIDList;<br> 
&nbsp; Pntr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : PItemIDList;<br> 
&nbsp; StrRet&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : TStrRet;<br> 
&nbsp; PopupMenu&nbsp;&nbsp; : hMenu;<br> 
&nbsp; ItemID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : Integer;<br> 
&nbsp; Pos&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : TPoint;<br> 
&nbsp; Procedure AddToMenu(Item : String);<br> 
&nbsp; Var S : String;<br> 
&nbsp; Begin<br> 
&nbsp;&nbsp;&nbsp; IconData[ItemID-cm_About] := Item;<br> 
&nbsp;&nbsp;&nbsp; S := ExtractFileName(Item);<br> 
&nbsp;&nbsp;&nbsp; If (System.Pos('.',S) &lt;&gt; 0) Then 
SetLength(S,System.Pos('.',S)-1);<br> 
&nbsp;&nbsp;&nbsp; AppendMenu(PopupMenu,mf_Enabled Or mf_String,ItemID,PChar(S));<br> 
&nbsp;&nbsp;&nbsp; Inc(ItemID);<br> 
&nbsp; End;<br> 
begin<br> 
&nbsp; PopupMenu := CreatePopupMenu;<br> 
&nbsp; ItemID := cm_About+1;<br> 
&nbsp; SHGetDesktopFolder(ShellFolder);<br> 
&nbsp; ShellFolder.EnumObjects(MainWindow,SHCONTF_NONFOLDERS,EnumIDList);<br> 
&nbsp; Pntr := @ItemIDList;<br> 
&nbsp; Result := EnumIDList.Next(1,Pntr,Dummy);<br> 
&nbsp; While (Result = NoError) do <br> 
Begin<br> 
&nbsp;&nbsp;&nbsp; ShellFolder.GetDisplayNameOf(Pntr,SHGDN_FORPARSING,@StrRet);<br> 
&nbsp;&nbsp;&nbsp; With StrRet do<br> 
AddToMenu(String(CStr));<br> 
&nbsp;&nbsp;&nbsp; Result := EnumIDList.Next(1,Pntr,Dummy);<br> 
&nbsp; End;<br> 
&nbsp; EnumIDList.Release;<br> 
&nbsp; ShellFolder.Release;<br> 
&nbsp; GetCursorPos(Pos); &nbsp; AppendMenu(PopupMenu,mf_Separator,0,'');<br> 
&nbsp; AppendMenu(PopupMenu,mf_Enabled Or mf_String,cm_Exit,'E&amp;xit'); &nbsp; <br> 
SetForegroundWindow(MainWindow);<br> 
&nbsp; TrackPopupMenu(PopupMenu,tpm_LeftAlign Or tpm_LeftButton, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
Pos.X,Pos.Y,0,MainWindow,nil);<br> 
&nbsp; DestroyMenu(PopupMenu);<br> 
end; </span></p> 
<p class="p2"> </p>
<p class="p2"><span>&nbsp;&nbsp;&nbsp; 
上面的程序看起来有点复杂,你可以将它分成两个部分来看:创建和显示菜单。 
</span></p> 
<p class="p2"><span>&nbsp;&nbsp;&nbsp; 列举创建菜单是用Windows的外壳接口完成的。首先,我们使用SHGetDesktopForlder函数得到使用桌面的IShellFolder接口。使用这个接口,我们能得到另一个接口的实例:IEnumIDList。这个接口通常实现实际的列举工作。我们简单的重复调用这个函数直到错误值返回(例如:所有的菜单被列举)。当我们得到一个菜单,我们使用AddToMenu函数加它。 
</span></p> 
<p class="p2"><span>&nbsp;&nbsp;&nbsp; 
当所有的菜单被列举和创建后,现在我们需要运行这个菜单。我们将找到的菜单保存到一个全局的List变量中,每一个菜单都拥有它的菜单号。这确保我们能得到它的索引。 
<br> 
<br> 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OpenDesktopIcon(WParam-cm_About) </span></p> 
<p class="p2"><span>当然,WParam中储存了用户单击鼠标的菜单的菜单号(ID)。 
</span></p> 
<p class="p2"><span>&nbsp;&nbsp;&nbsp; 下面我们将处理运行用户选择的菜单。 
</span></p> 
<p class="p2"><span>Procedure OpenDesktopIcon(Number : Integer);<br> 
Var &nbsp; S : String;<br> 
&nbsp; I : Integer;<br> 
begin<br> 
&nbsp; S := IconData[Number];<br> 
&nbsp; I := ShellExecute(0,nil,PChar(S),nil,nil,sw_ShowNormal);<br> 
&nbsp; If (I &lt; 32) Then<br> 
Begin<br> 
&nbsp;&nbsp;&nbsp; S := 'Could not open selected item &quot;'+S+'&quot;. '+ 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'Result was: '+IntToStr(I)+'.';<br> 
&nbsp;&nbsp;&nbsp; MessageBox(0,PChar(S),'Shell Test',mb_OK);<br> 
&nbsp; End;<br> 
end; <br> 
<br> 
&nbsp;&nbsp;&nbsp; 上面,Win 32 API函数ShellExecute做了所有的工作。 </span></p> 
<p class="p2"><span>&nbsp;&nbsp;&nbsp; 现在你应该能用Delphi创建简单的任务栏的程序了。 
<br> 
<br> 
&nbsp;&nbsp;&nbsp; 
实际上,有一些免费的元件可以供您直接使用,不过,因为使用VCL,文件的大小将比较大,如果使用上面的方法,文件的大小将只要20K。当然,现在文件的大小已经不是我们该十分关注的问题了</span></p> 
<hr color="#EE9B73" size="1" width="94%"> 
 
</TD> 
 
</TR> 
</table> 
</BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -