象《东方快车》的App Bar窗口技术(200分)

  • 主题发起人 主题发起人 3h
  • 开始时间 开始时间
3

3h

Unregistered / Unconfirmed
GUEST, unregistred user!
如题,如何做到?<br>&amp;, 李维的那本书我没有,不要叫我看,请给出例程。<br>奉上200分,不成敬意。
 
什么样的bar?<br>eYes真的很孤陋寡闻艾.
 
深度历险上全部控件的windows界面扩展中和Ttrayicon一起分成一类里就有。
 
我也是:-(
 
浮动工具条,<br>原理就是一个没有标题条的窗口,响应移动和停靠的消息。<br>李维的书有好几页,还是找一下吧。<br>
 
不是有人问过?
 
就是有人问过大家可以查一下“东方快车”。<br><br>to rss:<br>&nbsp; 那本书我确实没有,想麻烦您抄一些主要的片段,如果是这样的话,<br>&nbsp; 1、200分归您了;<br>&nbsp; 2、不够可以讲价。:)
 
抢分喽:)<br>{<br>&nbsp; FILE: APPBAR.PAS by Eric Janssen (e.janssen@libertel.nl)<br><br>&nbsp; DESCRIPTION: Encapsuling of SHAppBarMessage<br>}<br>unit AppBar;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; ShellApi;<br><br>const<br>&nbsp; WM_APPBAR = WM_USER +1;<br><br>type<br>&nbsp; TEdge = (abeLeft, abeTop, abeRight, abeBottom);<br><br>&nbsp; TQuerySizeEvent = procedure(Sender: TObject; Edge: TEdge; var Width, Height: Integer) of object;<br><br>&nbsp; TAppBar = class(TComponent)<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; &nbsp; m_ABD: TAppBarData;<br>&nbsp; &nbsp; m_WndProc: TWndMethod;<br>&nbsp; &nbsp; m_Edge: TEdge;<br>&nbsp; &nbsp; m_QuerySize: TQuerySizeEvent;<br>&nbsp; &nbsp; procedure SetEdge(const Value: TEdge);<br>&nbsp; &nbsp; procedure WndProc(var Msg: TMessage);<br>&nbsp; protected<br>&nbsp; &nbsp; { Protected declarations }<br>&nbsp; &nbsp; procedure ABRegister; virtual;<br>&nbsp; &nbsp; procedure ABUnregister; virtual;<br>&nbsp; &nbsp; procedure ABSetPos; virtual;<br>&nbsp; &nbsp; procedure ABPosChanged; virtual;<br>&nbsp; &nbsp; procedure ABFullScreenApp(Enabled: Boolean); virtual;<br>&nbsp; &nbsp; procedure ABSetAutoHide(Enabled: Boolean); virtual;<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; &nbsp; constructor Create(AOwner: TComponent); override;<br>&nbsp; &nbsp; destructor Destroy; override;<br><br>&nbsp; &nbsp; procedure Loaded; override;<br>&nbsp; published<br>&nbsp; &nbsp; { Published declarations }<br>&nbsp; &nbsp; property Edge: TEdge read m_Edge write SetEdge;<br>&nbsp; &nbsp; property QuerySize: TQuerySizeEvent read m_QuerySize write m_QuerySize;<br>&nbsp; end;<br><br>procedure Register;<br><br>implementation<br><br>procedure Register;<br>begin<br>&nbsp; RegisterComponents('Libertel', [TAppBar]);<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.ABRegister;<br>begin<br>&nbsp; // check if we are not in the Delphi IDE<br>&nbsp; if not (csDesigning in ComponentState) then<br>&nbsp; begin<br>&nbsp; &nbsp; // make sure we get the notification messages<br>&nbsp; &nbsp; m_WndProc:= TWinControl(Owner).WindowProc;<br>&nbsp; &nbsp; TWinControl(Owner).WindowProc:= WndProc;<br><br>&nbsp; &nbsp; m_ABD.cbSize:= SizeOf(TAppBarData);<br>&nbsp; &nbsp; m_ABD.hWnd:= TWinControl(Owner).Handle;<br>&nbsp; &nbsp; m_ABD.uCallbackMessage:= WM_APPBAR;<br><br>&nbsp; &nbsp; // register the application bar within the system<br>&nbsp; &nbsp; if SHAppBarMessage(ABM_NEW, m_ABD) = 0 then<br>&nbsp; &nbsp; &nbsp; raise Exception.Create(SysErrorMessage(GetLastError()));<br><br>&nbsp; &nbsp; // make it a toolwindow with no caption<br>&nbsp; &nbsp; if SetWindowLong(m_ABD.hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW or WS_EX_DLGMODALFRAME) = 0 then<br>&nbsp; &nbsp; &nbsp; raise Exception.Create(SysErrorMessage(GetLastError()));<br><br>&nbsp; &nbsp; if SetWindowLong(m_ABD.hWnd, GWL_STYLE, 0) = 0 then<br>&nbsp; &nbsp; &nbsp; raise Exception.Create(SysErrorMessage(GetLastError()));<br><br>&nbsp; &nbsp; SetWindowPos(m_ABD.hWnd, m_ABD.hWnd, 0, 0, 0, 0, SWP_FRAMECHANGED or SWP_NOACTIVATE or SWP_NOSIZE or SWP_SHOWWINDOW);<br>&nbsp; end;<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.ABSetPos;<br>var Height, Width: Integer;<br>begin<br>&nbsp; if not (csDesigning in ComponentState) then<br>&nbsp; begin<br>&nbsp; &nbsp; // default size<br>&nbsp; &nbsp; Width:= TWinControl(Owner).Width;<br>&nbsp; &nbsp; Height:= TWinControl(Owner).Height;<br><br>&nbsp; &nbsp; // request the new size<br>&nbsp; &nbsp; if Assigned(m_QuerySize) then<br>&nbsp; &nbsp; &nbsp; m_QuerySize(Self, m_Edge, Width, Height);<br><br>&nbsp; &nbsp; m_ABD.rc.Right:= GetSystemMetrics(SM_CXSCREEN);<br>&nbsp; &nbsp; m_ABD.rc.Bottom:= GetSystemMetrics(SM_CYSCREEN);<br><br>&nbsp; &nbsp; if (m_ABD.uEdge = ABE_LEFT) or (m_ABD.uEdge = ABE_RIGHT) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if m_ABD.uEdge = ABE_LEFT then m_ABD.rc.Left:= 0<br>&nbsp; &nbsp; &nbsp; else m_ABD.rc.Left:= GetSystemMetrics(SM_CXSCREEN) - Width;<br>&nbsp; &nbsp; &nbsp; m_ABD.rc.Top:= 0;<br>&nbsp; &nbsp; end else<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if m_ABD.uEdge = ABE_TOP then m_ABD.rc.Top:= 0<br>&nbsp; &nbsp; &nbsp; else m_ABD.rc.Top:= GetSystemMetrics(SM_CYSCREEN) - Height;<br>&nbsp; &nbsp; &nbsp; m_ABD.rc.Left:= 0;<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; // query the new position<br>&nbsp; &nbsp; if SHAppBarMessage(ABM_QUERYPOS, m_ABD) = 0 then<br>&nbsp; &nbsp; &nbsp; raise Exception.Create(SysErrorMessage(GetLastError()));<br><br>&nbsp; &nbsp; // calculate the size<br>&nbsp; &nbsp; case m_ABD.uEdge of<br>&nbsp; &nbsp; &nbsp; ABE_LEFT:<br>&nbsp; &nbsp; &nbsp; &nbsp; m_ABD.rc.Right:= m_ABD.rc.Left + Width;<br>&nbsp; &nbsp; &nbsp; ABE_RIGHT:<br>&nbsp; &nbsp; &nbsp; &nbsp; m_ABD.rc.Left:= m_ABD.rc.Right - Width;<br>&nbsp; &nbsp; &nbsp; ABE_TOP:<br>&nbsp; &nbsp; &nbsp; &nbsp; m_ABD.rc.Bottom:= m_ABD.rc.Top + Height;<br>&nbsp; &nbsp; &nbsp; ABE_BOTTOM:<br>&nbsp; &nbsp; &nbsp; &nbsp; m_ABD.rc.Top:= m_ABD.rc.Bottom - Height;<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; // set the new size<br>&nbsp; &nbsp; if SHAppBarMessage(ABM_SETPOS, m_ABD) = 0 then<br>&nbsp; &nbsp; &nbsp; raise Exception.Create(SysErrorMessage(GetLastError()));<br><br>&nbsp; &nbsp; // move the form<br>&nbsp; &nbsp; MoveWindow(m_ABD.hWnd, m_ABD.rc.Left, m_ABD.rc.Top,<br>&nbsp; &nbsp; &nbsp; m_ABD.rc.Right - m_ABD.rc.Left,<br>&nbsp; &nbsp; &nbsp; m_ABD.rc.Bottom - m_ABD.rc.Top, TRUE);<br><br>&nbsp; end;<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.ABUnregister;<br>begin<br>&nbsp; // check if the form is not being destroyed and not in the Delphi IDE<br>&nbsp; if not (csDesigning in ComponentState) then<br>&nbsp; begin<br>&nbsp; &nbsp; if not (csDestroying in ComponentState) then<br>&nbsp; &nbsp; &nbsp; TWinControl(Owner).WindowProc:= m_WndProc;<br><br>&nbsp; &nbsp; // remove the application bar<br>&nbsp; &nbsp; if SHAppBarMessage(ABM_REMOVE, m_ABD) = 0 then<br>&nbsp; &nbsp; &nbsp; raise Exception.Create(SysErrorMessage(GetLastError()));<br>&nbsp; end;<br>end;<br>//------------------------------------------------------------------------------<br>constructor TAppBar.Create(AOwner: TComponent);<br>var I: Cardinal;<br>begin<br>&nbsp; inherited Create(AOwner);<br><br>&nbsp; // check if we have an owner<br>&nbsp; if Assigned(AOwner) then<br>&nbsp; begin<br>&nbsp; &nbsp; // we could turn everything with a handle into a application-bar, but for<br>&nbsp; &nbsp; // for Delphi we only use descendants of TCustomForm<br>&nbsp; &nbsp; if (AOwner is TCustomForm) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; // make sure we are the only one<br>&nbsp; &nbsp; &nbsp; for I:=0 to AOwner.ComponentCount -1 do<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; if (AOwner.Components is TAppBar) and (AOwner.Components &lt;&gt; Self) then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; raise Exception.Create('Ooops, you need only *ONE* of these');<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end else<br>&nbsp; &nbsp; &nbsp; raise Exception.Create('Sorry, can''t do this only with TCustomForms');<br><br>&nbsp; end else<br>&nbsp; &nbsp; raise Exception.Create('Sorry, can''t do this without an owner');<br>end;<br>//------------------------------------------------------------------------------<br>destructor TAppBar.Destroy;<br>begin<br>&nbsp; ABUnregister();<br><br>&nbsp; inherited Destroy();<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.Loaded;<br>begin<br>&nbsp; inherited Loaded();<br><br>&nbsp; ABRegister();<br>&nbsp; ABSetPos();<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.SetEdge(const Value: TEdge);<br>begin<br>&nbsp; if (m_Edge &lt;&gt; Value) then<br>&nbsp; begin<br>&nbsp; &nbsp; m_Edge:= Value;<br>&nbsp; &nbsp; case m_Edge of<br>&nbsp; &nbsp; &nbsp; abeLeft:<br>&nbsp; &nbsp; &nbsp; &nbsp; m_ABD.uEdge:= ABE_LEFT;<br>&nbsp; &nbsp; &nbsp; abeTop:<br>&nbsp; &nbsp; &nbsp; &nbsp; m_ABD.uEdge:= ABE_TOP;<br>&nbsp; &nbsp; &nbsp; abeBottom:<br>&nbsp; &nbsp; &nbsp; &nbsp; m_ABD.uEdge:= ABE_BOTTOM;<br>&nbsp; &nbsp; &nbsp; abeRight:<br>&nbsp; &nbsp; &nbsp; &nbsp; m_ABD.uEdge:= ABE_RIGHT;<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; ABSetPos();<br>&nbsp; end;<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.WndProc(var Msg: TMessage);<br>begin<br>&nbsp; if (Msg.Msg = WM_APPBAR) then<br>&nbsp; begin<br>&nbsp; &nbsp; case Msg.wParam of<br>&nbsp; &nbsp; &nbsp; ABN_STATECHANGE, ABN_POSCHANGED:<br>&nbsp; &nbsp; &nbsp; &nbsp; ABPosChanged();<br><br>&nbsp; &nbsp; &nbsp; ABN_FULLSCREENAPP:<br>&nbsp; &nbsp; &nbsp; &nbsp; ABFullScreenApp(Msg.lParam &lt;&gt; 0);<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br><br>&nbsp; if (Msg.Msg = WM_WINDOWPOSCHANGED) then<br>&nbsp; begin<br>&nbsp; &nbsp; SHAppBarMessage(ABM_WINDOWPOSCHANGED, m_ABD);<br>&nbsp; end;<br><br>&nbsp; if (Msg.Msg = WM_ACTIVATE) then<br>&nbsp; begin<br>&nbsp; &nbsp; SHAppBarMessage(ABM_ACTIVATE, m_ABD);<br>&nbsp; end;<br><br>&nbsp; // call the original WndProc<br>&nbsp; if Assigned(m_WndProc) then<br>&nbsp; &nbsp; m_WndProc(Msg);<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.ABPosChanged;<br>var rc, rcWindow: TRect;<br>&nbsp; &nbsp; Height, Width: 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(m_ABD.hWnd, rcWindow);<br><br>&nbsp; Height:= rcWindow.Top - rcWindow.Bottom;<br>&nbsp; Width:= rcWindow.Right - rcWindow.Left;<br><br>&nbsp; case m_ABD.uEdge of<br>&nbsp; &nbsp; ABE_TOP:<br>&nbsp; &nbsp; &nbsp; rc.Bottom:= rc.Top + Height;<br><br>&nbsp; &nbsp; ABE_BOTTOM:<br>&nbsp; &nbsp; &nbsp; rc.Top:= rc.Bottom - Height;<br><br>&nbsp; &nbsp; ABE_LEFT:<br>&nbsp; &nbsp; &nbsp; rc.Right:= rc.Left + Width;<br><br>&nbsp; &nbsp; ABE_RIGHT:<br>&nbsp; &nbsp; &nbsp; rc.Left:= rc.Right - Width;<br>&nbsp; end;<br><br>&nbsp; ABSetPos();<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.ABFullScreenApp(Enabled: Boolean);<br>var State: Integer;<br>&nbsp; &nbsp; Flags: HWND;<br>begin<br>&nbsp; State:= SHAppBarMessage(ABM_GETSTATE, m_ABD);<br><br>&nbsp; if Enabled then<br>&nbsp; begin<br>&nbsp; &nbsp; if (State and ABS_ALWAYSONTOP) &lt;&gt; 0 then<br>&nbsp; &nbsp; &nbsp; Flags:= HWND_TOPMOST<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; Flags:= HWND_BOTTOM;<br><br>&nbsp; &nbsp; SetWindowPos(m_ABD.hWnd, Flags, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);<br>&nbsp; end else<br>&nbsp; begin<br>&nbsp; &nbsp; if (State and ABS_ALWAYSONTOP) &lt;&gt; 0 then<br>&nbsp; &nbsp; &nbsp; SetWindowPos(m_ABD.hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);<br>&nbsp; end;<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.ABSetAutoHide(Enabled: Boolean);<br>begin<br>&nbsp; if not (csDesigning in ComponentState) then<br>&nbsp; begin<br>&nbsp; &nbsp; if Enabled then m_ABD.lParam:= -1<br>&nbsp; &nbsp; else m_ABD.lParam:= 0;<br><br>&nbsp; &nbsp; if SHAppBarMessage(ABM_SETAUTOHIDEBAR, m_ABD) &lt;&gt; 0 then<br>&nbsp; &nbsp; &nbsp; raise Exception.Create(SysErrorMessage(GetLastError()));<br>&nbsp; end;<br>end;<br>//------------------------------------------------------------------------------<br><br>end.
 
看来是一个控件,让我试试再说。
 
不能达到那种鼠标进入窗口才显示的效果?<br>只能在桌面固定占一地方?
 
autohide?<br>那个DESKTOP BAR如何?
 
&gt; autohide?那个DESKTOP BAR如何?<br><br>那里有?<br>我要的效果想要跟 OICQ 一样的。东方快车的还没劲了一点,OICQ比较豪华。<br>
 
I want autohide one, who send to me?<br>100 point.
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
后退
顶部