如何用DELPHI实现程序最小化时缩在任务栏右边,就像OICQ、金山词霸一样? ?关于tray编程,delphi自带一个例子,可以看看啊 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 WINSHELLAPI BOOL WINAPI Shell_NotifyIcon( DWORD dwMessage, // message identifier PNOTIFYICONDATA pnid // pointer to structure );先看帮助,剩下的不会再问。 贴上一篇:==============================================在开始之前,请看下面的需要的接口方面的内容: 从技术方面来说,一个任务栏应用程序非常象普通的应用程序,它有一个消息循环,相应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 :=di2001.jpg; 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创建简单的任务栏的程序了。 我这里有控件,如果需要 my email: [email protected]. tell me u Emailpost a letter 怎么这个函数老是报错.我看了一晚还是看出不问题,哈哈,哪个来帮帮我.. 再线提问:在下是菜鸟,请问各位高手:抢先windows登陆都需调用那些api? 我想写一个程序,请帮忙解决里面的几个小问题? ado控件哪些比较常用,与传统的ado对象比较,使用哪些比较好。 有没DELPHI FORM DESIGNER方面的资料? 关于SQL关键字的问题?今天高兴,同时也散分,希望大家赏脸:) 初学者提问 各位老师帮帮我 DateTimePicker里可以同时显示日期和时间吗? DBGrid多层标题如何设置? 如何在Delphi的报表里打印1/4形式的页数? 如何保存源程序。 高难问题
PNOTIFYICONDATA pnid // pointer to structure
);
先看帮助,剩下的不会再问。
==============================================
在开始之前,请看下面的需要的接口方面的内容: 从技术方面来说,一个任务栏应用程序非常象普通的应用程序,它有一个消息循环,相应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 :=di2001.jpg;
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创建简单的任务栏的程序了。
post a letter