如何真正的用Api函数实现任务栏的自动隐藏?(50分)

  • 主题发起人 主题发起人 elton
  • 开始时间 开始时间
E

elton

Unregistered / Unconfirmed
GUEST, unregistred user!
注意,是实现任务栏的自动隐藏,先前看了不少人的做法,基本上对此做不了太多的解释,<br>大多数只是找到任务栏的句柄,然后用ShowWindow()来实现隐藏和显示,并不是真正的实现<br>自动隐藏,还有,是否能通过编程把任务栏的‘总是在前’选项也撤掉,希望大家好好讨论,<br>来对这个问题作个总结,希望以后不再有类似的问题出现,谢谢大家!
 
怎么没有人关注啊?
 
应该是SHAppBarMessage里面的ABM_SETAUTOHIDEBAR,刚才试验了一下,没有成功,不过应该不难。
 
简单的思路:<br>RECT rect1/*桌面大小*/, rect2/*桌面工作区*/;<br>1、先获取桌面大小和桌面工作区大小<br>GetWindowRect(GetDesktopWindow(), &amp;rect1);<br>SystemParametersInfo(SPI_GETWORKAREA, 0, &amp;rect2, SPIF_SENDCHANGE);<br>2、改变桌面工作区大小到桌面大小,并将你的窗口推到前台<br>SystemParametersInfo(SPI_SETWORKAREA, 0, &amp;rect1, SPIF_SENDCHANGE);<br>SetWindowPos(Form1-&gt;Handle, HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);<br><br>注:<br>SPIF_SENDCHANGE参数广播WM_WININICHANGE消息。<br>如要保留变化,请使用SPIF_UPDATEINIFILE参数。<br><br>3、取消隐藏只须恢复工作区大小即可。<br><br>为了方便我用C写的,<br>另外使用SHELL函数也可实现,请参阅MSDN关于SHELL的帮助。
 
to yzhshi:调用ShellApi函数我已经试过很多次了,都不成功,希望你能够测试一下,以前的<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 贴子也有类似的问题:<br><br>to yyii_yyii:你的方法的思路是很好的, 不过你最好有成功的实例,因为我也试过这种方法,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 请你给出源代码,谢谢!<br><br>我的e_mail:zyongzhi@vip.sina.com
 
源码如下:<br><br>#include &lt;vcl.h&gt;<br>#pragma hdrstop<br>#include "Unit1.h"<br>#pragma package(smart_init)<br>#pragma resource "*.dfm"<br>TForm1 *Form1;<br>RECT rect1, rect2;<br><br>__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)<br>{<br>&nbsp; /*获取系统信息*/<br>&nbsp; GetWindowRect(GetDesktopWindow(), &amp;rect1);<br>&nbsp; SystemParametersInfo(SPI_GETWORKAREA, 0, &amp;rect2, SPIF_SENDCHANGE);<br>}<br><br>void __fastcall TForm1::Button1Click(TObject *Sender)<br>{<br>&nbsp; /*设置自定义信息*/<br>&nbsp; SystemParametersInfo(SPI_SETWORKAREA, 0, &amp;rect1, SPIF_SENDCHANGE);<br>&nbsp; SetWindowPos(Form1-&gt;Handle, HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);<br>}<br><br>void __fastcall TForm1::Button2Click(TObject *Sender)<br>{<br>&nbsp; /*恢复系统原始设定*/<br>&nbsp; SystemParametersInfo(SPI_SETWORKAREA, 0, &amp;rect2, SPIF_SENDCHANGE);<br>&nbsp; SetWindowPos(Form1-&gt;Handle, HWND_NOTOPMOST,0,0,rect2.right,rect2.bottom,SWP_NOZORDER);<br>}
 
写一下刚才的探索结果吧。<br>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/messages/abm_setstate.asp<br>有这样的说明:<br><br>ABM_SETSTATE Message<br>Sets the autohide and always-on-top states of the Microsoft&amp;reg; Windows&amp;reg; taskbar.<br><br>Syntax<br><br>SHAppBarMessage(ABM_SETSTATE, pabd); <br>Parameters<br><br>pabd<br>Pointer to an APPBARDATA structure. You must specify the cbSize and hWnd members when sending this message. Data for the desired state is sent in the lParam member using one of the following values.<br>0<br>Autohide and always-on-top both off<br>ABS_ALWAYSONTOP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Always-on-top on, autohide off<br>ABS_AUTOHIDE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Autohide on, always-on-top off<br>ABS_AUTOHIDE | ABS_ALWAYSONTOP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Autohide and always-on-top both on<br><br>-----------------------------------------------------------------------------<br>uses<br>&nbsp; Shellapi;<br><br>const<br>&nbsp; ABM_SETSTATE = $0000000A;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; pabd: TAPPBARDATA;<br>begin<br>&nbsp; pabd.cbSize := SizeOf(pabd);<br>&nbsp; pabd.hWnd := FindWindow('Shell_TrayWnd', nil);<br>// &nbsp;SHAppBarMessage(ABM_GETSTATE, pabd);<br>&nbsp; pabd.lParam := ABS_AUTOHIDE or ABS_ALWAYSONTOP;<br>&nbsp; SHAppBarMessage(ABM_SETSTATE, pabd);<br>end;<br>按道理说上面的结果应该可以了,但是只能使用Getstate取得信息,但是SetState在我这里没有成功。98/2000均不可以。<br>郁闷。。。
 
to yzhshi:<br>你可能没注意Taskbar Display Options中有这样一句话<br>The taskbar supports two display options: Auto Hide and Always On Top.<br>To set these options, the user must open the taskbar shortcut menu, <br>click Properties, and select or clear the Auto Hide check box or <br>the Always On Top check box. <br>There is no way to set these options programmatically. <br><br>请注意最后一句,呵呵。
 
上面的意思其实就是说可以设置自己的<br>用SHAppBarMessage(ABM_NEW, pabd)创建的TaskBar(或称作AppBar,有时也叫Desktop bar);<br>而不能设置系统的,而自己的也不能和系统的bar放在屏幕上相同的Edge(边)上。
 
没找到这句话呀。在msdn的那个连接里面呀?<br>不过masn中将系统的任务栏成为taskbar,将自己创建的叫做appbar。<br>而上面的ABM_SETSTATE就是针对Taskbar的呀。<br>还有,这个参数在Delphi5、Delphi7中均没有定义,在VC6中也没有声明。我是在VC.net的库中找到的宏定义的。
 
在Intermediate Shell Techniques下。<br>所有定义如下<br><br>//// AppBar stuff<br>#define ABM_NEW &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0x00000000<br>#define ABM_REMOVE &nbsp; &nbsp; &nbsp; &nbsp;0x00000001<br>#define ABM_QUERYPOS &nbsp; &nbsp; &nbsp;0x00000002<br>#define ABM_SETPOS &nbsp; &nbsp; &nbsp; &nbsp;0x00000003<br>#define ABM_GETSTATE &nbsp; &nbsp; &nbsp;0x00000004<br>#define ABM_GETTASKBARPOS 0x00000005<br>#define ABM_ACTIVATE &nbsp; &nbsp; &nbsp;0x00000006 &nbsp;// lParam == TRUE/FALSE means activate/deactivate<br>#define ABM_GETAUTOHIDEBAR 0x00000007<br>#define ABM_SETAUTOHIDEBAR 0x00000008 &nbsp;// this can fail at any time. &nbsp;MUST check the result<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // lParam = TRUE/FALSE &nbsp;Set/Unset<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // uEdge = what edge<br>#define ABM_WINDOWPOSCHANGED 0x0000009<br>#define ABM_SETSTATE &nbsp; &nbsp; &nbsp;0x0000000a<br><br>// these are put in the wparam of callback messages<br>#define ABN_STATECHANGE &nbsp; &nbsp;0x0000000<br>#define ABN_POSCHANGED &nbsp; &nbsp; 0x0000001<br>#define ABN_FULLSCREENAPP &nbsp;0x0000002<br>#define ABN_WINDOWARRANGE &nbsp;0x0000003 // lParam == TRUE means hide<br><br>// flags for get state<br>#define ABS_AUTOHIDE &nbsp; &nbsp;0x0000001<br>#define ABS_ALWAYSONTOP 0x0000002<br><br>#define ABE_LEFT &nbsp; &nbsp; &nbsp; &nbsp;0<br>#define ABE_TOP &nbsp; &nbsp; &nbsp; &nbsp; 1<br>#define ABE_RIGHT &nbsp; &nbsp; &nbsp; 2<br>#define ABE_BOTTOM &nbsp; &nbsp; &nbsp;3<br><br>如borland无定义,直接用值就可
 
to yyii_yyii:<br>总之,我觉得可能是用程序解决不了的,我还有一个思路,请大家讨论一下:在FormCreat事件<br>中用FindWindows函数找到任务栏句柄,然后,Hide it;在FormClose事件中Show it.<br>但是,如果程序意外终止,那么任务栏就彻底隐藏了,那可对用户太残酷了:)!所以,<br>yzhshi的办法可以尝试,不过是不是和我所说的方法有相同的问题呢?<br>
 
是不是可以用程序动态修改注册表实现自动隐藏,请大家多多关注!<br><br>请给出具体方法!
 
后退
顶部