📄 状态指示的编成.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0049)http://go5.163.com/_NTES/~ssudi/doc/common/1.html -->
<HTML><HEAD><TITLE>Delphi编程参考--编程文章</TITLE>
<META content=zh-cn http-equiv=Content-Language>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<META content=FrontPage.Editor.Document name=ProgId>
<META content=ou,delphi,weather,borland,inprise,asp,files,component,sample,编程
name=keywords>
<STYLE type=text/css>.unnamed1 {
COLOR: #ffffff; FONT-SIZE: 11pt; PADDING-TOP: 5px; TEXT-ALIGN: center
}
.f1 {
COLOR: #000000; FONT-SIZE: 11pt
}
.f2 {
COLOR: #0f0fff; FONT-SIZE: 9pt
}
.f3 {
COLOR: #000000; FONT-SIZE: 9pt
}
.f4 {
COLOR: #ff1f00; FONT-SIZE: 9pt; FONT-WEIGHT: bold
}
.f5 {
COLOR: #0f0fff; FONT-SIZE: 9pt
}
A:link {
COLOR: #333333; TEXT-DECORATION: none
}
A:visited {
COLOR: #333333; TEXT-DECORATION: none
}
A:hover {
COLOR: #ff2111; TEXT-DECORATION: none
}
</STYLE>
<META content="MSHTML 5.00.2919.6307" name=GENERATOR></HEAD>
<BODY bgColor=#ffffec leftMargin=2 topMargin=2>
<CENTER>
<TABLE bgColor=#ecbe8c border=1 borderColor=#804000 cellPadding=0 cellSpacing=0
height=478 width="80%">
<TBODY>
<TR>
<TD bgColor=#f7b573 height=31 vAlign=center width="100%">
<P align=center>DELPHI状态指示区的编程</P></TD></TR>
<TR>
<TD bgColor=#f9daac height=435 vAlign=top width="100%">
Windows
95作为Windows家族的一个里程碑,不仅增加了系统的稳定性,更在易用性上下了很大的功夫。其中任务栏的引入可以说是易用性方面的典范。系统运行的每一个应用程序都在任务栏的任务切换区有对应的按钮,用户可以简便、快捷地在应用程序间切换。通过任务栏的状态指示区,用户可以很方便地到当前系统时间,调节声音大小,切换输入法等。Windows
95也允许应用程序在状态指示区上放置图标,以指示应用程序目前的状态,或者提醒用户某个事件的发生。现在,越来越多的应用程序,如拨号软件、网络监视软件、杀毒软件、字典等都把自己的图标加到状态指示区上。在大家享受如此方便快捷的服务的同时,作为程序员则更加关注此功能的实现方法,以使自己的产品立于不败之地。 <BR><BR>
针对这个问题,我查阅了大量的技术资料及Delphi
3.0所带的源代码,成功地解决了它。以下是对这个问题分析及解决它的三个步骤。 <BR><BR>1.在状态指示区上安装、更改、卸载图标 <BR><BR>
Windows
95是基于事件驱动机制的操作系统。任何一个控件都是通过发消息或对系统消息的处理来实现功能的。状态指示区实际上也是一个标准控件。对它的控制和操纵,与其他的标准控件一样,也是通过发消息和处理消息进行的。应用程序通过系统功能调用Shell_NotifyIcon向状态指示区发消息,它的函数说明如下(摘自Delphi的Source\RTL\WIN\shellapi.pas文件): <BR>function
Shell_NotifyIcon(dwMessage: DWORD; lpData: PNotifyIconData): BOOL;
stdcall; <BR><BR>其中: <BR><BR>dwMessage:要发给状态指示区的消息,可以取以下三个值: <BR>NIM_ADD
在状态指示区上增加一个图标 <BR>NIM_MODIFY 修改一个状态指示区的图标 <BR>NIM_DELETE
删除状态指示区的一个图标 <BR>lpData:指向TNotifyIconDataA结构的指针,此结构是要增加的图标的信息。 <BR>PNotifyIconData
= ^TNotifyIconDataA <BR>TNotifyIconDataA = record <BR>cbSize :
DWORD; <BR>Wnd : HWND; <BR>uID : UINT; <BR>uFlags :
UINT; <BR>uCallbackMessage : UINT; <BR>hIcon :
HICON; <BR>szTip : array [0..63] of
AnsiChar; <BR>end; <BR><BR>各字段的含义如下所述: <BR><BR>cbSize:记录TNotifyIconDataA的大小,设置为SizeOf(
TNotifyIconDataA); <BR>Wnd:接收状态指示区鼠标事件的窗口的句柄,例如:Form1.Handle; <BR>uID:图标的ID(状态指示区鼠标事件的wPara参数的值); <BR>uFlags:此条消息的有效范围(低三位有效) <BR>NIF_MESSAGE
0x1 // uCallbackMessage参数有效 <BR>NIF_ICON 0x2 // hIcon is
valid参数有效 <BR>NIF_TIP 0x4 // szTip is
valid参数有效 <BR>uCallbackMessage:系统回送消息的ID; <BR>hIcon:显示在状态指示区上的图标的句柄; <BR>szTip:鼠标移动到图标上时系统显示的提示信息。 <BR><BR>
在安装图标时,需要对结构的每一个字段都赋值。而当更改、卸载图标时,则有些字段可以不赋值。当更改图标信息时,除设置需要更改的内容外,要把cbSize,Wnd,uID设置成正确的值,还要按照更改的内容将uFlags调到的相应的位置。例如,只更改图标的提示信息时,把cbSize,Wnd,uID设置为正确的值,szTip赋值为要更改成的提示信息,uFlags赋值为4即可。需要删除图标时,只需要把cbSize,Wnd,uID设置成正确的值即可。 <BR><BR>2.对状态指示区上图标鼠标事件的响应 <BR><BR>
现在,我们已经在状态指示区上安装了自己的图标,但它并不产生任何实际效果。因为当应用程序接收到鼠标事件后,除了可以显示提示信息外,没有产生任何动作。我们现在要做的就是要响应图标上的鼠标事件。 <BR><BR>当用户在你的图标上移动、点击时,状态指示区会向应用程序发送如下的消息: <BR><BR>messageID
= uCallbackMessage <BR>wParam = uID <BR>lParam = mouse event
(如:WM_LBUTTONDOWN) <BR><BR>我们只需在主窗口的定义中,声明一个过程,来响应这个消息,在它的实现部分就可以对消息进行处理了。 <BR><BR>3.隐藏任务切换区的应用程序按钮 <BR>
完成了上面这些工作以后,我们已经可以在状态指示区成功地安装上图标,而且也可以响应图标上的事件了。美中不足的是,在状态指示区显示应用程序图标的同时,任务切换区也存在此应用程序的按钮,怎么让它不出现在任务切换区上呢?这里又要提到一个系统调用ShowWindow,它的说明如下(摘自Delphi的Source\RTL\WIN\
windows.pas文件): <BR><BR>function ShowWindow(hWnd: HWND; nCmdShow:
Integer): BOOL;
stdcall; <BR>其中: <BR>hWnd:要改变显示状态的窗口的句柄; <BR>nCmdShow:窗口要改变成为的显示状态: <BR>SW_HIDE
隐藏本窗口,激活另一个窗口 <BR>SW_SHOW
激活本窗口 <BR><BR>当一个应用程序的所有窗口都隐藏时,它的任务按钮就不显示。在用户选取状态指示区的图标时,再让某一个窗口激活就可以了。 <BR><BR>4.
样例 <BR><BR>
下面是我在研究过程中做的一个小例子。它运行时在状态指示区上安装一个图标。此图标共有两个运行状态:激活状态和非激活状态。在激活状态下,状态显示区显示一个“笑脸”图标;非激活状态显示一个“哭脸”图标。用户右击此图标,则弹出一个菜单,选取“激活”菜单项时,将切换运行状态,状态指示区的图标也做相应的变化。选取“关闭”菜单项时,卸载状态指示区的图标。 <BR><BR>unit
Utest; <BR>interface <BR>uses <BR>Windows, Messages,
SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Menus,
shellapi, StdCtrls; <BR>const <BR>ICON_ID = 1; //
图标在本应用程序中的编号 <BR>MI_ICONEVENT = WM_USER + 1; //
图标上的鼠标事件 <BR>type <BR>TForm1 = class(TForm) <BR>pop1:
TPopupMenu; // 在图标上右点鼠标时弹出的菜单 <BR>status1: TMenuItem; //
pop1菜单的第一项,选取它会改变程序的状态 <BR>N1: TMenuItem; <BR>close1: TMenuItem;
// pop1菜单的最后一项,它会关闭此应用程序 <BR>procedure FormCreate(Sender:
TObject); <BR>procedure FormClose(Sender: TObject; var Action:
TCloseAction); <BR>procedure close1Click(Sender:
TObject); <BR>procedure status1Click(Sender:
TObject); <BR>private <BR>normalicon, disabledicon: TIcon;
//需放在状态指示区的图标 <BR>status: Boolean; <BR>procedure InstallIcon;
//在状态指示区上安装图标 <BR>procedure
ChangeIcon(status:Boolean);//根据参数,显示不同的图标 <BR>procedure
UnInstallIcon; //卸载图标 <BR>procedure IconOnClick(var message:
TMessage); message MI_ICONEVENT;
//响应图标上的鼠标事件 <BR>end; <BR>var <BR>Form1:
TForm1; <BR>implementation <BR>{$R *.DFM} <BR>procedure
TForm1.FormCreate(Sender:
TObject); <BR>begin <BR>InstallIcon; <BR>ChangeIcon(False
); <BR>ShowWindow(Application.Handle, SW_HIDE );
//隐藏应用程序主窗口机 <BR>end; <BR>procedure
TForm1.InstallIcon; <BR>var IconData:
TNotifyIconData; <BR>begin <BR>normalicon :=
TIcon.Create; <BR>disabledicon :=
TIcon.Create; <BR>normalicon.LoadFromFile( 'normal.ico'
); <BR>disabledicon.LoadFromFile( 'disable.ico'
); <BR>IconData.cbSize := SizeOf( IconData ); <BR>IconData.Wnd
:= Handle; <BR>IconData.uID := ICON_ID; <BR>IconData.uFlags :=
NIF_ICON or NIF_MESSAGE or NIF_TIP; <BR>IconData.uCallBackMessage :=
MI_ICONEVENT; <BR>IconData.hIcon :=
normalicon.Handle; <BR>IconData.szTip :=
'我可以在状态指示区上加图标了!'; <BR>Shell_NotifyIcon( NIM_ADD, @IconData
); <BR>end; <BR>procedure TForm1.ChangeIcon( status: boolean
); <BR>var IconData:
TNotifyIconData; <BR>begin <BR>IconData.cbSize :=
SizeOf(IconData); <BR>IconData.wnd := Handle; <BR>IconData.uID
:= ICON_ID; <BR>if IconData.fconectado then IconData.hIcon :=
normalicon.Handle else IconData.hIcon :=
disabledIcon.Handle; <BR>IconData.uFlags :=
NIF_ICON; <BR>Shell_NotifyIcon(NIM_MODIFY,
@IconData); <BR>end; <BR>procedure
TForm1.UnInstallIcon; <BR>var IconData:
TNotifyIconData; <BR>begin <BR>IconData.cbSize := SizeOf(
IconData ); <BR>IconData.Wnd := Handle; <BR>IconData.uID :=
ICON_ID; <BR>Shell_NotifyIcon( NIM_DELETE, @IconData
); <BR>end; <BR>procedure TForm1.IconOnClick( var message:
Tmessage); <BR>var p : TPoint; <BR>begin <BR>if
(message.lParam = WM_LBUTTONDOWN) then <BR>ShowWindow(
Application.Handle, SW_SHOW ); <BR>if (message.lParam =
WM_RBUTTONDOWN) then begin <BR>GetCursorPos( p
); <BR>pop1.Popup( p.x ,p.y ); <BR>ChangeIcon( status
); <BR>end; <BR>end; <BR>procedure TForm1.FormClose(Sender:
TObject; var Action:
TCloseAction); <BR>begin <BR>UnInstallIcon; <BR>normalicon.Free; <BR>disabledicon.Free; <BR>end; <BR>procedure
TForm1.FormActivate(Sender: TObject); <BR>begin <BR>ShowWindow(
Application.Handle, SW_HIDE ); <BR>end; <BR>procedure
TForm1.close1Click(Sender:
TObject); <BR>begin <BR>Close; <BR>end; <BR>procedure
TForm1.status1Click(Sender: TObject); <BR>begin <BR>status :=
not status; <BR>if status then status1.Caption :=
'Enable' <BR>else status1.Caption :=
'Disable'; <BR>end; <BR>end. <BR></TD></TR></TBODY></TABLE></CENTER>
<P align=center>
<HR>
<P align=center><I><FONT color=#808000>学勇的Delphi情缘</FONT></I><BR><BR><A
href="mailto:lsscxy@sohu.com">lsscxy@sohu.com</A></P></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -