如何获取任务栏程序的图标?
解决方案 »
- 如何根据一个窗体的某个字段值,查询数据库并在另一窗体中显示呢
- 下岗了,郁闷中
- 小妹初来乍到,请各位师哥门多多指教,问一个简单问题!!
- Mediaplayer
- 请问能不能把字库文件打包到资源文件里面???怎么搞啊…… ??
- 大开帖散分:合同续约,加薪四位数……
- Socket编程,在运行过程,会出现Asynchronous Socket Error 10053?错误怎么处理
- 如何打印整个窗体?
- 怎样显式地建立tdatabase和tquery的绑定?
- 函数定义部分
- pos58打印循环的问题
- 请问:那位有多种格式文件的浏览控件,能够提供多种格式文件的浏览控件的下载地址,如PDF、CAD、JPG,BMP等文件的浏览控件。
然后调用InstTrayIcon方法就行了
ProcedureRunTrayApplication;
VarMsg:TMsg;
BeginCreateWindow;
AddTrayIcon;
WhileGetMessage(Msg000)doBeginTranslateMessage(Msg);
DispatchMessage(Msg);
End;
DeleteTrayIcon;
End;
你能看到:所有需要做的工作是创建一个窗口,注册一个图标到任务栏,设置它的消息循环,最后关闭它。当然,必须还有增加其他代码完成相应的功能,但是,它是真的不需要担心。让我们从窗口的创建开始。实际上,这个窗口是不是能在任务栏上能见到的窗口。相应的,这个窗口只是处理消息循环、其它父类的工作。任务窗口(Windows95&NT)句柄创建消息(例如鼠标单击等)和将消息发到我们的窗口。
ProcedureCreateWindow;
VarWC:TWndClass;
W:hWnd;
BeginWithWCdoBeginStyle:=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_OverlappedWindow000000hInstancenil);
ShowWindow(Wsw_Hide);
UpdateWindow(W);
MainWindow:=W;
End;
这个窗口使用普通的窗口函数创建。注意这个窗口的类型是“ws_OverlappedWindow”,但是这个尺寸是0,并且它是隐藏的,所有,它将不会显示出来。
下一步是加(注册)我们的图标。这将需要使用Shell_NotifyIcon这个API函数,这个函数实际上可以完成三个功能,这里只需要它的增加的特性。
ProcedureAddTrayIcon;
VarIconData:TNotifyIconData;
BeginWithIconDatadoBegincbSize:=SizeOf(IconData);
Wnd:=MainWindow;
uID:=0;
uFlags:=nif_IconOrnif_MessageOrnif_Tip;
uCallBackMessage:=wm_MyCallBack;
hIcon:=LoadIcon(hInstance'MYICON');
StrCopy(szTipPChar(TrayIconTip));
End;
Shell_NotifyIcon(nim_Add@IconData);
End;
这个最重要的事情是TNotifyIconData的数据结构,它是一个设置Window句柄的数据结构,是一个记录参数,对我们来说,我们需要设置这个图标的窗口句柄(这将定义哪个窗口处理消息循环),回调消息号,图标,工具提示等。一旦这个数据设置了,我们就可以增加一个图标到任务栏上了。为了完成这个工作,使用nim_Add程序。
现行我们已经加了我们的图标到任务栏,下面需要决定如何处理消息。
Constwm_MyCallback=wm_User+1000;
cm_Exit=100;{weworryabout...}
cm_About=101;{...theselater}
这个实际的窗口处理过程也是相当普通。几个窗口消息(如wm_NCCreate)必须处理。
然而,对我们来说,更重要的事情是处理wm_MyCallback和wm_Command消息:FunctionWndProc(Window:hWnd;MsgWParamLParam:Integer):Integer;StdCall;
BeginResult:=0;
CaseMsgofwm_NCCreate:Result:=1;
wm_Destroy:PostQuitMessage(0);
wm_Command:Begin{acommandwaschosenfromthepopupmenu}
If(WParam=cm_Exit)ThenPostMessage(Windowwm_Destroy00)
ElseIf(WParam=cm_About)ThenMessageBox(0'ShellTestCopyright?'+
'JaniJ鋜vinen1996.'
'AboutShellTest'
mb_OK)
ElseOpenDesktopIcon(WParam-cm_About);
End;
wm_MyCallback:Begin{ouriconwasclicked}
If(LParam=wm_LButtonDown)ThenShowIconPopupMenuElseIf(LParam=wm_RButtonDown)ThenShowAboutPopupMenu;
End;
ElseResult:=DefWindowProc(WindowMsgWParamLParam);
End;
End;
就象你看到的一样,当用户单击图标时,Windows提示我们。注意我们不使用通常使用的wm_LButtonDown消息,而使用wm_MyCallbackmessage,详细的消息信息存储在LParam参数中。当用户单击鼠标右键,我们创建一个菜单在桌面上。
TypeTIconData=Array[1..100]ofString;
VarIconData:TIconData;
ProcedureShowIconPopupMenu;
VarShellFolder:IShellFolder;
EnumIDList:IEnumIDList;
Result:hResult;
Dummy:ULong;
ItemIDList:TItemIDList;
Pntr:PItemIDList;
StrRet:TStrRet;
PopupMenu:hMenu;
ItemID:Integer;
Pos:TPoint;
ProcedureAddToMenu(Item:String);
VarS:String;
BeginIconData[ItemID-cm_About]:=Item;
S:=ExtractFileName(Item);
If(System.Pos('.'
S)<>0)ThenSetLength(SSystem.Pos('.'
S)-1);
AppendMenu(PopupMenumf_EnabledOrmf_StringItemIDPChar(S));
Inc(ItemID);
End;
beginPopupMenu:=CreatePopupMenu;
ItemID:=cm_About+1;
SHGetDesktopFolder(ShellFolder);
ShellFolder.EnumObjects(MainWindowSHCONTF_NONFOLDERSEnumIDList);
Pntr:=@ItemIDList;
Result:=EnumIDList.Next(1PntrDummy);
While(Result=NoError)doBeginShellFolder.GetDisplayNameOf(PntrSHGDN_FORPARSING@StrRet);
WithStrRetdoAddToMenu(String(CStr));
Result:=EnumIDList.Next(1PntrDummy);
End;
EnumIDList.Release;
ShellFolder.Release;
GetCursorPos(Pos);
AppendMenu(PopupMenumf_Separator0'');
AppendMenu(PopupMenumf_EnabledOrmf_Stringcm_Exit'E&xit');
SetForegroundWindow(MainWindow);
TrackPopupMenu(PopupMenutpm_LeftAlignOrtpm_LeftButtonPos.XPos.Y0MainWindownil);
DestroyMenu(PopupMenu);
end;
上面的程序看起来有点复杂,你可以将它分成两个部分来看:创建和显示菜单。
列举创建菜单是用Windows的外壳接口完成的。首先,我们使用SHGetDesktopForlder函数得到使用桌面的IShellFolder接口。使用这个接口,我们能得到另一个接口的实例:IEnumIDList。这个接口通常实现实际的列举工作。我们简单的重复调用这个函数直到错误值返回(例如:所有的菜单被列举)。当我们得到一个菜单,我们使用AddToMenu函数加它。
当所有的菜单被列举和创建后,现在我们需要运行这个菜单。我们将找到的菜单保存到一个全局的List变量中,每一个菜单都拥有它的菜单号。这确保我们能得到它的索引。
OpenDesktopIcon(WParam-cm_About)
当然,WParam中储存了用户单击鼠标的菜单的菜单号(ID)。
下面我们将处理运行用户选择的菜单。
ProcedureOpenDesktopIcon(Number:Integer);
VarS:String;
I:Integer;
beginS:=IconData[Number];
I:=ShellExecute(0nilPChar(S)
nilnilsw_ShowNormal);
If(I<32)ThenBeginS:='Couldnotopenselecteditem"'+S+'".'+
'Resultwas:'+IntToStr(I)+'.';
MessageBox(0PChar(S)
'ShellTest'
mb_OK);
End;
end;
上面,Win32API函数ShellExecute做了所有的工作。
现在你应该能用Delphi创建简单的任务栏的程序了。
实际上,有一些免费的元件可以供您直接使用,不过,因为使用VCL,文件的大小将比较大,如果使用上面的方法,文件的大小将只要20K。当然,现在文件的大小已经不是我们该十分关注的问题了。