如何作到taskbar的效果(150分)

  • 主题发起人 主题发起人 DNChen
  • 开始时间 开始时间
AppBar和Dock是不同的,还要不要我翻译?<br>或者我直接把英文版的东西贴在这里?
 
请继续翻译,谢谢,我英文很烂,*^_^*
 
To DNChen : 我看到pegasu 做的那么辛苦, 先打点预付款吧. :)
 
Appbar 事件通知消息:<br>当有会影响AppBar的位置和外观的事件发生的时候,系统会给AppBar发送消息,消息是通过<br>应用程序自定义的消息发送的。当应用程序注册AppBar的时候填写了通知消息的ID, 系统的通<br>知消息就用那个ID发给应用程序,通知的具体内容是用wParam参数给出的<br><br>AppBar在下列情况发生的时候会收到系统发来的 ABN_POSCHANGED 通知消息:<br>1.当任务栏的大小,位置或者可视状态变化的时候<br>2.当别的AppBar被增加到同一边的时候<br>3.当同一边的AppBar被移动或者删除了的时候<br>AppBar必须再次用ABM_QUERYPOS 和 ABM_SETPOS向系统确认自己的新的大小和位置,如果<br>允许发生变化的话,再次用MoveWindow把自己移动到被确认的位置上去<br><br>当任务栏的"自动隐藏"("Auto hide")或者"总在最前面"("Always on top")状态变化了的时候, 系统<br>会给AppBar发送 ABN_STATECHANGE 通知消息<br><br>当一个全屏幕运行的程序启动或者最后一个全屏幕运行的程序结束的时候,系统会给AppBar<br>应用程序发送 ABN_FULLSCREENAPP 通知消息. 消息的 lParam 指出了应用程序启动或者结束.<br>如果是应用程序启动,AppBar应该把自己的窗口显示顺序(Z-Order)设置为最底层. 当最后一个<br>全屏幕运行的程序结束的时候,AppBar应当恢复原先的显示顺序.<br><br>当用户选择了任务栏的"层叠窗口"("Cascade"), "水平平铺窗口"("Tile Horizontally"), 或者"垂直<br>平铺窗口"("Tile Vertically")的时候,系统会给AppBar应用程序发送 ABN_WINDOWARRANGE <br>通知消息. 通知消息会发送两次:第一次在重排列窗口之前,消息的lParam参数为True(非0值);<br>第二次在重排列窗口完成之后,消息的lParam参数为False(0).<br>AppBar自己可以要求任务栏不要重新排列自己的窗口. 只要在lParam为True的时候把自己的窗<br>口隐藏起来,lParam为False的时候再显示出来就行了. 如果AppBar这样做了,那么就不需要<br>向系统发送ABM_QUERYPOS 和 ABM_SETPOS AppBar 消息.<br><br>一些例子程序如下,(未完待续,等我下了版之后晚上在Delphi4上面调试通过再给大家,免得<br>再犯错误,:)
 
To Nuke:<br>您的要求恐怕办不到,除非您截获别的程序发送到系统的TaskBar消息
 
to DNChen,我可没有电子版的书
 
seasky,我没有办法给予付啊,否则就给了。<br><br>pegasus做的真的很辛苦啊,呵呵,我看看情况,如果这点分数不够,我再加
 
Xixi, 我的分够多的啦!不用再加了。。<br><br>晚上贴出剩下的3小段程序。。。
 
Unit AppBar;<br><br>Interface<br><br>Uses Windows, ShellApi;<br><br>function RegisterAccessBar(hwndAccessBar: HWND; bRegister : Boolean; nAppBarCallBackMsgID : DWORD):boolean;<br>procedure AppBarQuerySetPos(uEdge: longInt; var rc : TRECT; var ABD : APPBARDATA);<br><br>Implementation<br><br>function RegisterAccessBar(hwndAccessBar: HWND; bRegister : Boolean; nAppBarCallBackMsgID : DWORD):boolean;<br>var<br>&nbsp; abd : APPBARDATA;<br><br>begin<br>&nbsp; &nbsp; // Specify the structure size and handle to the appbar.<br>&nbsp; &nbsp; abd.cbSize := sizeof(APPBARDATA);<br>&nbsp; &nbsp; abd.hWnd := hwndAccessBar;<br><br>&nbsp; &nbsp; result :=TRUE;<br><br>&nbsp; &nbsp; if (bRegister) then<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; // Provide an identifier for notification messages.<br>&nbsp; &nbsp; &nbsp; &nbsp; abd.uCallbackMessage := nAppBarCallBackMsgID;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; // Register the appbar.<br>&nbsp; &nbsp; &nbsp; &nbsp; if (SHAppBarMessage(ABM_NEW, abd)&lt;&gt;0) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result := false;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; begin<br><br>&nbsp; &nbsp; &nbsp; &nbsp; // Unregister the appbar.<br>&nbsp; &nbsp; &nbsp; &nbsp; SHAppBarMessage(ABM_REMOVE, abd);<br>&nbsp; &nbsp; &nbsp; end;<br>end;<br><br>procedure AppBarQuerySetPos(uEdge: longInt; var rc : TRECT; var ABD : APPBARDATA);<br>var<br>&nbsp; iHeight : Integer;<br>&nbsp; iWidth &nbsp;: Integer;<br><br>begin<br>&nbsp; iHeight := 0;<br>&nbsp; iWidth &nbsp;:= 0;<br><br><br>&nbsp; abd.rc &nbsp; &nbsp;:= rc;<br>&nbsp; abd.uEdge := uEdge;<br><br>&nbsp; // Copy the screen coordinates of the appbar's bounding<br>&nbsp; // rectangle into the APPBARDATA structure.<br>&nbsp; if ((uEdge = ABE_LEFT) or (uEdge = ABE_RIGHT)) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; iWidth := abd.rc.right - abd.rc.left;<br>&nbsp; &nbsp; &nbsp; &nbsp; abd.rc.top := 0;<br>&nbsp; &nbsp; &nbsp; &nbsp; abd.rc.bottom := GetSystemMetrics(SM_CYSCREEN);<br>&nbsp; &nbsp; end<br>&nbsp; else<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; iHeight := abd.rc.bottom - abd.rc.top;<br>&nbsp; &nbsp; &nbsp; &nbsp; abd.rc.left := 0;<br>&nbsp; &nbsp; &nbsp; &nbsp; abd.rc.right := GetSystemMetrics(SM_CXSCREEN);<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; // Query the system for an approved size and position.<br>&nbsp; &nbsp; SHAppBarMessage(ABM_QUERYPOS, abd);<br><br>&nbsp; &nbsp; // Adjust the rectangle, depending on the edge to which the<br>&nbsp; &nbsp; // appbar is anchored.<br>&nbsp; &nbsp; case (uEdge) of<br>&nbsp; &nbsp; &nbsp; &nbsp; ABE_LEFT:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; abd.rc.right := abd.rc.left + iWidth;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; ABE_RIGHT:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; abd.rc.left := abd.rc.right - iWidth;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; ABE_TOP:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; abd.rc.bottom := abd.rc.top + iHeight;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; ABE_BOTTOM:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; abd.rc.top := abd.rc.bottom - iHeight;<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; // Pass the final bounding rectangle to the system. <br>&nbsp; &nbsp; SHAppBarMessage(ABM_SETPOS, abd);<br><br>&nbsp; &nbsp; // Move and size the appbar so that it conforms to the<br>&nbsp; &nbsp; // bounding rectangle passed to the system.<br>&nbsp; &nbsp; MoveWindow(abd.hWnd, abd.rc.left, abd.rc.top,<br>&nbsp; &nbsp; &nbsp; &nbsp; abd.rc.right - abd.rc.left,<br>&nbsp; &nbsp; &nbsp; &nbsp; abd.rc.bottom - abd.rc.top, TRUE);<br>End;<br><br>begin<br>end.
 
这一段是在AppBar的程序里面要用的<br><br>Uses ShellApi, AppBar;<br><br>var g_uSide:longInt; // record which side my AppBar resides.<br>// AppBarPosChanged - adjusts the appbar's size and position.<br>// pabd - address of an APPBARDATA structure that contains information<br>// &nbsp; &nbsp; used to adjust the size and position<br>procedure AppBarPosChanged(var abd : APPBARDATA);<br>var<br>&nbsp; rc &nbsp; &nbsp; &nbsp; : TRECT;<br>&nbsp; rcWindow :TRECT;<br>&nbsp; iHeight &nbsp;:integer;<br>&nbsp; iWidth &nbsp; :Integer;<br>Begin<br>&nbsp; rc.top := 0;<br>&nbsp; rc.left := 0;<br>&nbsp; rc.right := GetSystemMetrics(SM_CXSCREEN);<br>&nbsp; rc.bottom := GetSystemMetrics(SM_CYSCREEN);<br><br>&nbsp; GetWindowRect(abd.hWnd, rcWindow);<br>&nbsp; iHeight := rcWindow.bottom - rcWindow.top;<br>&nbsp; iWidth := rcWindow.right - rcWindow.left;<br><br>&nbsp; case (g_uSide) of<br>&nbsp; &nbsp; ABE_TOP:<br>&nbsp; &nbsp; &nbsp; rc.bottom := rc.top + iHeight;<br>&nbsp; &nbsp; ABE_BOTTOM:<br>&nbsp; &nbsp; &nbsp; rc.top := rc.bottom - iHeight;<br>&nbsp; &nbsp; ABE_LEFT:<br>&nbsp; &nbsp; &nbsp; rc.right := rc.left + iWidth;<br>&nbsp; &nbsp; ABE_RIGHT:<br>&nbsp; &nbsp; &nbsp; rc.left := rc.right - iWidth;<br>&nbsp; end;<br><br>&nbsp; AppBarQuerySetPos(g_uSide, rc, abd);<br>end;<br><br>// 这个CallBack处理过程 handle住系统发来的AppBar通知消息<br>// AppBarCallback - processes notification messages sent by the system.<br>// hwndAccessBar - handle to the appbar<br>// uNotifyMsg - identifier of the notification message<br>// lParam - message parameter<br>procedure AppBarCallback(hwndAccessBar : HWND; uNotifyMsg : UINT; lParam : LongInt);<br>var<br>&nbsp; abd :APPBARDATA;<br>&nbsp; uState: LongInt;<br>&nbsp; hWndTmp : HWnd;<br>begin<br>&nbsp; abd.cbSize := sizeof(abd);<br>&nbsp; abd.hWnd := hwndAccessBar;<br><br>&nbsp; case (uNotifyMsg) of<br>&nbsp; &nbsp; ABN_STATECHANGE:<br>&nbsp; &nbsp; &nbsp; Begin<br><br>&nbsp; &nbsp; &nbsp; // Check to see if the taskbar's always-on-top state has<br>&nbsp; &nbsp; &nbsp; // changed and, if it has, change the appbar's state<br>&nbsp; &nbsp; &nbsp; // accordingly.<br>&nbsp; &nbsp; &nbsp; uState := SHAppBarMessage(ABM_GETSTATE, abd);<br>&nbsp; &nbsp; &nbsp; if (ABS_ALWAYSONTOP and uState)&lt;&gt;0 then<br>&nbsp; &nbsp; &nbsp; &nbsp; Begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hWndTmp := HWND_TOPMOST<br>&nbsp; &nbsp; &nbsp; &nbsp; End<br>&nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; hWndTmp := HWND_BOTTOM;<br><br>&nbsp; &nbsp; &nbsp; SetWindowPos(hwndAccessBar,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hWndTmp,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0, 0, 0, 0,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; ABN_FULLSCREENAPP:<br>&nbsp; &nbsp; &nbsp; Begin<br>&nbsp; &nbsp; &nbsp; &nbsp; // A full-screen application has started, or the last full-<br>&nbsp; &nbsp; &nbsp; &nbsp; // screen application has closed. Set the appbar's<br>&nbsp; &nbsp; &nbsp; &nbsp; // z-order appropriately.<br>&nbsp; &nbsp; &nbsp; &nbsp; if (lParam&lt;&gt;0) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (ABS_ALWAYSONTOP and uState)&lt;&gt;0 then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hWndTmp := HWND_TOPMOST<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; End<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hWndTmp := HWND_BOTTOM;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetWindowPos(hwndAccessBar, hWndTmp,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0, 0, 0, 0,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; End<br>&nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uState := SHAppBarMessage(ABM_GETSTATE, abd);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (uState and ABS_ALWAYSONTOP)&lt;&gt;0 then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetWindowPos(hwndAccessBar, HWND_TOPMOST,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0, 0, 0, 0,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; End;<br>&nbsp; &nbsp; &nbsp; End;<br>&nbsp; &nbsp; ABN_POSCHANGED:<br>&nbsp; &nbsp; &nbsp; Begin<br>&nbsp; &nbsp; &nbsp; &nbsp; // The taskbar or another appbar has changed its<br>&nbsp; &nbsp; &nbsp; &nbsp; // size or position.<br>&nbsp; &nbsp; &nbsp; &nbsp; AppBarPosChanged(abd, g_uSide);<br>&nbsp; &nbsp; &nbsp; End<br>&nbsp; End;<br>End;<br><br>
 
从我作起,不再平均分配!
 
后退
顶部