怎样才能做一个会自动隐藏的工具条?(100分)

  • 主题发起人 主题发起人 drroc
  • 开始时间 开始时间
D

drroc

Unregistered / Unconfirmed
GUEST, unregistred user!
我用以下代码创建一条Window工具条,但不会自动隐藏,请问,<br>是哪里错了?如何改正.<br>代码如下:<br>unit AppBarSampleCode;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,ShellApi,<br>&nbsp; StdCtrls;<br>const<br>&nbsp; APPBAR_CALLBACK=WM_USER+1024;<br>&nbsp; DEF_APPBAR_WIDTH=40;<br>&nbsp; DEF_APPBAR_HEIGHT=35;<br>type<br>&nbsp; TMainForm = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; &nbsp; procedure FormClose(Sender: TObject; var Action: TCloseAction);<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button2Click(Sender: TObject);<br>&nbsp; protected<br>&nbsp; &nbsp; procedure CreateParams(var Params:TCreateParams);override;<br>&nbsp; &nbsp; procedure SetTopMost(TopMost:Boolean);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; &nbsp; aAppBarData:TAppBarData;<br>&nbsp; &nbsp; procedure SetAppBarPos(uPosition:UINT);<br>&nbsp; &nbsp; procedure AppbarCallBack(var Msg:TMessage);message APPBAR_CALLBACK;<br>&nbsp; &nbsp; procedure WMActivate(var Msg:TMessage);message WM_ACTIVATE;<br>&nbsp; &nbsp; procedure WMWindowPosChange(var Msg:TMessage);message WM_WINDOWPOSCHANGED;<br>&nbsp; &nbsp; function SendAppBarMsg(Msg:DWORD):UINT;<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; MainForm: TMainForm;<br>implementation<br><br>{$R *.DFM}<br><br>procedure TMainForm.FormCreate(Sender: TObject);<br>begin<br>aAppBarData.hWnd:=Handle;<br>aAppBarData.cbSize:=SizeOf(TAppBarData);<br>aAppBarData.uCallbackMessage:=APPBAR_CALLBACK;<br>if SendAppBarMsg(ABM_NEW)=0 then<br>&nbsp; Application.Terminate;<br>SendAppBarMsg(ABM_SETAUTOHIDEBAR);<br>SetAppBarPos(ABE_TOP);<br>end;<br><br>procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);<br>begin<br>SHAppBarMessage(ABM_REMOVE,aAppBarData);<br>end;<br><br>procedure TMainForm.SetAppBarPos(uPosition:UINT);<br>begin<br>aAppBarData.uEdge:=uPosition;<br>with aAppBarData.rc do<br>begin<br>&nbsp; Top:=0;<br>&nbsp; Left:=0;<br>&nbsp; Right:=Screen.Width;<br>&nbsp; Bottom:=Screen.Height;<br>&nbsp; SendAppBarMsg(ABM_QUERYPOS);<br>&nbsp; case uPosition of<br>&nbsp; ABE_LEFT:Right:=Left+DEF_APPBAR_WIDTH;<br>&nbsp; ABE_RIGHT:Left:=Right-DEF_APPBAR_WIDTH;<br>&nbsp; ABE_TOP:Bottom:=Top+DEF_APPBAR_HEIGHT;<br>&nbsp; ABE_BOTTOM:Top:=Bottom-DEF_APPBAR_HEIGHT;<br>&nbsp; end;<br>&nbsp; SendAppBarMsg(ABM_SETPOS);<br>end;<br>BoundsRect:=aAppBarData.rc;<br>end;<br><br>procedure TMainForm.AppbarCallBack(var Msg:TMessage);<br>var<br>&nbsp; uState:UINT;<br>begin<br>case Msg.wParam of<br>ABN_STATECHANGE:<br>begin<br>&nbsp; uState:=SendAppBarMsg(ABM_GETSTATE);<br>&nbsp; if ABS_ALWAYSONTOP and uState=0 then<br>&nbsp; &nbsp; SetTopMost(False)<br>&nbsp; else<br>&nbsp; &nbsp; SetTopMost(True);<br>end;<br>ABN_FULLSCREENAPP:<br>begin<br>&nbsp; uState:=SendAppBarMsg(ABM_GETSTATE);<br>&nbsp; if Msg.lParam&lt;&gt;0 then<br>&nbsp; begin<br>&nbsp; &nbsp; if ABS_ALWAYSONTOP and uState=0 then<br>&nbsp; &nbsp; &nbsp; SetTopMost(False)<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; SetTopMost(True);<br>&nbsp; end<br>&nbsp; else<br>&nbsp; begin<br>&nbsp; &nbsp; if uState and ABS_ALWAYSONTOP&lt;&gt;0 then<br>&nbsp; &nbsp; &nbsp; SetTopMost(True);<br>&nbsp; end;<br>end;<br>ABN_POSCHANGED:<br>begin<br>&nbsp; SetAppBarPos(aAppBarData.uEdge);<br>end;<br>end;<br>end;<br><br>procedure TMainForm.WMActivate(var Msg:TMessage);<br>begin<br>inherited;<br>SendAppBarMsg(ABM_ACTIVATE);<br>end;<br><br>procedure TMainForm.CreateParams(var Params:TCreateParams);<br>begin<br>inherited CreateParams(Params);<br>with Params do<br>begin<br>ExStyle:=WS_EX_TOOLWINDOW or WS_EX_TOPMOST;<br>Style:=WS_VISIBLE or WS_POPUP or WS_THICKFRAME or WS_CLIPCHILDREN;<br>end;<br>end;<br><br>function TMainForm.SendAppBarMsg(Msg:DWORD):UINT;<br>begin<br>Result:=SHAppBarMessage(Msg,aAppBarData);<br>end;<br><br>procedure TMainForm.WMWindowPosChange(var Msg:TMessage);<br>begin<br>inherited;<br>SendAppBarMsg(ABM_WINDOWPOSCHANGED);<br>end;<br><br>procedure TMainForm.SetTopMost(TopMost:Boolean);<br>const<br>&nbsp; WndPosArray:array[Boolean] of HWND=(HWND_BOTTOM,HWND_TOPMOST);<br>begin<br>SetWindowPos(Handle,WndPosArray[TopMost],0,0,0,0,SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE)<br>end;<br><br><br>procedure TMainForm.Button1Click(Sender: TObject);<br>begin<br>SetTopMost(False);<br>end;<br><br>procedure TMainForm.Button2Click(Sender: TObject);<br>begin<br>SetTopMost(True);<br>end;<br><br>end.<br>
 
请参阅如下控件 &nbsp;<br>unit USAppBar;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,ShellApi;<br><br>const WM_Appbar = WM_USER+23;<br>&nbsp; &nbsp; &nbsp; id_UnhideTimer = 2906 ;<br>&nbsp; &nbsp; &nbsp; id_HideTimer &nbsp; = 2907 ;<br><br>type<br><br>&nbsp; TEdge = (abeLeft,abeTop,abeRight,abeBottom);<br><br>&nbsp; TUSAppBar = class(TComponent)<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; &nbsp;FABOldStyle,FABOldStyleEx,FABZOrder,FABTimerID:Integer;<br>&nbsp; &nbsp;FABOwner:TForm;<br>&nbsp; &nbsp;FABHandle:THandle;<br>&nbsp; &nbsp;FABData:TAppBarData;<br>&nbsp; &nbsp;FABReg,FABMoving,FABHidden:Boolean;<br>&nbsp; &nbsp;FABWide,FABEdge:Integer;<br>&nbsp; &nbsp;FABActive,FABSliding,FABAutoHide,FABAlwaysOnTop:Boolean;<br>&nbsp; &nbsp;FABOldRect,FABRect:TRect;<br>&nbsp; &nbsp;procedure SlideWindow (hwnd:Integer;np:TRect;slide:boolean);<br><br>&nbsp; &nbsp;procedure AB_Register; //Registriert<br>&nbsp; &nbsp;procedure AB_Remove; &nbsp; //Entfernt AppBar aus dem System<br>&nbsp; &nbsp;procedure AB_CB (var msg:TMessage);<br><br>&nbsp; &nbsp;procedure AB_Hide;<br>&nbsp; &nbsp;procedure AB_Unhide;<br><br>&nbsp; &nbsp;procedure AB_CalcRect (wide:Integer;var R:TRect);<br>&nbsp; &nbsp;procedure AB_CheckPos (wide:Integer;var R:Trect);<br>&nbsp; &nbsp;procedure AB_SetABPos;<br>&nbsp; &nbsp;procedure AB_SetWndPos;<br><br>&nbsp; &nbsp;procedure AB_SetActive;<br><br>&nbsp; &nbsp;procedure AB_NoAutoHide;<br>&nbsp; &nbsp;procedure AB_AutoHide;<br>&nbsp; &nbsp;procedure AB_SetAutoHide;<br>&nbsp; &nbsp;procedure AB_SetAlwaysOnTop (aAlwaysOnTop:Boolean);<br>&nbsp; protected<br>&nbsp; &nbsp; { Protected declarations }<br>&nbsp; &nbsp; FOnChangeEdge:TNotifyEvent;<br>&nbsp; &nbsp; OldWndProc : TFarProc;<br>&nbsp; &nbsp; NewWndProc : Pointer;<br>&nbsp; &nbsp; procedure SetEdge (aEdge:TEdge);<br>&nbsp; &nbsp; function &nbsp;GetEdge:TEdge;<br>&nbsp; &nbsp; procedure SetWide (aWide:Integer);<br>&nbsp; &nbsp; procedure SetAutoHide (aAutoHide:Boolean);<br>&nbsp; &nbsp; procedure SetAlwaysOnTop (aAlwaysOnTop:Boolean);<br>&nbsp; &nbsp; procedure SetActive (aActive:Boolean);<br><br>&nbsp; &nbsp; procedure HookWin;<br>&nbsp; &nbsp; procedure UnhookWin;<br>&nbsp; &nbsp; function Design:Boolean; //Noch ersetzen<br>&nbsp; &nbsp; procedure HookWndProc(var Message: TMessage);<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; &nbsp; constructor Create(AOwner: TComponent); &nbsp;override;<br>&nbsp; &nbsp; destructor &nbsp;Destroy; override;<br>&nbsp; published<br>&nbsp; &nbsp; { Published declarations }<br>&nbsp; &nbsp; property Active:boolean read FABActive write SetActive;<br>&nbsp; &nbsp; property Wide:Integer read FABWide write SetWide;<br>&nbsp; &nbsp; property Edge:TEdge read GetEdge write SetEdge;<br>&nbsp; &nbsp; property Autohide:boolean read FABAutohide write SetAutohide;<br>&nbsp; &nbsp; property AlwaysOnTop:boolean read FABAlwaysOnTop write SetAlwaysOnTop;<br>&nbsp; &nbsp; property Sliding:boolean read FABSliding write FABSliding;<br>&nbsp; &nbsp; property Registerd:Boolean Read FABReg;<br>&nbsp; &nbsp; property OnChangeEdge:TNotifyEvent read FOnChangeEdge write FOnChangeEdge;<br>&nbsp; end;<br><br>procedure Register;<br><br>implementation<br><br>procedure Register;<br>begin<br>&nbsp; RegisterComponents('Win95', [TUSAppBar]);<br>end;<br><br>function TUSAppBar.Design:Boolean;<br>BEGIN<br>result:=csDesigning in ComponentState;<br>END;<br><br>procedure TUSAppBar.SlideWindow(hwnd:Integer;np:TRect;slide:Boolean);<br>var OldPos:TRect;<br>&nbsp; &nbsp; priority,x,y,dx,dy,dt,t,t0:Integer;<br>&nbsp; &nbsp; fShow:Boolean;<br>&nbsp; &nbsp; hThreadMe:Integer;<br>const g_dtSlideHide = 400;<br>const g_dtSlideShow = 400;<br><br>begin<br>&nbsp;IF slide THEN<br>&nbsp; BEGIN<br>&nbsp;GetWindowRect(hwnd, OldPos);<br><br>&nbsp;fShow:=((np.bottom - np.top)&gt;(OldPos.bottom - OldPos.top)) or<br>&nbsp; ((np.right - np.left) &gt; (OldPos.right - OldPos.left));<br>&nbsp;dx := (np.right - oldpos.right) + (np.left - oldpos.left);<br>&nbsp;dy := (np.bottom - oldpos.bottom) + (np.top - oldpos.top);<br>if (fShow) THEN<br>&nbsp;BEGIN<br>&nbsp; OldPos:=np;<br>&nbsp; OffsetRect(OldPos, -dx, -dy);<br>&nbsp; SetWindowPos(hwnd,0,OldPos.left,OldPos.top,<br>&nbsp; &nbsp; &nbsp;OldPos.right - OldPos.left, OldPos.bottom - OldPos.top,<br>&nbsp; &nbsp; &nbsp;SWP_NOZORDER OR SWP_NOACTIVATE {OR SWP_DRAWFRAME});<br>&nbsp; dt := g_dtSlideShow;<br>END<br>&nbsp;else<br>&nbsp; dt := g_dtSlideHide;<br><br>hThreadMe := GetCurrentThread();<br>priority := GetThreadPriority(hThreadMe);<br>SetThreadPriority(hThreadMe, THREAD_PRIORITY_BELOW_NORMAL);<br><br>t0 := GetTickCount();<br>t:=t0;<br>while ((t) &lt; t0 + dt) do<br>&nbsp;begin<br>&nbsp; &nbsp;t := GetTickCount();<br>&nbsp; &nbsp;x := Round(OldPos.left + dx * (t - t0) / dt);<br>&nbsp; &nbsp;y := Round(OldPos.top + dy * (t - t0) / dt);<br>&nbsp; &nbsp;SetWindowPos(hwnd, 0, x, y, 0, 0,<br>&nbsp; &nbsp;SWP_NOSIZE or SWP_NOZORDER or SWP_NOACTIVATE);<br>&nbsp; &nbsp;if (fShow) THEN UpdateWindow(hwnd) else;<br>&nbsp; &nbsp; UpdateWindow(GetDesktopWindow());<br>&nbsp;END;<br>&nbsp; SetThreadPriority(hThreadMe, priority);<br>&nbsp; END;<br><br>&nbsp;SetWindowPos(hwnd, 0, np.left, np.top,<br>&nbsp; &nbsp; np.right - np.left, np.bottom - np.top,<br>&nbsp; &nbsp; SWP_NOZORDER or SWP_NOACTIVATE or SWP_DRAWFRAME);<br>END;<br><br><br>procedure &nbsp;TUSAppBar.AB_Register;<br>begin<br>with FABData do<br>&nbsp;begin<br>&nbsp; cbsize:=SizeOf (FABData);<br>&nbsp; hwnd:=FABHandle;<br>&nbsp; uCallBackMessage:=wm_appbar;<br>&nbsp;end;<br>&nbsp;if not FABReg THEN<br>&nbsp; FABReg:=(shAppBarMessage (ABM_NEW,FABData)&lt;&gt;0);<br>end;<br><br>procedure TUSAppBar.AB_Remove;<br>begin<br>with FABData do<br>&nbsp;begin<br>&nbsp; cbsize:=SizeOf (FABData);<br>&nbsp; hwnd:=FABHandle;<br>&nbsp;end;<br>if FABReg THEN shAppBarMessage (ABM_REMOVE,FABData);<br>FABReg:=false;<br>end;<br><br>procedure TUSAppBar.AB_CB (var msg:TMessage);<br>begin<br>&nbsp; IF msg.WPARAM = ABN_PosChanged THEN<br>&nbsp; &nbsp;BEGIN<br>&nbsp; &nbsp; AB_SetABPOS;AB_SetWndPos<br>&nbsp; &nbsp;END<br>end;<br><br>procedure TUSAppBar.AB_Hide;<br><br>var r:TRect;<br>begin<br>If (not FABHidden) Then<br>&nbsp;BEGIN<br>&nbsp;AB_CheckPos(2,r);<br>&nbsp;SlideWindow (FABHandle,r,FABSliding);<br>&nbsp;FABHidden:=true;<br>&nbsp;END;<br>end;<br><br>procedure TUSAppBar.AB_Unhide;<br>var r:TRect;<br><br>begin<br><br>If FABHidden Then<br>&nbsp;BEGIN<br>&nbsp;AB_CheckPos (FABWide,r);<br>&nbsp;SlideWindow (FABHandle,r,FABSliding);<br>&nbsp;FABHidden:=False;<br>&nbsp;if (fABAutoHide) THEN<br>&nbsp; &nbsp;FABTimerId:=SetTimer(FABHandle, ID_HIDETIMER, 500, NIL)<br>&nbsp;END<br>END;<br><br>procedure TUSAppBar.AB_CalcRect (wide:Integer;var R:TRect);<br><br>BEGIN<br>case FABEdge of<br>&nbsp;ABE_LEFT &nbsp;: with r do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TOP:=0;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LEFT:=0;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Bottom:=GetSystemMetrics(SM_CYSCREEN);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Right:=Wide;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END;<br>&nbsp;ABE_RIGHT : with r do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TOP:=0;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Bottom:=GetSystemMetrics(SM_CYSCREEN);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Right:=GetSystemMetrics(SM_CXSCREEN);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LEFT:=Right-Wide;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END;<br>&nbsp;ABE_TOP &nbsp; : with r do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TOP:=0;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LEFT:=0;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Bottom:=Wide;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Right:=GetSystemMetrics(SM_CXSCREEN);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END;<br>&nbsp;ABE_BOTTOM: with r do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LEFT:=0;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Bottom:=GetSystemMetrics(SM_CYSCREEN);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TOP:=Bottom-Wide;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Right:=GetSystemMetrics(SM_CXSCREEN);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END<br>&nbsp; END<br>&nbsp;END;<br><br>procedure TUSAppBar.AB_CheckPos (wide:Integer;var R:Trect);<br>begin<br>&nbsp;AB_CalcRect (wide,r);<br>&nbsp;with FABData do<br>&nbsp; BEGIN<br>&nbsp; &nbsp;cbsize:=SizeOf (FABData);<br>&nbsp; &nbsp;uEdge:=FABEdge;<br>&nbsp; &nbsp;hwnd:=FABHandle;<br>&nbsp; &nbsp;rc:=r<br>&nbsp; END;<br>&nbsp;IF FABReg THEN shAppBarMessage (ABM_QUERYPOS,FABData);<br>&nbsp;r:=FABData.rc;<br>case FABEdge of<br>&nbsp;ABE_LEFT &nbsp;: r.LEFT:=0;<br>&nbsp;ABE_RIGHT : r.Bottom:=GetSystemMetrics(SM_CYSCREEN);<br>&nbsp;ABE_TOP &nbsp; : r.TOP:=0;<br>&nbsp;ABE_BOTTOM: r.Bottom:=GetSystemMetrics(SM_CYSCREEN);<br>&nbsp; END<br><br>end;<br><br>procedure TUSAppBar.AB_SetABPos;<br>var wide:Integer;<br>begin<br>IF FABReg THEN<br>&nbsp;BEGIN<br>&nbsp; wide:=FABWide;<br>&nbsp; If FABAutohide THEN wide:=2;<br>&nbsp; IF (not FABAlwaysOnTop) and (not FABAutohide) Then wide:=0;<br>&nbsp; AB_CheckPos (wide,FABRect);<br>&nbsp; with FABData do<br>&nbsp; &nbsp;begin<br>&nbsp; &nbsp; cbsize:=SizeOf (FABData);<br>&nbsp; &nbsp; uEdge:=FABEdge;<br>&nbsp; &nbsp; hwnd:=FABHandle;<br>&nbsp; &nbsp; rc:=FABRect<br>&nbsp; &nbsp;end;<br>&nbsp; shAppBarMessage (ABM_setPos,FABData);<br>&nbsp;END;<br>end;<br><br>procedure TUSAppBar.AB_SetWndPos;<br><br>var wide:Integer;<br>&nbsp; &nbsp; r:TREct;<br>BEGIN<br><br>IF FABReg THEN<br>&nbsp; BEGIN<br>&nbsp; &nbsp;If FABHidden Then wide:=2 else wide:=FABWide;<br>&nbsp; &nbsp;AB_CheckPos (Wide,r);<br>&nbsp; &nbsp;SlideWindow (FABHandle,r,FABSliding);<br>&nbsp; END;<br>END;<br><br>procedure TUSAppBar.AB_SetActive;<br><br>BEGIN<br>If FABActive THEN<br>&nbsp;BEGIN //Registrieren, Werte setzen, und hinschieben...<br>&nbsp;IF not FABReg THEN AB_Register;<br>&nbsp;IF FABReg THEN<br>&nbsp; BEGIN<br>&nbsp; &nbsp;GetWindowRect (FABHandle,FABOldRect);<br>&nbsp; &nbsp;FABOldStyleEx:=GetWindowLong (FABHandle,GWL_EXSTYLE);<br>&nbsp; &nbsp;FABOldStyle:=GetWindowLong (FABHandle,GWL_STYLE);<br>&nbsp; &nbsp;SetWindowLong (FABHandle,GWL_EXSTYLE,WS_EX_TOOLWINDOW);<br>&nbsp; &nbsp;SetWindowLong (FABHandle,GWL_Style,WS_VISIBLE or WS_DLGFRAME or ws_thickframe);<br>&nbsp; &nbsp;HookWin;<br>&nbsp; &nbsp;AB_SetAutohide;<br>&nbsp; &nbsp;AB_SetAlwaysOnTop(FABAlwaysOnTop);<br>&nbsp; &nbsp;AB_SetABPos;<br>&nbsp; &nbsp;AB_SetWndPos<br>&nbsp; END<br>&nbsp;END<br>ELSE<br>&nbsp;BEGIN<br>&nbsp;AB_NoAutoHide;<br>&nbsp;AB_SetAlwaysOnTop (false);<br>&nbsp;AB_Remove;<br>&nbsp;UnHookWin;<br>&nbsp;SetWindowLong (FABHandle,GWL_EXSTYLE,FABOldStyleEx);<br>&nbsp;SetWindowLong (FABHandle,GWL_STYLE,FABOldStyle);<br>&nbsp;SlideWindow (FABHandle,FABOldRect,false);<br>&nbsp;END<br>END;<br><br>procedure TUSAppBar.AB_NoAutoHide;<br>var ret:Integer;<br><br>BEGIN<br><br>IF FABReg THEN<br>&nbsp;BEGIN<br>&nbsp;with FABData do<br>&nbsp; begin<br>&nbsp; cbsize:=Sizeof(FABData);<br>&nbsp; uEdge:=FABEdge;<br>&nbsp; hwnd:=FABHandle<br>&nbsp; END;<br>&nbsp;ret:=shAppBarMessage (ABM_GetAutohideBar,FABData);<br>&nbsp;IF (ret=FABHandle) THEN<br>&nbsp; BEGIN<br>&nbsp; &nbsp;FABData.LParam:=0;<br>&nbsp; &nbsp;ret:=shAppBarMessage (ABM_SetAutohideBar,FABData);<br>&nbsp; END<br>&nbsp;END<br>END;<br><br>procedure TUSAppBar.AB_AutoHide;<br>var ret:Integer;<br>BEGIN<br>IF FABReg THEN<br>&nbsp;BEGIN<br>&nbsp;with FABData do<br>&nbsp; begin<br>&nbsp; cbsize:=Sizeof(FABData);<br>&nbsp; uEdge:=FABEdge;<br>&nbsp; hwnd:=FABHandle<br>&nbsp; END;<br>&nbsp;ret:=shAppBarMessage (ABM_GetAutohideBar,FABData);<br>&nbsp;IF (ret&lt;&gt;0) THEN<br>&nbsp; BEGIN<br>&nbsp; &nbsp; &nbsp;MessageDlg ('Another appbar ist already registered to this edge',<br>&nbsp; &nbsp; &nbsp; &nbsp;mtError,[mbOk],0);<br>&nbsp; &nbsp; &nbsp;AB_Unhide;<br>&nbsp; &nbsp; &nbsp;FABAutohide:=FALSE;<br>&nbsp; END<br>&nbsp;ELSE<br>&nbsp; BEGIN<br>&nbsp; &nbsp; &nbsp;FABData.LParam:=1;<br>&nbsp; &nbsp; &nbsp;ret:=shAppBarMessage (ABM_SetAutohideBar,FABData);<br>&nbsp; &nbsp; &nbsp;FABAutohide:=ret&lt;&gt;0;<br>&nbsp; &nbsp; &nbsp;IF FABAutohide THEN FABTimerId:=SetTimer(FABHandle, ID_HIDETIMER, 500, NIL)<br>&nbsp; END<br>&nbsp;END;<br><br>END;<br><br><br>procedure TUSAppBar.AB_SetAutoHide;<br><br>begin<br><br>If FABAutohide THEN AB_AutoHide ELSE AB_NoAutoHide;<br>END;<br><br><br><br><br>procedure TUSAppBar.AB_SetAlwaysOnTop;<br><br>BEGIN<br><br>IF FABReg THEN<br>BEGIN<br>&nbsp; If aAlwaysOnTop THEN<br>&nbsp; SetWindowPos(FABHandle,HWND_TOPMOST,<br>&nbsp; &nbsp; &nbsp;0, 0, 0, 0, SWP_NOMOVE OR SWP_NOSIZE OR SWP_NOACTIVATE)<br>&nbsp; &nbsp;ELSE<br>&nbsp; SetWindowPos(FABHandle,HWND_NOTOPMOST,<br>&nbsp; &nbsp; &nbsp;0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);<br>&nbsp; AB_SetABPos;<br>END;<br><br>END;<br><br><br>procedure TUSAppBar.SetEdge (aEdge:TEdge);<br><br>BEGIN<br>IF FABEdge&lt;&gt;Ord(aEdge) THEN<br>&nbsp;BEGIN<br>&nbsp;FABEdge:=Ord(aEdge);<br>&nbsp;IF not Design THEN<br>&nbsp; BEGIN<br>&nbsp; &nbsp;AB_SetABPos;<br>&nbsp; &nbsp;AB_SetWndPos<br>&nbsp; END<br>&nbsp;END<br>END;<br><br><br>function &nbsp;TUSAppBar.GetEdge:TEdge;<br>BEGIN<br>Result:=TEdge(FABEdge);<br>END;<br>procedure TUSAppBar.SetWide (aWide:Integer);<br>BEGIN<br>IF FABWide&lt;&gt;aWide THEN<br>&nbsp;BEGIN<br>&nbsp;FABWide:=aWide;<br>&nbsp;IF not Design THEN<br>&nbsp; BEGIN<br>&nbsp; &nbsp;AB_SetABPos;<br>&nbsp; &nbsp;AB_SetWndPos<br>&nbsp; END<br>&nbsp;END<br>END;<br><br>procedure TUSAppBar.SetAutoHide (aAutoHide:Boolean);<br><br>BEGIN<br>IF FABAutoHide&lt;&gt;aAutoHide THEN<br>&nbsp;BEGIN<br>&nbsp;FABAutohide:=aAutohide;<br>&nbsp;If not Design THEN AB_SetAutohide;<br>&nbsp;END<br>END;<br><br>procedure TUSAppBar.SetAlwaysOnTop (aAlwaysOnTop:Boolean);<br>BEGIN<br>IF FABAlwaysOnTop&lt;&gt;aAlwaysOnTop THEN<br>&nbsp;BEGIN<br>&nbsp;FABAlwaysOnTop:=aAlwaysOnTop;<br>&nbsp;If not Design THEN AB_SetAlwaysOnTop(FABAlwaysOnTop);<br>&nbsp;END<br>END;<br><br>procedure TUSAppBar.SetActive (aActive:Boolean);<br>BEGIN<br>IF aActive &lt;&gt;FABActive THEN<br>&nbsp;BEGIN<br>&nbsp;FABActive:=aActive;<br>&nbsp;IF not Design THEN AB_SetActive<br>&nbsp;END<br>END;<br><br>procedure TUSAppBar.HookWin;<br><br>BEGIN<br>&nbsp;OldWndProc := TFarProc(GetWindowLong(FABHandle, GWL_WNDPROC));<br>&nbsp;NewWndProc := MakeObjectInstance(HookWndProc);<br>&nbsp;SetWindowLong(FABHandle, GWL_WNDPROC, LongInt(NewWndProc));<br>END;<br><br>procedure TUSAppBar.UnhookWin;<br>begin<br>&nbsp;SetWindowLong(FABHandle, GWL_WNDPROC, LongInt(OldWndProc));<br>&nbsp;if assigned(NewWndProc) then<br>&nbsp; FreeObjectInstance(NewWndProc);<br>&nbsp;NewWndProc := nil;<br>end;<br><br>procedure TUSAppBar.HookWndProc(var Message: TMessage);<br>var VorlRes:Integer;<br>&nbsp; &nbsp; MP:TPoint;<br>&nbsp; &nbsp; R:Trect;<br>&nbsp; &nbsp; dx,dy,cxscreen,cyscreen,vert,horz:Integer;<br>begin<br><br>&nbsp; with Message do<br>&nbsp; begin<br>&nbsp; &nbsp; CASE Msg OF<br>&nbsp; &nbsp; &nbsp;wm_AppBar &nbsp; &nbsp; : AB_CB (Message); //Eine Nachricht von unsere Appbar<br>&nbsp; &nbsp; &nbsp;wm_Timer &nbsp; &nbsp; &nbsp;: If ((WParam=id_UnHideTimer) OR (WParam=id_HideTimer)) //Ein Timer zum Autohiding<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND FABAutoHide THEN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IF WParam=id_HideTimer THEN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(MP);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetWindowRect(FABHandle, R);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if not PtInRect(r, mp) THEN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;KillTimer(FABHandle, id_HideTimer);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AB_Hide<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IF WParam=id_UnHideTimer THEN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(MP);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetWindowRect(FABHandle, R);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if PtInRect(r, mp) THEN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;KillTimer(FABHandle, id_UnhideTimer);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AB_Unhide<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ELSE<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result := CallWindowProc (OldWndProc,FABHandle, Msg, wParam, lParam);<br><br>&nbsp; &nbsp; &nbsp;WM_NCHITTEST: &nbsp;//Es wird gerade NichtClient getestet<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If FABHIDDEN THEN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FABTimerID:=SetTimer(FABHandle,id_UnhideTimer,200,nil);<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;result:=HTClient;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;VorlRes := CallWindowProc (<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OldWndProc,FABHandle, Msg, wParam, lParam);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IF not(VorlRes in [HTBottom,HTTOP,HTRight,HTLeft]) THEN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result:=VorlRes;<br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((FABEdge=ABE_TOP) AND (VorlRes = HTBOTTOM)) THEN<br> &nbsp; &nbsp; &nbsp; &nbsp;result:= HTBOTTOM;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ((FABEdge=ABE_Bottom) AND (VorlRes = HTTop)) THEN<br> &nbsp; &nbsp; &nbsp; &nbsp;result:= HTTOP;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (FABEdge=ABE_LEFT) AND (VorlRes = HTRight) THEN<br> &nbsp; &nbsp; &nbsp; &nbsp;result:= HTRight;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ((FABEdge=ABE_RIGHT) AND (VorlRes = HTLeft)) THEN<br> &nbsp; &nbsp; &nbsp; &nbsp;result:= HTLeft;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END;<br><br>&nbsp; &nbsp; wm_sizing : &nbsp;IF (wparam=wmsz_top) or (wparam=wmsz_bottom) THEN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FABWide:=PRect(lparam)^.bottom-PRect(lparam)^.top<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FABWide:=PRect(lparam)^.right-PRect(lparam)^.left;<br>&nbsp; &nbsp; &nbsp;wm_LButtonDown : BEGIN<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetForeGroundWindow (FABHandle);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetCapture (FABHandle);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FABMoving:=true;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AB_NoAutohide;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END;<br>&nbsp; &nbsp; &nbsp;wm_MouseMove &nbsp; : IF FABMoving THEN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;BEGIN<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cxScreen := GetSystemMetrics(SM_CXSCREEN);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cyScreen := GetSystemMetrics(SM_CYSCREEN);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GetCursorPos(MP) ;<br><br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if mp.x &lt; (cxScreen div 2) THEN<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BEGIN<br> &nbsp; &nbsp; &nbsp; &nbsp; dx := mp.x;<br> &nbsp; &nbsp; &nbsp; &nbsp; horz:= ABE_LEFT;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;BEGIN<br> &nbsp; &nbsp; &nbsp; &nbsp; dx := (cxscreen-mp.x);<br> &nbsp; &nbsp; &nbsp; &nbsp; horz:= ABE_RIGHT;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ((mp.y) &lt; (cyScreen div 2)) THEN<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BEGIN<br> &nbsp; &nbsp; &nbsp; &nbsp; dy := mp.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; vert:= ABE_TOP;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;BEGIN<br> &nbsp; &nbsp; &nbsp; &nbsp; dy := cyscreen-mp.y;<br> &nbsp; &nbsp; &nbsp; &nbsp; vert:= ABE_Bottom;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (cxScreen div dx) &gt; (cyScreen div dy) THEN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FABEdge:=horz ELSE<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FABEDge:=vert;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AB_CheckPos (FABWide,R);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SlideWindow (FABHandle,R,FALSE);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END;<br>&nbsp; &nbsp; &nbsp;wm_LButtonUp &nbsp; : IF FABMoving THEN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IF Assigned (FOnChangeEdge) THEN FOnChangeEdge(self);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AB_SetABPos;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AB_SetAutoHide;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FABMoving:=False;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ReleaseCapture();<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END;<br>&nbsp; &nbsp; &nbsp;wm_Activate &nbsp; &nbsp; : BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;with FABData do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbSize:=sizeof (FABData);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hwnd:=FABHandle;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lparam:=0;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SHAppBarMessage (ABM_Activate,FABData);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CASE wParamlo of<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WA_CLICKACTIVE: BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;IF FABAutohide THEN AB_Unhide;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;KillTimer (FABHandle,ID_HideTimer);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WA_InACtive &nbsp; : IF FABAutohide THEN AB_Hide;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END;<br>&nbsp; &nbsp; &nbsp;wm_size : BEGIN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;with FABData do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbSize:=sizeof(FABData);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hWnd:=FABHandle;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lParam:=0<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SHAppBarMessage (ABM_WindowPosChanged,FABData);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result := CallWindowProc (OldWndProc,FABHandle, Msg, wParam, lParam);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;END<br>&nbsp; &nbsp; ELSE Result := CallWindowProc (OldWndProc,FABHandle, Msg, wParam, lParam);<br>&nbsp; &nbsp;END //von Case<br>&nbsp; end;<br>end;<br><br>constructor TUSAppBar.Create(AOwner: TComponent);<br>BEGIN<br>inherited Create (AOwner);<br>FABOwner:=Aowner As TForm;<br>FABHandle:=FABOwner.Handle;<br><br>FABActive:=false;<br>FABAutoHide:=false;<br>FABAlwaysOnTop:=false;<br>FABSliding:=true;<br>FABWide:=50;<br>FABEdge:=ABE_Left;<br>FABHidden:=false;<br>FABMoving:=false;<br>FABReg:=false;<br>END;<br><br>destructor &nbsp;TUSAppBar.Destroy;<br><br>BEGIN<br>AB_Remove;<br>inherited Destroy;<br>END;<br><br>end.<br><br>
 
提问者:<br>如果你还要继续讨论请定期提前你的帖子,如果不想继续讨论请结束帖子。<br>请认真阅读大富翁论坛规则说明 &nbsp;<br><br>http://www.delphibbs.com/delphibbs/rules.htm
 
哇靠,太复杂了。用控件吧,很简单的。我有个源码,你看<br><br>{*****************************************************************************}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ TAppBar Class v1.4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ implements Application Desktop Toolbar &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ (based on J.Richter's CAppBar MFC Class) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ Copyright (c) 1997/98 Paolo Giacomuzzi &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ e-mail: paolo.giacomuzzi@usa.net &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br>{ http://www.geocities.com/SiliconValley/9486 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br>{*****************************************************************************}<br><br><br>unit AppBar;<br><br><br>interface<br><br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Forms, Dialogs, Controls, ExtCtrls,<br>&nbsp; ShellApi, Registry;<br><br><br>const<br>&nbsp; // AppBar's user notification message<br>&nbsp; WM_APPBARNOTIFY = WM_USER + 100;<br><br>&nbsp; // Timer interval<br>&nbsp; SLIDE_DEF_TIMER_INTERVAL = 400; &nbsp;// milliseconds<br><br>&nbsp; // Defaults<br>&nbsp; AB_DEF_SIZE_INC &nbsp;= 1;<br>&nbsp; AB_DEF_DOCK_SIZE = 32;<br>&nbsp; AB_DEF_ROOT_KEY &nbsp;= HKEY_CURRENT_USER;<br>&nbsp; AB_DEF_KEY_NAME &nbsp;= 'Software/AppBar/1.4/Delphi';<br><br><br>type<br>&nbsp; // You can send to the Windows shell one of the following messages:<br>&nbsp; // Message &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Description<br>&nbsp; // -------------- &nbsp; &nbsp; &nbsp;--------------------------------------------------<br>&nbsp; // ABM_NEW &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Register a new AppBar to the system<br>&nbsp; // ABM_REMOVE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Remove a previously created AppBar from the system<br>&nbsp; // ABM_QUERYPOS &nbsp; &nbsp; &nbsp; &nbsp;Query the AppBar position<br>&nbsp; // ABM_SETPOS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Set the AppBar position<br>&nbsp; // ABM_GETSTATE &nbsp; &nbsp; &nbsp; &nbsp;Get the edge the Appbar is docked to<br>&nbsp; // ABM_GETTASKBARPOS &nbsp; Get the Explorer Taskbar position<br>&nbsp; // ABM_ACTIVATE &nbsp; &nbsp; &nbsp; &nbsp;Activate the AppBar<br>&nbsp; // ABM_GETAUTOHIDEBAR &nbsp;Query if AppBar has Auto-hide behavior<br>&nbsp; // ABM_SETAUTOHIDEBAR &nbsp;Set the AppBar's Auto-hide behavior<br><br>&nbsp; // The ABM_message constants are defined in SHELLAPI.PAS as follows:<br>&nbsp; // ABM_NEW &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;= $00000000;<br>&nbsp; // ABM_REMOVE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = $00000001;<br>&nbsp; // ABM_QUERYPOS &nbsp; &nbsp; &nbsp; &nbsp; = $00000002;<br>&nbsp; // ABM_SETPOS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = $00000003;<br>&nbsp; // ABM_GETSTATE &nbsp; &nbsp; &nbsp; &nbsp; = $00000004;<br>&nbsp; // ABM_GETTASKBARPOS &nbsp; &nbsp;= $00000005;<br>&nbsp; // ABM_ACTIVATE &nbsp; &nbsp; &nbsp; &nbsp; = $00000006;<br>&nbsp; // ABM_GETAUTOHIDEBAR &nbsp; = $00000007;<br>&nbsp; // ABM_SETAUTOHIDEBAR &nbsp; = $00000008;<br>&nbsp; // ABM_WINDOWPOSCHANGED = $00000009;<br><br>&nbsp; // The following enumerated type defines the constants in the table<br>&nbsp; TAppBarMessage = (abmNew, abmRemove, abmQueryPos, abmSetPos, abmGetState,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; abmGetTaskBarPos, abmActivate, abmGetAutoHideBar,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; abmSetAutoHideBar, abmWindowPosChanged);<br><br>&nbsp; // An AppBar can be in one of 6 states shown in the table below:<br>&nbsp; // State &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Description<br>&nbsp; // ----------- &nbsp; &nbsp;-----------------------------------------------------<br>&nbsp; // ABE_UNKNOWN &nbsp; &nbsp;The Appbar is in an unknown state<br>&nbsp; // &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(usually during construction/destruction)<br>&nbsp; // ABE_FLOAT &nbsp; &nbsp; &nbsp;The AppBar is floating on the screen<br>&nbsp; // ABE_LEFT &nbsp; &nbsp; &nbsp; The Appbar is docked on the left &nbsp; edge of the screen<br>&nbsp; // ABE_TOP &nbsp; &nbsp; &nbsp; &nbsp;The Appbar is docked on the top &nbsp; &nbsp;edge of the screen<br>&nbsp; // ABE_RIGHT &nbsp; &nbsp; &nbsp;The Appbar is docked on the right &nbsp;edge of the screen<br>&nbsp; // ABE_BOTTOM &nbsp; &nbsp; The Appbar is docked on the bottom edge of the screen<br><br>&nbsp; // The ABE_edge state constants are defined in SHELLAPI.PAS as follows:<br>&nbsp; // ABE_LEFT &nbsp; &nbsp;= 0;<br>&nbsp; // ABE_TOP &nbsp; &nbsp; = 1;<br>&nbsp; // ABE_RIGHT &nbsp; = 2;<br>&nbsp; // ABE_BOTTOM &nbsp;= 3;<br><br>&nbsp; // The ABE_UNKNOWN and ABE_FLOAT constants are defined here as follows:<br>&nbsp; // ABE_UNKNOWN = 4;<br>&nbsp; // ABE_FLOAT &nbsp; = 5;<br><br>&nbsp; // The following enumerated type defines the constants in the table<br>&nbsp; // (Values are mutually exclusive)<br>&nbsp; TAppBarEdge = (abeLeft, abeTop, abeRight, abeBottom, abeUnknown, abeFloat);<br><br>&nbsp; // An AppBar can have several behavior flags as shown below:<br>&nbsp; // Flag &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Description<br>&nbsp; // --------------------------- -----------------------------------<br>&nbsp; // ABF_ALLOWLEFT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Allow dock on left &nbsp; of screen<br>&nbsp; // ABF_ALLOWRIGHT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Allow dock on right &nbsp;of screen<br>&nbsp; // ABF_ALLOWTOP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Allow dock on top &nbsp; &nbsp;of screen<br>&nbsp; // ABF_ALLOWBOTTOM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Allow dock on bottom of screen<br>&nbsp; // ABF_ALLOWFLOAT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Allow float in the middle of screen<br><br>&nbsp; // The following enumerated type defines the constants in the table<br>&nbsp; TAppBarFlag = (abfAllowLeft, abfAllowTop, abfAllowRight, abfAllowBottom,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;abfAllowFloat);<br>&nbsp; TAppBarFlags = set of TAppBarFlag;<br><br>&nbsp; // The following enumerated type defines the AppBar behavior in the Taskbar<br>&nbsp; TAppBarTaskEntry = (abtShow, abtHide, abtFloatDependent);<br><br>&nbsp; // The record below contains all of the AppBar settings that<br>&nbsp; // can be saved/loaded in/from the Registry<br>&nbsp; TAppBarSettings = record<br>&nbsp; &nbsp; cbSize &nbsp; &nbsp; &nbsp; &nbsp; : DWORD; &nbsp; &nbsp; &nbsp; &nbsp;// Size of this structure<br>&nbsp; &nbsp; abEdge &nbsp; &nbsp; &nbsp; &nbsp; : TAppBarEdge; &nbsp;// ABE_UNKNOWN, ABE_FLOAT, or ABE_edge<br>&nbsp; &nbsp; abFlags &nbsp; &nbsp; &nbsp; &nbsp;: TAppBarFlags; // ABF_* flags<br>&nbsp; &nbsp; bAutohide &nbsp; &nbsp; &nbsp;: Boolean; &nbsp; &nbsp; &nbsp;// Should AppBar be auto-hidden when docked?<br>&nbsp; &nbsp; bAlwaysOnTop &nbsp; : Boolean; &nbsp; &nbsp; &nbsp;// Should AppBar always be on top?<br>&nbsp; &nbsp; bSlideEffect &nbsp; : Boolean; &nbsp; &nbsp; &nbsp;// Should AppBar slide?<br>&nbsp; &nbsp; nTimerInterval : Integer; &nbsp; &nbsp; &nbsp;// Slide Timer Interval (determines speed)<br>&nbsp; &nbsp; szSizeInc &nbsp; &nbsp; &nbsp;: TSize; &nbsp; &nbsp; &nbsp; &nbsp;// Discrete width/height size increments<br>&nbsp; &nbsp; szDockSize &nbsp; &nbsp; : TSize; &nbsp; &nbsp; &nbsp; &nbsp;// Width/Height for docked bar<br>&nbsp; &nbsp; rcFloat &nbsp; &nbsp; &nbsp; &nbsp;: TRect; &nbsp; &nbsp; &nbsp; &nbsp;// Floating rectangle in screen coordinates<br>&nbsp; &nbsp; nMinWidth &nbsp; &nbsp; &nbsp;: Integer; &nbsp; &nbsp; &nbsp;// Min allowed width<br>&nbsp; &nbsp; nMinHeight &nbsp; &nbsp; : Integer; &nbsp; &nbsp; &nbsp;// Min allowed height<br>&nbsp; &nbsp; nMaxWidth &nbsp; &nbsp; &nbsp;: Integer; &nbsp; &nbsp; &nbsp;// Max allowed width<br>&nbsp; &nbsp; nMaxHeight &nbsp; &nbsp; : Integer; &nbsp; &nbsp; &nbsp;// Max allowed height<br>&nbsp; &nbsp; szMinDockSize &nbsp;: TSize; &nbsp; &nbsp; &nbsp; &nbsp;// Min Width/Height when docked<br>&nbsp; &nbsp; szMaxDockSize &nbsp;: TSize; &nbsp; &nbsp; &nbsp; &nbsp;// Max Width/Height when docked<br>&nbsp; &nbsp; abTaskEntry &nbsp; &nbsp;: TAppBarTaskEntry; // AppBar behavior in the Taskbar<br>&nbsp; end;<br><br>&nbsp; // The record below contains the settings location in the registry<br>&nbsp; TAppBarSettingsLocation = record<br>&nbsp; &nbsp; nRootKey : Integer; &nbsp;// HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE<br>&nbsp; &nbsp; KeyName &nbsp;: String; &nbsp; // Key Name starting from root<br>&nbsp; end;<br><br>&nbsp; // TAppBar class ////////////////////////////////////////////////////////////<br>&nbsp; TAppBar = class(TForm)<br><br>&nbsp; private<br><br>&nbsp; { Internal implementation state variables }<br><br>&nbsp; &nbsp; // This AppBar's settings info<br>&nbsp; &nbsp; FABS : TAppBarSettings;<br><br>&nbsp; &nbsp; // We need a member variable which tracks the proposed edge of the<br>&nbsp; &nbsp; // AppBar while the user is moving it, deciding where to position it.<br>&nbsp; &nbsp; // While not moving, this member must contain ABE_UNKNOWN so that<br>&nbsp; &nbsp; // GetEdge returns the current edge contained in FABS.abEdge.<br>&nbsp; &nbsp; // While moving the AppBar, FabEdgeProposedPrev contains the<br>&nbsp; &nbsp; // proposed edge based on the position of the AppBar. &nbsp;The proposed<br>&nbsp; &nbsp; // edge becomes the new edge when the user stops moving the AppBar.<br>&nbsp; &nbsp; FabEdgeProposedPrev : TAppBarEdge;<br><br>&nbsp; &nbsp; // We need a member variable which tracks whether a full screen<br>&nbsp; &nbsp; // application window is open<br>&nbsp; &nbsp; FbFullScreenAppOpen : Boolean;<br><br>&nbsp; &nbsp; // We need a member variable which tracks whether our autohide window<br>&nbsp; &nbsp; // is visible or not<br>&nbsp; &nbsp; FbAutoHideIsVisible : Boolean;<br><br>&nbsp; &nbsp; // We need a timer to to determine when the AppBar should be re-hidden<br>&nbsp; &nbsp; FTimer : TTimer;<br><br>&nbsp; &nbsp; // We need a member variable to store the settings location in the registry<br>&nbsp; &nbsp; FabSettingsLocation : TAppBarSettingsLocation;<br><br>&nbsp; { Internal implementation functions }<br><br>&nbsp; &nbsp; // Modifies window creation flags<br>&nbsp; &nbsp; procedure CreateParams (var Params: TCreateParams); override;<br><br>&nbsp; &nbsp; // These functions encapsulate the shell's SHAppBarMessage function<br>&nbsp; &nbsp; function AppBarMessage (abMessage : TAppBarMessage;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; abEdge &nbsp; &nbsp;: TAppBarEdge;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lParam &nbsp; &nbsp;: LPARAM;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bRect &nbsp; &nbsp; : Boolean;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var rc &nbsp; &nbsp;: TRect) : UINT;<br><br>&nbsp; &nbsp; function AppBarMessage1 (abMessage : TAppBarMessage) : UINT;<br><br>&nbsp; &nbsp; function AppBarMessage2 (abMessage : TAppBarMessage;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;abEdge &nbsp; &nbsp;: TAppBarEdge) : UINT;<br><br>&nbsp; &nbsp; function AppBarMessage3 (abMessage : TAppBarMessage;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;abEdge &nbsp; &nbsp;: TAppBarEdge;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lParam &nbsp; &nbsp;: LPARAM) : UINT;<br><br>&nbsp; &nbsp; function AppBarMessage4 (abMessage : TAppBarMessage;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;abEdge &nbsp; &nbsp;: TAppBarEdge;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lParam &nbsp; &nbsp;: LPARAM;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var rc &nbsp; &nbsp;: TRect) : UINT;<br><br>&nbsp; &nbsp; // Gets a edge (ABE_FLOAT or ABE_edge) from a point (screen coordinates)<br>&nbsp; &nbsp; function CalcProposedState (var pt : TSmallPoint) : TAppBarEdge;<br><br>&nbsp; &nbsp; // Gets a retangle position (screen coordinates) from a proposed state<br>&nbsp; &nbsp; procedure GetRect (abEdgeProposed : TAppBarEdge; var rcProposed : TRect);<br><br>&nbsp; &nbsp; // Adjusts the AppBar's location to account for autohide<br>&nbsp; &nbsp; // Returns TRUE if rectangle was adjusted<br>&nbsp; &nbsp; function AdjustLocationForAutohide (bShow &nbsp;: Boolean;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var rc : TRect) : Boolean;<br><br>&nbsp; &nbsp; // If AppBar is Autohide and docked, shows/hides the AppBar<br>&nbsp; &nbsp; procedure ShowHiddenAppBar (bShow : Boolean);<br><br>&nbsp; &nbsp; // When Autohide AppBar is shown/hidden, slides in/out of view<br>&nbsp; &nbsp; procedure SlideWindow (var rcEnd : TRect);<br><br>&nbsp; &nbsp; // Returns which edge we're autohidden on or ABE_UNKNOWN<br>&nbsp; &nbsp; function GetAutohideEdge : TAppBarEdge;<br><br>&nbsp; &nbsp; // Returns a TSmallPoint that gives the cursor position in screen coords<br>&nbsp; &nbsp; function GetMessagePosition : TSmallPoint;<br><br>&nbsp; &nbsp; // Changes the style of a window (translated from AfxModifyStyle)<br>&nbsp; &nbsp; function ModifyStyle (hWnd &nbsp; &nbsp; &nbsp; &nbsp; : THandle;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nStyleOffset : Integer;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwRemove &nbsp; &nbsp; : DWORD;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwAdd &nbsp; &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nFlags &nbsp; &nbsp; &nbsp; : UINT) : Boolean;<br><br>&nbsp; protected<br><br>&nbsp; { Property selector functions }<br><br>&nbsp; &nbsp; // Retrieves the AppBar's edge. &nbsp;If the AppBar is being positioned, its<br>&nbsp; &nbsp; // proposed state is returned instead<br>&nbsp; &nbsp; function GetEdge : TAppBarEdge;<br><br>&nbsp; &nbsp; // Changes the AppBar's edge to ABE_UNKNOWN, ABE_FLOAT or an ABE_edge<br>&nbsp; &nbsp; procedure SetEdge (abEdge : TAppBarEdge);<br><br>&nbsp; &nbsp; // Changes the slide time interval<br>&nbsp; &nbsp; procedure SetSlideTime (nInterval : Integer);<br><br>&nbsp; { Overridable functions }<br><br>&nbsp; &nbsp; // Called when the AppBar's proposed state changes<br>&nbsp; &nbsp; procedure OnAppBarStateChange (bProposed &nbsp; &nbsp; &nbsp;: Boolean;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;abEdgeProposed : TAppBarEdge); virtual;<br><br>&nbsp; &nbsp; // Called if user attempts to dock an Autohide AppBar on<br>&nbsp; &nbsp; // an edge that already contains an Autohide AppBar<br>&nbsp; &nbsp; procedure OnAppBarForcedToDocked; virtual;<br><br>&nbsp; &nbsp; // Called when AppBar gets an ABN_FULLSCREENAPP notification<br>&nbsp; &nbsp; procedure OnABNFullScreenApp (bOpen : Boolean); virtual;<br><br>&nbsp; &nbsp; // Called when AppBar gets an ABN_POSCHANGED notification<br>&nbsp; &nbsp; procedure OnABNPosChanged; virtual;<br><br>&nbsp; &nbsp; // Called when AppBar gets an ABN_WINDOWARRANGE notification<br>&nbsp; &nbsp; procedure OnABNWindowArrange (bBeginning : Boolean); virtual;<br><br>&nbsp; { Message handlers }<br><br>&nbsp; &nbsp; // Called when the AppBar receives a WM_APPBARNOTIFY window message<br>&nbsp; &nbsp; procedure OnAppBarCallbackMsg(var Msg : TMessage); message WM_APPBARNOTIFY;<br><br>&nbsp; &nbsp; // Called when the AppBar form is first created<br>&nbsp; &nbsp; procedure OnCreate (var Msg: TWMCreate); message WM_CREATE;<br><br>&nbsp; &nbsp; // Called when the AppBar form is about to be destroyed<br>&nbsp; &nbsp; procedure OnDestroy (var Msg : TWMDestroy); message WM_DESTROY;<br><br>&nbsp; &nbsp; // Called when the AppBar receives a WM_WINDOWPOSCHANGED message<br>&nbsp; &nbsp; procedure OnWindowPosChanged (var Msg : TWMWindowPosChanged);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;message WM_WINDOWPOSCHANGED;<br><br>&nbsp; &nbsp; // Called when the AppBar receives a WM_ACTIVATE message<br>&nbsp; &nbsp; procedure OnActivate (var Msg : TWMActivate); message WM_ACTIVATE;<br><br>&nbsp; &nbsp; // Called every timer tick<br>&nbsp; &nbsp; procedure OnAppBarTimer (Sender : TObject);<br><br>&nbsp; &nbsp; // Called when the AppBar receives a WM_NCMOUSEMOVE message<br>&nbsp; &nbsp; procedure OnNcMouseMove (var Msg : TWMNCMouseMove); message WM_NCMOUSEMOVE;<br><br>&nbsp; &nbsp; // Called when the AppBar receives a WM_NCHITTEST message<br>&nbsp; &nbsp; procedure OnNcHitTest (var Msg: TWMNCHitTest); message WM_NCHITTEST;<br><br>&nbsp; &nbsp; // Called when the AppBar receives a WM_ENTERSIZEMOVE message<br>&nbsp; &nbsp; procedure OnEnterSizeMove (var Msg : TMessage); message WM_ENTERSIZEMOVE;<br><br>&nbsp; &nbsp; // Called when the AppBar receives a WM_EXITSIZEMOVE message<br>&nbsp; &nbsp; procedure OnExitSizeMove (var Msg : TMessage); message WM_EXITSIZEMOVE;<br><br>&nbsp; &nbsp; // Called when the AppBar receives a WM_MOVING message<br>&nbsp; &nbsp; procedure OnMoving (var Msg : TMessage); message WM_MOVING;<br><br>&nbsp; &nbsp; // Called when the AppBar receives a WM_SIZING message<br>&nbsp; &nbsp; procedure OnSizing (var Msg : TMessage); message WM_SIZING;<br><br>&nbsp; &nbsp; // Called when the AppBar receives a WM_GETMINMAXINFO message<br>&nbsp; &nbsp; procedure OnGetMinMaxInfo (var Msg : TWMGetMinMaxInfo);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; message WM_GETMINMAXINFO;<br><br>&nbsp; { AppBar-specific helper functions }<br><br>&nbsp; &nbsp; // Returns TRUE if abEdge is ABE_LEFT or ABE_RIGHT, else FALSE is returned<br>&nbsp; &nbsp; function IsEdgeLeftOrRight (abEdge : TAppBarEdge) : Boolean;<br><br>&nbsp; &nbsp; // Returns TRUE if abEdge is ABE_TOP or ABE_BOTTOM, else FALSE is returned<br>&nbsp; &nbsp; function IsEdgeTopOrBottom (abEdge : TAppBarEdge) : Boolean;<br><br>&nbsp; &nbsp; // Returns TRUE if abEdge is ABE_FLOAT, else FALSE is returned<br>&nbsp; &nbsp; function IsFloating (abEdge : TAppBarEdge) : Boolean;<br><br>&nbsp; &nbsp; // Returns TRUE if abFlags contain an at least allowed edge to dock on<br>&nbsp; &nbsp; function IsDockable (abFlags : TAppBarFlags) : Boolean;<br><br>&nbsp; &nbsp; // Returns TRUE if abFlags contain abfAllowLeft and abfAllowRight<br>&nbsp; &nbsp; function IsDockableVertically (abFlags : TAppBarFlags) : Boolean;<br><br>&nbsp; &nbsp; // Returns TRUE if abFlags contain abfAllowTop and abfAllowBottom<br>&nbsp; &nbsp; function IsDockableHorizontally (abFlags : TAppBarFlags) : Boolean;<br><br>&nbsp; &nbsp; // Forces the shell to update its AppBar list and the workspace area<br>&nbsp; &nbsp; procedure ResetSystemKnowledge;<br><br>&nbsp; &nbsp; // Returns a proposed edge or ABE_FLOAT based on ABF_* flags and a<br>&nbsp; &nbsp; // point specified in screen coordinates<br>&nbsp; &nbsp; function GetEdgeFromPoint (abFlags : TAppBarFlags;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pt &nbsp; &nbsp; &nbsp;: TSmallPoint) : TAppBarEdge;<br><br>&nbsp; public<br><br>&nbsp; { Public member functions }<br><br>&nbsp; &nbsp; // Constructs an AppBar<br>&nbsp; &nbsp; constructor Create (Owner : TComponent); override;<br><br>&nbsp; &nbsp; // Destroys a previously created AppBar<br>&nbsp; &nbsp; destructor Destroy; override;<br><br>&nbsp; &nbsp; // Forces the AppBar's visual appearance to match its internal state<br>&nbsp; &nbsp; procedure UpdateBar; virtual;<br><br>&nbsp; &nbsp; // Loads settings from the registry at RootKey and KeyName location.<br>&nbsp; &nbsp; // Returns TRUE if the settings are available, else FALSE<br>&nbsp; &nbsp; function LoadSettings : Boolean; virtual;<br><br>&nbsp; &nbsp; // Saves settings into the registry at RootKey and KeyName location.<br>&nbsp; &nbsp; // Returns TRUE if succeeded, else FALSE<br>&nbsp; &nbsp; function SaveSettings : Boolean; virtual;<br><br>&nbsp; published<br><br>&nbsp; { Properties }<br><br>&nbsp; &nbsp; // Allowed dockable edges<br>&nbsp; &nbsp; property Flags : TAppBarFlags read FABS.abFlags write FABS.abFlags;<br><br>&nbsp; &nbsp; // Horizontal size increment<br>&nbsp; &nbsp; property HorzSizeInc : Integer read &nbsp;FABS.szSizeInc.cx<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write FABS.szSizeInc.cx;<br>&nbsp; &nbsp; // Vertical size increment<br>&nbsp; &nbsp; property VertSizeInc : Integer read &nbsp;FABS.szSizeInc.cy<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write FABS.szSizeInc.cy;<br>&nbsp; &nbsp; // Edge to dock on<br>&nbsp; &nbsp; property Edge : TAppBarEdge read GetEdge write SetEdge;<br><br>&nbsp; &nbsp; // Auto-hide On/Off<br>&nbsp; &nbsp; property AutoHide : Boolean read FABS.bAutohide write FABS.bAutohide;<br><br>&nbsp; &nbsp; // Always On Top On/Off<br>&nbsp; &nbsp; property AlwaysOnTop : Boolean read &nbsp;FABS.bAlwaysOnTop<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write FABS.bAlwaysOnTop;<br>&nbsp; &nbsp; // Slide Effect On/Off<br>&nbsp; &nbsp; property SlideEffect : Boolean read &nbsp;FABS.bSlideEffect<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write FABS.bSlideEffect;<br>&nbsp; &nbsp; // Slide Time<br>&nbsp; &nbsp; property SlideTime : Integer read FABS.nTimerInterval write SetSlideTime;<br><br>&nbsp; &nbsp; // Horizontal size when docked on left or right<br>&nbsp; &nbsp; property HorzDockSize : Integer read &nbsp;FABS.szDockSize.cy<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; write FABS.szDockSize.cy;<br><br>&nbsp; &nbsp; // Vertical size when docked on top or bottom<br>&nbsp; &nbsp; property VertDockSize : Integer read &nbsp;FABS.szDockSize.cx<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; write FABS.szDockSize.cx;<br><br>&nbsp; &nbsp; // AppBar coordinates when floating<br>&nbsp; &nbsp; property FloatLeft &nbsp; : Integer read &nbsp;FABS.rcFloat.Left<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write FABS.rcFloat.Left;<br>&nbsp; &nbsp; property FloatTop &nbsp; &nbsp;: Integer read &nbsp;FABS.rcFloat.Top<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write FABS.rcFloat.Top;<br>&nbsp; &nbsp; property FloatRight &nbsp;: Integer read &nbsp;FABS.rcFloat.Right<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write FABS.rcFloat.Right;<br>&nbsp; &nbsp; property FloatBottom : Integer read &nbsp;FABS.rcFloat.Bottom<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write FABS.rcFloat.Bottom;<br><br>&nbsp; &nbsp; // AppBar MinMax dimensions when floating<br>&nbsp; &nbsp; property MinWidth &nbsp;: Integer read FABS.nMinWidth &nbsp;write FABS.nMinWidth;<br>&nbsp; &nbsp; property MinHeight : Integer read FABS.nMinHeight write FABS.nMinHeight;<br>&nbsp; &nbsp; property MaxWidth &nbsp;: Integer read FABS.nMaxWidth &nbsp;write FABS.nMaxWidth;<br>&nbsp; &nbsp; property MaxHeight : Integer read FABS.nMaxHeight write FABS.nMaxHeight;<br><br>&nbsp; &nbsp; // Min Height when docked horizontally<br>&nbsp; &nbsp; property MinHorzDockSize : Integer read &nbsp;FABS.szMinDockSize.cy<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write FABS.szMinDockSize.cy;<br><br>&nbsp; &nbsp; // Min Width when docked vertically<br>&nbsp; &nbsp; property MinVertDockSize : Integer read &nbsp;FABS.szMinDockSize.cx<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write FABS.szMinDockSize.cx;<br><br>&nbsp; &nbsp; // Max Height when docked horizontally<br>&nbsp; &nbsp; property MaxHorzDockSize : Integer read &nbsp;FABS.szMaxDockSize.cy<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write FABS.szMaxDockSize.cy;<br><br>&nbsp; &nbsp; // Max Width when docked vertically<br>&nbsp; &nbsp; property MaxVertDockSize : Integer read &nbsp;FABS.szMaxDockSize.cx<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write FABS.szMaxDockSize.cx;<br><br>&nbsp; &nbsp; // AppBar behavior in the Window Taskbar<br>&nbsp; &nbsp; property TaskEntry : TAppBarTaskEntry read &nbsp;FABS.abTaskEntry<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; write FABS.abTaskEntry;<br><br>&nbsp; &nbsp; // RootKey in the registry where settings should be loaded/saved<br>&nbsp; &nbsp; property RootKey : Integer read &nbsp;FabSettingsLocation.nRootKey<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write FabSettingsLocation.nRootKey;<br><br>&nbsp; &nbsp; // KeyName in the registry where settings should be loaded/saved<br>&nbsp; &nbsp; property KeyName : String read &nbsp;FabSettingsLocation.KeyName<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; write FabSettingsLocation.KeyName;<br><br>&nbsp; end;<br><br><br>implementation<br><br><br>{ Internal implementation functions }<br><br><br>// TAppBar.CreateParams ///////////////////////////////////////////////////////<br>procedure TAppBar.CreateParams (var Params: TCreateParams);<br>var<br>&nbsp; dwAdd, dwRemove, dwAddEx, dwRemoveEx : DWORD;<br>begin<br>&nbsp; // Call the inherited first<br>&nbsp; inherited CreateParams(Params);<br><br>&nbsp; // Styles to be added<br>&nbsp; dwAdd := 0;<br>&nbsp; dwAddEx := WS_EX_TOOLWINDOW;<br><br>&nbsp; // Styles to be removed<br>&nbsp; dwRemove := WS_SYSMENU or WS_MAXIMIZEBOX or WS_MINIMIZEBOX;<br>&nbsp; dwRemoveEx := WS_EX_APPWINDOW;<br><br>&nbsp; // Modify style flags<br>&nbsp; with Params do begin<br>&nbsp; &nbsp; Style := Style and (not dwRemove);<br>&nbsp; &nbsp; Style := Style or dwAdd;<br>&nbsp; &nbsp; ExStyle := ExStyle and (not dwRemoveEx);<br>&nbsp; &nbsp; ExStyle := ExStyle or dwAddEx;<br>&nbsp; end;<br>end;<br><br><br>// TAppBar.AppBarMessage //////////////////////////////////////////////////////<br>function TAppBar.AppBarMessage (abMessage : TAppBarMessage;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; abEdge &nbsp; &nbsp;: TAppBarEdge;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lParam &nbsp; &nbsp;: LPARAM;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bRect &nbsp; &nbsp; : Boolean;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var rc &nbsp; &nbsp;: TRect) : UINT;<br>var<br>&nbsp; abd : TAppBarData;<br>begin<br>&nbsp; // Initialize an APPBARDATA structure<br>&nbsp; abd.cbSize := sizeof(abd);<br>&nbsp; abd.hWnd := Handle;<br>&nbsp; abd.uCallbackMessage := WM_APPBARNOTIFY;<br>&nbsp; abd.uEdge := Ord(abEdge);<br>&nbsp; if bRect then<br>&nbsp; &nbsp; abd.rc := rc<br>&nbsp; else<br>&nbsp; &nbsp; abd.rc := Rect(0, 0, 0, 0);<br>&nbsp; abd.lParam := lParam;<br>&nbsp; Result := SHAppBarMessage(Ord(abMessage), abd);<br><br>&nbsp; // If the caller passed a rectangle, return the updated rectangle<br>&nbsp; if bRect then<br>&nbsp; &nbsp; rc := abd.rc;<br>end;<br><br><br>// TAppBar.AppBarMessage1 /////////////////////////////////////////////////////<br>function TAppBar.AppBarMessage1 (abMessage : TAppBarMessage) : UINT;<br>var<br>&nbsp; rc : TRect;<br>begin<br>&nbsp; Result := AppBarMessage(abMessage, abeFloat, 0, False, rc);<br>end;<br><br><br>// TAppBar.AppBarMessage2 /////////////////////////////////////////////////////<br>function TAppBar.AppBarMessage2 (abMessage : TAppBarMessage;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;abEdge &nbsp; &nbsp;: TAppBarEdge) : UINT;<br>var<br>&nbsp; rc : TRect;<br>begin<br>&nbsp; Result := AppBarMessage(abMessage, abEdge, 0, False, rc);<br>end;<br><br><br>// TAppBar.AppBarMessage3 /////////////////////////////////////////////////////<br>function TAppBar.AppBarMessage3 (abMessage : TAppBarMessage;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;abEdge &nbsp; &nbsp;: TAppBarEdge;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lParam &nbsp; &nbsp;: LPARAM) : UINT;<br>var<br>&nbsp; rc : TRect;<br>begin<br>&nbsp; Result := AppBarMessage(abMessage, abEdge, lParam, False, rc);<br>end;<br><br><br>// TAppBar.AppBarMessage4 /////////////////////////////////////////////////////<br>function TAppBar.AppBarMessage4 (abMessage : TAppBarMessage;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;abEdge &nbsp; &nbsp;: TAppBarEdge;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lParam &nbsp; &nbsp;: LPARAM;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var rc &nbsp; &nbsp;: TRect) : UINT;<br>begin<br>&nbsp; Result := AppBarMessage(abMessage, abEdge, lParam, True, rc);<br>end;<br><br><br>// TAppBar.CalcProposedState //////////////////////////////////////////////////<br>function TAppBar.CalcProposedState (var pt : TSmallPoint) : TAppBarEdge;<br>var<br>&nbsp; bForceFloat : Boolean;<br>begin<br>&nbsp; // Force the AppBar to float if the user is holding down the Ctrl key<br>&nbsp; // and the AppBar's style allows floating<br>&nbsp; bForceFloat := ((GetKeyState(VK_CONTROL) and $8000) &lt;&gt; 0) and<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(abfAllowFloat in FABS.abFlags);<br>&nbsp; if bForceFloat then<br>&nbsp; &nbsp; Result := abeFloat<br>&nbsp; else<br>&nbsp; &nbsp; Result := GetEdgeFromPoint(FABS.abFlags, pt);<br>end;<br><br><br>// TAppBar.GetRect ////////////////////////////////////////////////////////////<br>procedure TAppBar.GetRect (abEdgeProposed : TAppBarEdge;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var rcProposed : TRect);<br>begin<br>&nbsp; // This function finds the x, y, cx, cy of the AppBar window<br>&nbsp; if abEdgeProposed = abeFloat then begin<br>&nbsp; &nbsp; // The AppBar is floating, the proposed rectangle is correct<br>&nbsp; end else begin<br>&nbsp; &nbsp; // The AppBar is docked or auto-hide<br>&nbsp; &nbsp; // Set dimensions to full screen<br>&nbsp; &nbsp; with rcProposed do begin<br>&nbsp; &nbsp; &nbsp; Left &nbsp; := 0;<br>&nbsp; &nbsp; &nbsp; Top &nbsp; &nbsp;:= 0;<br>&nbsp; &nbsp; &nbsp; Right &nbsp;:= GetSystemMetrics(SM_CXSCREEN);<br>&nbsp; &nbsp; &nbsp; Bottom := GetSystemMetrics(SM_CYSCREEN);<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; // Subtract off what we want from the full screen dimensions<br>&nbsp; &nbsp; if not FABS.bAutohide then<br>&nbsp; &nbsp; &nbsp; // Ask the shell where we can dock<br>&nbsp; &nbsp; &nbsp; AppBarMessage4(abmQueryPos, abEdgeProposed, LPARAM(False), rcProposed);<br><br>&nbsp; &nbsp; case abEdgeProposed of<br>&nbsp; &nbsp; &nbsp; abeLeft:<br>&nbsp; &nbsp; &nbsp; &nbsp; rcProposed.Right &nbsp;:= rcProposed.Left &nbsp; + FABS.szDockSize.cx;<br>&nbsp; &nbsp; &nbsp; abeTop:<br>&nbsp; &nbsp; &nbsp; &nbsp; rcProposed.Bottom := rcProposed.Top &nbsp; &nbsp;+ FABS.szDockSize.cy;<br>&nbsp; &nbsp; &nbsp; abeRight:<br>&nbsp; &nbsp; &nbsp; &nbsp; rcProposed.Left &nbsp; := rcProposed.Right &nbsp;- FABS.szDockSize.cx;<br>&nbsp; &nbsp; &nbsp; abeBottom:<br>&nbsp; &nbsp; &nbsp; &nbsp; rcProposed.Top &nbsp; &nbsp;:= rcProposed.Bottom - FABS.szDockSize.cy;<br>&nbsp; &nbsp; end; // end of case<br><br>&nbsp; end; // end of else<br>end;<br><br><br>// TAppBar.AdjustLocationForAutohide //////////////////////////////////////////<br>function TAppBar.AdjustLocationForAutohide (bShow &nbsp;: Boolean;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var rc : TRect) : Boolean;<br>var<br>&nbsp; x, y : Integer;<br>&nbsp; cxVisibleBorder, cyVisibleBorder : Integer;<br>begin<br>&nbsp; if ((GetEdge = abeUnknown) or (GetEdge = abeFloat) or<br>&nbsp; &nbsp; &nbsp; (not FABS.bAutohide)) then begin<br>&nbsp; &nbsp; // If we are not docked on an edge OR we are not auto-hidden, there is<br>&nbsp; &nbsp; // nothing for us to do; just return<br>&nbsp; &nbsp; Result := False;<br>&nbsp; &nbsp; Exit;<br>&nbsp; end;<br><br>&nbsp; // Showing/hiding doesn't change our size; only our position<br>&nbsp; x := 0; y := 0; // Assume a position of (0, 0)<br><br>&nbsp; if bShow then<br>&nbsp; &nbsp; // If we are on the right or bottom, calculate our visible position<br>&nbsp; &nbsp; case GetEdge of<br>&nbsp; &nbsp; &nbsp; abeRight:<br>&nbsp; &nbsp; &nbsp; &nbsp; x := GetSystemMetrics(SM_CXSCREEN) - (rc.Right - rc.Left);<br>&nbsp; &nbsp; &nbsp; abeBottom:<br>&nbsp; &nbsp; &nbsp; &nbsp; y := GetSystemMetrics(SM_CYSCREEN) - (rc.Bottom - rc.Top);<br>&nbsp; &nbsp; end<br>&nbsp; else begin<br>&nbsp; &nbsp; // Keep a part of the AppBar visible at all times<br>&nbsp; &nbsp; cxVisibleBorder := 2 * GetSystemMetrics(SM_CXBORDER);<br>&nbsp; &nbsp; cyVisibleBorder := 2 * GetSystemMetrics(SM_CYBORDER);<br><br>&nbsp; &nbsp; // Calculate our x or y coordinate so that only the border is visible<br>&nbsp; &nbsp; case GetEdge of<br>&nbsp; &nbsp; &nbsp; abeLeft:<br>&nbsp; &nbsp; &nbsp; &nbsp; x := -((rc.Right - rc.Left) - cxVisibleBorder);<br>&nbsp; &nbsp; &nbsp; abeRight:<br>&nbsp; &nbsp; &nbsp; &nbsp; x := GetSystemMetrics(SM_CXSCREEN) - cxVisibleBorder;<br>&nbsp; &nbsp; &nbsp; abeTop:<br>&nbsp; &nbsp; &nbsp; &nbsp; y := -((rc.Bottom - rc.Top) - cyVisibleBorder);<br>&nbsp; &nbsp; &nbsp; abeBottom:<br>&nbsp; &nbsp; &nbsp; &nbsp; y := GetSystemMetrics(SM_CYSCREEN) - cyVisibleBorder;<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br><br>&nbsp; with rc do begin<br>&nbsp; &nbsp; Right &nbsp;:= x + (Right - Left);<br>&nbsp; &nbsp; Bottom := y + (Bottom - Top);<br>&nbsp; &nbsp; Left &nbsp; := x;<br>&nbsp; &nbsp; Top &nbsp; &nbsp;:= y;<br>&nbsp; end;<br><br>&nbsp; Result := True;<br>end;<br><br><br>// TAppBar.ShowHiddenAppBar ///////////////////////////////////////////////////<br>procedure TAppBar.ShowHiddenAppBar (bShow : Boolean);<br>var<br>&nbsp; rc : TRect;<br>begin<br>&nbsp; // Get our window location in screen coordinates<br>&nbsp; GetWindowRect(Handle, rc);<br><br>&nbsp; // Assume &nbsp;that we are visible<br>&nbsp; FbAutoHideIsVisible := True;<br><br>&nbsp; if AdjustLocationForAutohide(bShow, rc) then begin<br>&nbsp; &nbsp; // the rectangle was adjusted, we are an autohide bar<br>&nbsp; &nbsp; // Remember whether we are visible or not<br>&nbsp; &nbsp; FbAutoHideIsVisible := bShow;<br><br>&nbsp; &nbsp; // Slide window in from or out to the edge<br>&nbsp; &nbsp; SlideWindow(rc);<br>&nbsp; end;<br>end;<br><br><br>// TAppBar.SlideWindow ////////////////////////////////////////////////////////<br>procedure TAppBar.SlideWindow (var rcEnd : TRect);<br>var<br>&nbsp; bFullDragOn : LongBool;<br>&nbsp; rcStart : TRect;<br>&nbsp; dwTimeStart, dwTimeEnd, dwTime : DWORD;<br>&nbsp; x, y, w, h : Integer;<br>begin<br>&nbsp; // Only slide the window if the user has FullDrag turned on<br>&nbsp; SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @bFullDragOn, 0);<br><br>&nbsp; // Get the current window position<br>&nbsp; GetWindowRect(Handle, rcStart);<br>&nbsp; if (FABS.bSlideEffect and bFullDragOn and<br>&nbsp; &nbsp; &nbsp; ((rcStart.Left &nbsp; &lt;&gt; rcEnd.Left &nbsp;) or<br>&nbsp; &nbsp; &nbsp; &nbsp;(rcStart.Top &nbsp; &nbsp;&lt;&gt; rcEnd.Top &nbsp; ) or<br>&nbsp; &nbsp; &nbsp; &nbsp;(rcStart.Right &nbsp;&lt;&gt; rcEnd.Right ) or<br>&nbsp; &nbsp; &nbsp; &nbsp;(rcStart.Bottom &lt;&gt; rcEnd.Bottom))) then begin<br><br>&nbsp; &nbsp; // Get our starting and ending time<br>&nbsp; &nbsp; dwTimeStart := GetTickCount;<br>&nbsp; &nbsp; dwTimeEnd := dwTimeStart + FABS.nTimerInterval;<br>&nbsp; &nbsp; dwTime := dwTimeStart;<br>&nbsp; &nbsp; while (dwTime &lt; dwTimeEnd) do begin<br>&nbsp; &nbsp; &nbsp; // While we are still sliding, calculate our new position<br>&nbsp; &nbsp; &nbsp; x := rcStart.Left - (rcStart.Left - rcEnd.Left)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Integer(dwTime - dwTimeStart) div FABS.nTimerInterval;<br><br>&nbsp; &nbsp; &nbsp; y := rcStart.Top &nbsp;- (rcStart.Top &nbsp;- rcEnd.Top)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Integer(dwTime - dwTimeStart) div FABS.nTimerInterval;<br><br>&nbsp; &nbsp; &nbsp; w := (rcStart.Right - rcStart.Left)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- ((rcStart.Right - rcStart.Left) - (rcEnd.Right - rcEnd.Left))<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Integer(dwTime - dwTimeStart) div FABS.nTimerInterval;<br><br>&nbsp; &nbsp; &nbsp; h := (rcStart.Bottom - rcStart.Top)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- ((rcStart.Bottom - rcStart.Top) - (rcEnd.Bottom - rcEnd.Top))<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Integer(dwTime - dwTimeStart) div FABS.nTimerInterval;<br><br>&nbsp; &nbsp; &nbsp; // Show the window at its changed position<br>&nbsp; &nbsp; &nbsp; SetWindowPos(Handle, 0, x, y, w, h,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SWP_NOZORDER or SWP_NOACTIVATE or SWP_DRAWFRAME);<br>&nbsp; &nbsp; &nbsp; UpdateWindow(Handle);<br>&nbsp; &nbsp; &nbsp; dwTime := GetTickCount;<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br><br>&nbsp; // Make sure that the window is at its final position<br>&nbsp; Left &nbsp; := rcEnd.Left;<br>&nbsp; Top &nbsp; &nbsp;:= rcEnd.Top;<br>&nbsp; Width &nbsp;:= rcEnd.Right - rcEnd.Left;<br>&nbsp; Height := rcEnd.Bottom - rcEnd.Top;<br>end;<br><br><br>// TAppBar.GetAutohideEdge ////////////////////////////////////////////////////<br>function TAppBar.GetAutohideEdge : TAppBarEdge;<br>begin<br>&nbsp; if Handle = AppBarMessage2(abmGetAutoHideBar, abeLeft) then<br>&nbsp; &nbsp; Result := abeLeft<br>&nbsp; else if Handle = AppBarMessage2(abmGetAutoHideBar, abeTop) then<br>&nbsp; &nbsp; Result := abeTop<br>&nbsp; else if Handle = AppBarMessage2(abmGetAutoHideBar, abeRight) then<br>&nbsp; &nbsp; Result := abeRight<br>&nbsp; else if Handle = AppBarMessage2(abmGetAutoHideBar, abeBottom) then<br>&nbsp; &nbsp; Result := abeBottom<br>&nbsp; else<br>&nbsp; &nbsp; // NOTE: If AppBar is docked but not auto-hidden, we return ABE_UNKNOWN<br>&nbsp; &nbsp; Result := abeUnknown;<br>end;<br><br><br>// TAppBar.GetMessagePosition /////////////////////////////////////////////////<br>function TAppBar.GetMessagePosition : TSmallPoint;<br>var<br>&nbsp; pt : TSmallPoint;<br>&nbsp; dw : DWORD;<br>begin<br>&nbsp; dw := GetMessagePos;<br>&nbsp; pt.X := SHORT(dw);<br>&nbsp; pt.Y := SHORT((dw and $FFFF0000) shr 16);<br>&nbsp; Result := pt;<br>end;<br><br><br>// TAppBar.ModifyStyle ////////////////////////////////////////////////////////<br>function TAppBar.ModifyStyle (hWnd : THandle;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nStyleOffset : Integer;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwRemove &nbsp; &nbsp; : DWORD;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwAdd &nbsp; &nbsp; &nbsp; &nbsp;: DWORD;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nFlags &nbsp; &nbsp; &nbsp; : UINT) : Boolean;<br>var<br>&nbsp; dwStyle : DWORD;<br>&nbsp; dwNewStyle : DWORD;<br>begin<br>&nbsp; dwStyle := GetWindowLong(hWnd, nStyleOffset);<br>&nbsp; dwNewStyle := (dwStyle and (not dwRemove)) or dwAdd;<br><br>&nbsp; if dwStyle = dwNewStyle then begin<br>&nbsp; &nbsp; Result := False;<br>&nbsp; &nbsp; Exit;<br>&nbsp; end;<br><br>&nbsp; SetWindowLong(hWnd, nStyleOffset, dwNewStyle);<br><br>&nbsp; if nFlags &lt;&gt; 0 then<br>&nbsp; &nbsp; SetWindowPos(hWnd, 0, 0, 0, 0, 0,<br>&nbsp; &nbsp; &nbsp; SWP_NOSIZE or SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or nFlags);<br><br>&nbsp; Result := True;<br>end;<br><br><br>{ Property selector functions }<br><br><br>// TAppBar.GetEdge ////////////////////////////////////////////////////////////<br>function TAppBar.GetEdge : TAppBarEdge;<br>begin<br>&nbsp; if FabEdgeProposedPrev &lt;&gt; abeUnknown then<br>&nbsp; &nbsp; Result := FabEdgeProposedPrev<br>&nbsp; else<br>&nbsp; &nbsp; Result := FABS.abEdge;<br>end;<br><br><br>// TAppBar.SetEdge ////////////////////////////////////////////////////////////<br>procedure TAppBar.SetEdge (abEdge : TAppBarEdge);<br>var<br>&nbsp; abCurrentEdge : TAppBarEdge;<br>&nbsp; currentRect : TRect;<br>&nbsp; rc : TRect;<br>&nbsp; hWnd : THandle;<br>begin<br>&nbsp; // If the AppBar is registered as auto-hide, unregister it<br>&nbsp; abCurrentEdge := GetAutohideEdge;<br><br>&nbsp; if abCurrentEdge &lt;&gt; abeUnknown then<br>&nbsp; &nbsp; // Our AppBar is auto-hidden, unregister it<br>&nbsp; &nbsp; AppBarMessage3(abmSetAutoHideBar, abCurrentEdge, LPARAM(False));<br><br>&nbsp; // Save the new requested state<br>&nbsp; FABS.abEdge := abEdge;<br><br>&nbsp; case abEdge of<br><br>&nbsp; &nbsp; abeUnknown: begin<br>&nbsp; &nbsp; &nbsp; // We are being completely unregistered.<br>&nbsp; &nbsp; &nbsp; // Probably, the AppBar window is being destroyed.<br>&nbsp; &nbsp; &nbsp; // If the AppBar is registered as NOT auto-hide, unregister it<br>&nbsp; &nbsp; &nbsp; AppBarMessage1(abmRemove);<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; abeFloat: begin<br>&nbsp; &nbsp; &nbsp; // We are floating and therefore are just a regular window.<br>&nbsp; &nbsp; &nbsp; // Tell the shell that the docked AppBar should be of 0x0 dimensions<br>&nbsp; &nbsp; &nbsp; // so that the workspace is not affected by the AppBar<br>&nbsp; &nbsp; &nbsp; currentRect := Rect(0, 0, 0, 0);<br>&nbsp; &nbsp; &nbsp; AppBarMessage4(abmSetPos, abEdge, LPARAM(False), currentRect);<br>&nbsp; &nbsp; &nbsp; Left &nbsp; := FABS.rcFloat.Left;<br>&nbsp; &nbsp; &nbsp; Top &nbsp; &nbsp;:= FABS.rcFloat.Top;<br>&nbsp; &nbsp; &nbsp; Width &nbsp;:= FABS.rcFloat.Right - FABS.rcFloat.Left;<br>&nbsp; &nbsp; &nbsp; Height := FABS.rcFloat.Bottom - FABS.rcFloat.Top;<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; else begin<br>&nbsp; &nbsp; &nbsp; if FABS.bAutohide and<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(AppBarMessage3(abmSetAutoHideBar,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetEdge,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LPARAM(True)) = 0) then begin<br>&nbsp; &nbsp; &nbsp; &nbsp; // We couldn't set the AppBar on a new edge, let's dock it instead<br>&nbsp; &nbsp; &nbsp; &nbsp; FABS.bAutohide := False;<br>&nbsp; &nbsp; &nbsp; &nbsp; // Call a virtual function to let derived classes know that the AppBar<br>&nbsp; &nbsp; &nbsp; &nbsp; // changed from auto-hide to docked<br>&nbsp; &nbsp; &nbsp; &nbsp; OnAppBarForcedToDocked;<br>&nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; GetRect(GetEdge, rc);<br>&nbsp; &nbsp; &nbsp; if FABS.bAutohide then begin<br>&nbsp; &nbsp; &nbsp; &nbsp; currentRect := Rect(0, 0, 0, 0);<br>&nbsp; &nbsp; &nbsp; &nbsp; AppBarMessage4(abmSetPos, abeLeft, LPARAM(False), currentRect);<br>&nbsp; &nbsp; &nbsp; end else begin<br>&nbsp; &nbsp; &nbsp; &nbsp; // Tell the shell where the AppBar is<br>&nbsp; &nbsp; &nbsp; &nbsp; AppBarMessage4(abmSetPos, abEdge, LPARAM(False), rc);<br>&nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; AdjustLocationForAutohide(FbAutoHideIsVisible, rc);<br><br>&nbsp; &nbsp; &nbsp; // Slide window in from or out to the edge<br>&nbsp; &nbsp; &nbsp; SlideWindow(rc);<br><br>&nbsp; &nbsp; end; // end of else<br><br>&nbsp; end; // end of case<br><br>&nbsp; // Set the AppBar's z-order appropriately<br>&nbsp; hWnd := HWND_NOTOPMOST; // Assume normal Z-Order<br>&nbsp; if FABS.bAlwaysOnTop then begin<br>&nbsp; &nbsp; // If we are supposed to be always-on-top, put us there<br>&nbsp; &nbsp; hWnd := HWND_TOPMOST;<br>&nbsp; &nbsp; if FbFullScreenAppOpen then<br>&nbsp; &nbsp; &nbsp; // But, if a full-screen window is opened, put ourself at the bottom<br>&nbsp; &nbsp; &nbsp; // of the z-order so that we don't cover the full-screen window<br>&nbsp; &nbsp; &nbsp; hWnd := HWND_BOTTOM;<br>&nbsp; end;<br>&nbsp; SetWindowPos(Handle,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hWnd,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0, 0, 0, 0,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);<br><br>&nbsp; // Make sure that any auto-hide appbars stay on top of us after we move<br>&nbsp; // even though our activation state has not changed<br>&nbsp; AppBarMessage1(abmActivate);<br><br>&nbsp; // Tell our derived class that there is a state change<br>&nbsp; OnAppBarStateChange(False, abEdge);<br><br>&nbsp; // Show or hide the taskbar entry depending on AppBar position<br>&nbsp; case FABS.abTaskEntry of<br>&nbsp; &nbsp; abtShow :<br>&nbsp; &nbsp; &nbsp; ShowWindow(Application.Handle, SW_SHOW);<br>&nbsp; &nbsp; abtHide :<br>&nbsp; &nbsp; &nbsp; ShowWindow(Application.Handle, SW_HIDE);<br>&nbsp; &nbsp; abtFloatDependent :<br>&nbsp; &nbsp; &nbsp; case abEdge of<br>&nbsp; &nbsp; &nbsp; &nbsp; abeFloat:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ShowWindow(Application.Handle, SW_SHOW);<br>&nbsp; &nbsp; &nbsp; &nbsp; abeLeft, abeTop, abeRight, abeBottom :<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ShowWindow(Application.Handle, SW_HIDE);<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; end;<br>end;<br><br><br>// TAppBar.SetSlideTime ///////////////////////////////////////////////////////<br>procedure TAppBar.SetSlideTime (nInterval : Integer);<br>begin<br>&nbsp; FABS.nTimerInterval := nInterval;<br>&nbsp; FTimer.Interval := nInterval;<br>end;<br><br><br>{ Overridable functions }<br><br><br>// TAppBar.OnAppBarStateChange ////////////////////////////////////////////////<br>procedure TAppBar.OnAppBarStateChange (bProposed &nbsp; &nbsp; &nbsp;: Boolean;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;abEdgeProposed : TAppBarEdge);<br>var<br>&nbsp; bFullDragOn : LongBool;<br>begin<br>&nbsp; // Find out if the user has FullDrag turned on<br>&nbsp; SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, @bFullDragOn, 0);<br><br>&nbsp; // If FullDrag is turned on OR the appbar has changed position<br>&nbsp; if bFullDragOn or not bProposed then begin<br>&nbsp; &nbsp; if abEdgeProposed = abeFloat then<br>&nbsp; &nbsp; &nbsp; // Show the window adornments<br>&nbsp; &nbsp; &nbsp; ModifyStyle(Handle,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GWL_STYLE,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WS_CAPTION or WS_SYSMENU,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SWP_DRAWFRAME)<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; // Hide the window adornments<br>&nbsp; &nbsp; &nbsp; ModifyStyle(Handle,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; GWL_STYLE,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WS_CAPTION or WS_SYSMENU,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SWP_DRAWFRAME);<br>&nbsp; end;<br>end;<br><br><br>// TAppBar.OnAppBarForcedToDocked /////////////////////////////////////////////<br>procedure TAppBar.OnAppBarForcedToDocked;<br>const<br>&nbsp; CRLF = #10#13;<br>begin<br>&nbsp; // Display the application name as the message box caption text.<br>&nbsp; MessageDlg('There is already an auto hidden window on this edge.' + CRLF +<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'Only one auto hidden window is allowed on each edge.',<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mtInformation,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[mbOk],<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0);<br>end;<br><br>// TAppBar.OnABNFullScreenApp /////////////////////////////////////////////////<br>procedure TAppBar.OnABNFullScreenApp (bOpen : Boolean);<br>begin<br>&nbsp; // This function is called when a FullScreen window is openning or<br>&nbsp; // closing. A FullScreen window is a top-level window that has its caption<br>&nbsp; // above the top of the screen allowing the entire screen to be occupied<br>&nbsp; // by the window's client area.<br><br>&nbsp; // If the AppBar is a topmost window when a FullScreen window is activated,<br>&nbsp; // we need to change our window to a non-topmost window so that the AppBar<br>&nbsp; // doesn't cover the FullScreen window's client area.<br><br>&nbsp; // If the FullScreen window is closing, we need to set the AppBar's<br>&nbsp; // Z-Order back to when the user wants it to be.<br>&nbsp; FbFullScreenAppOpen := bOpen;<br>&nbsp; UpdateBar;<br>end;<br><br><br>// TAppBar.OnABNPosChanged ////////////////////////////////////////////////////<br>procedure TAppBar.OnABNPosChanged;<br>begin<br>&nbsp; // The TaskBar or another AppBar has changed its size or position<br>&nbsp; if (GetEdge &lt;&gt; abeFloat) and (not FABS.bAutohide) then<br>&nbsp; &nbsp; // If we're not floating and we're not auto-hidden, we have to<br>&nbsp; &nbsp; // reposition our window<br>&nbsp; &nbsp; UpdateBar;<br>end;<br><br><br>// TAppBar.OnABNWindowArrange /////////////////////////////////////////////////<br>procedure TAppBar.OnABNWindowArrange (bBeginning : Boolean);<br>begin<br>&nbsp; // This function intentionally left blank<br>end;<br><br><br>{ Message handlers }<br><br><br>// TAppBar.OnAppBarCallbackMsg ////////////////////////////////////////////////<br>procedure TAppBar.OnAppBarCallbackMsg (var Msg : TMessage);<br>begin<br>&nbsp; case Msg.WParam of<br><br>&nbsp; &nbsp; ABN_FULLSCREENAPP:<br>&nbsp; &nbsp; &nbsp; OnABNFullScreenApp(Msg.LParam &lt;&gt; 0);<br><br>&nbsp; &nbsp; ABN_POSCHANGED:<br>&nbsp; &nbsp; &nbsp; OnABNPosChanged;<br><br>&nbsp; &nbsp; ABN_WINDOWARRANGE:<br>&nbsp; &nbsp; &nbsp; OnABNWindowArrange(Msg.LParam &lt;&gt; 0);<br>&nbsp; end;<br>end;<br><br><br>// TAppBar.OnCreate ///////////////////////////////////////////////////////////<br>procedure TAppBar.OnCreate (var Msg : TWMCreate);<br>var<br>&nbsp; hMenu : THandle;<br>begin<br>&nbsp; inherited;<br>&nbsp; // Associate a timer with the AppBar. &nbsp;The timer is used to determine<br>&nbsp; // when a visible, inactive, auto-hide AppBar should be re-hidden<br>&nbsp; FTimer := TTimer.Create(Self);<br>&nbsp; with FTimer do begin<br>&nbsp; &nbsp; Interval := FABS.nTimerInterval;<br>&nbsp; &nbsp; OnTimer := OnAppBarTimer;<br>&nbsp; &nbsp; Enabled := True;<br>&nbsp; end;<br><br>&nbsp; // Save the initial position of the floating AppBar<br>&nbsp; FABS.rcFloat.Left &nbsp; := Left;<br>&nbsp; FABS.rcFloat.Top &nbsp; &nbsp;:= Top;<br><br>&nbsp; // Register our AppBar window with the Shell<br>&nbsp; AppBarMessage1(abmNew);<br><br>&nbsp; // Update AppBar internal state<br>&nbsp; UpdateBar;<br><br>&nbsp; // Save the initial size of the floating AppBar<br>&nbsp; PostMessage(Handle, WM_ENTERSIZEMOVE, 0, 0);<br>&nbsp; PostMessage(Handle, WM_EXITSIZEMOVE, &nbsp;0, 0);<br><br>&nbsp; // Remove system menu<br>&nbsp; hMenu := GetSystemMenu(Handle, False);<br>&nbsp; DeleteMenu(hMenu, SC_RESTORE, &nbsp;MF_BYCOMMAND);<br>&nbsp; DeleteMenu(hMenu, SC_MINIMIZE, MF_BYCOMMAND);<br>&nbsp; DeleteMenu(hMenu, SC_MAXIMIZE, MF_BYCOMMAND);<br>end;<br><br><br>// TAppBar.OnDestroy //////////////////////////////////////////////////////////<br>procedure TAppBar.OnDestroy (var Msg : TWMDestroy);<br>begin<br>&nbsp; // Free the Autohide timer<br>&nbsp; FTimer.Enabled := False;<br>&nbsp; FTimer.Free;<br>&nbsp; // Unregister our AppBar window with the Shell<br>&nbsp; SetEdge(abeUnknown);<br>&nbsp; inherited;<br>end;<br><br><br>// TAppBar.OnWindowPosChanged /////////////////////////////////////////////////<br>procedure TAppBar.OnWindowPosChanged (var Msg : TWMWindowPosChanged);<br>begin<br>&nbsp; inherited;<br>&nbsp; // When our window changes position, tell the Shell so that any<br>&nbsp; // auto-hidden AppBar on our edge stays on top of our window making it<br>&nbsp; // always accessible to the user<br>&nbsp; AppBarMessage1(abmWindowPosChanged);<br>end;<br><br><br>// TAppBar.OnActivate /////////////////////////////////////////////////////////<br>procedure TAppBar.OnActivate (var Msg : TWMActivate);<br>begin<br>&nbsp; inherited;<br>&nbsp; if Msg.Active = WA_INACTIVE then<br>&nbsp; &nbsp; // Hide the AppBar if we are docked and auto-hidden<br>&nbsp; &nbsp; ShowHiddenAppBar(False);<br>&nbsp; // When our window changes position, tell the Shell so that any<br>&nbsp; // auto-hidden AppBar on our edge stays on top of our window making it<br>&nbsp; // always accessible to the user.<br>&nbsp; AppBarMessage1(abmActivate);<br>end;<br><br><br>// TAppBar.OnAppBarTimer //////////////////////////////////////////////////////<br>procedure TAppBar.OnAppBarTimer (Sender : TObject);<br>var<br>&nbsp; pt : TSmallPoint;<br>&nbsp; rc : TRect;<br>begin<br>&nbsp; if GetActiveWindow &lt;&gt; Handle then begin<br>&nbsp; &nbsp; // Possibly hide the AppBar if we are not the active window<br>&nbsp; &nbsp; // Get the position of the mouse and the AppBar's position<br>&nbsp; &nbsp; // Everything must be in screen coordinates<br>&nbsp; &nbsp; pt := GetMessagePosition;<br>&nbsp; &nbsp; GetWindowRect(Handle, rc);<br>&nbsp; &nbsp; // Add a little margin around the AppBar<br>&nbsp; &nbsp; InflateRect(rc,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 * GetSystemMetrics(SM_CXDOUBLECLK),<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 * GetSystemMetrics(SM_CYDOUBLECLK));<br>&nbsp; &nbsp; if not PtInRect(rc, SmallPointToPoint(pt)) then<br>&nbsp; &nbsp; &nbsp; // If the mouse is NOT over the AppBar, hide the AppBar<br>&nbsp; &nbsp; &nbsp; ShowHiddenAppBar(False);<br>&nbsp; end;<br>&nbsp; inherited;<br>end;<br><br><br>// TAppBar.OnNcMouseMove //////////////////////////////////////////////////////<br>procedure TAppBar.OnNcMouseMove (var Msg : TWMNCMouseMove);<br>begin<br>&nbsp; // If we are a docked, auto-hidden AppBar, shown us<br>&nbsp; // when the user moves over our non-client area<br>&nbsp; ShowHiddenAppBar(True);<br>&nbsp; inherited;<br>end;<br><br><br>// TAppBar.OnNcHitTest ////////////////////////////////////////////////////////<br>procedure TAppBar.OnNcHitTest (var Msg: TWMNCHitTest);<br>var<br>&nbsp; u : UINT;<br>&nbsp; bPrimaryMouseBtnDown : Boolean;<br>&nbsp; rcClient : TRect;<br>&nbsp; pt : TPoint;<br>&nbsp; vKey : Integer;<br>begin<br>&nbsp; // Find out what the system thinks is the hit test code<br>&nbsp; inherited;<br>&nbsp; u := Msg.Result;<br><br>&nbsp; // NOTE: If the user presses the secondary mouse button, pretend that the<br>&nbsp; // user clicked on the client area so that we get WM_CONTEXTMENU messages<br>&nbsp; if GetSystemMetrics(SM_SWAPBUTTON) &lt;&gt; 0 then<br>&nbsp; &nbsp; vKey := VK_RBUTTON<br>&nbsp; else<br>&nbsp; &nbsp; vKey := VK_LBUTTON;<br>&nbsp; bPrimaryMouseBtnDown := ((GetAsyncKeyState(vKey) and $8000) &lt;&gt; 0);<br><br>&nbsp; pt.X := Msg.XPos;<br>&nbsp; pt.Y := Msg.YPos;<br>&nbsp; pt := ScreenToClient(pt);<br>&nbsp; if (u = HTCLIENT) and bPrimaryMouseBtnDown<br>&nbsp; &nbsp; &nbsp;and (ControlAtPos(pt, False) = nil) then<br>&nbsp; &nbsp; // User clicked in client area, allow AppBar to move. &nbsp;We get this<br>&nbsp; &nbsp; // behavior by pretending that the user clicked on the caption area<br>&nbsp; &nbsp; u := HTCAPTION;<br><br>&nbsp; // If the AppBar is floating and the hittest code is a resize code...<br>&nbsp; if ((GetEdge = abeFloat) and<br>&nbsp; &nbsp; &nbsp; (HTSIZEFIRST &lt;= u) and (u &lt;= HTSIZELAST)) then begin<br>&nbsp; &nbsp; case u of<br>&nbsp; &nbsp; &nbsp; HTLEFT, HTRIGHT:<br>&nbsp; &nbsp; &nbsp; &nbsp; if FABS.szSizeInc.cx = 0<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then u := HTBORDER;<br>&nbsp; &nbsp; &nbsp; HTTOP, HTBOTTOM:<br>&nbsp; &nbsp; &nbsp; &nbsp; if FABS.szSizeInc.cy = 0<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then u := HTBORDER;<br>&nbsp; &nbsp; &nbsp; HTTOPLEFT:<br>&nbsp; &nbsp; &nbsp; &nbsp; if (FABS.szSizeInc.cx = 0) and (FABS.szSizeInc.cy = 0)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then u := HTBORDER<br>&nbsp; &nbsp; &nbsp; &nbsp; else if (FABS.szSizeInc.cx = 0) and (FABS.szSizeInc.cy &lt;&gt; 0)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then u := HTTOP<br>&nbsp; &nbsp; &nbsp; &nbsp; else if (FABS.szSizeInc.cx &lt;&gt; 0) and (FABS.szSizeInc.cy = 0)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then u := HTLEFT;<br>&nbsp; &nbsp; &nbsp; HTTOPRIGHT:<br>&nbsp; &nbsp; &nbsp; &nbsp; if (FABS.szSizeInc.cx = 0) and (FABS.szSizeInc.cy = 0)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then u := HTBORDER<br>&nbsp; &nbsp; &nbsp; &nbsp; else if (FABS.szSizeInc.cx = 0) and (FABS.szSizeInc.cy &lt;&gt; 0)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then u := HTTOP<br>&nbsp; &nbsp; &nbsp; &nbsp; else if (FABS.szSizeInc.cx &lt;&gt; 0) and (FABS.szSizeInc.cy = 0)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then u := HTRIGHT;<br>&nbsp; &nbsp; &nbsp; HTBOTTOMLEFT:<br>&nbsp; &nbsp; &nbsp; &nbsp; if (FABS.szSizeInc.cx = 0) and (FABS.szSizeInc.cy = 0)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then u := HTBORDER<br>&nbsp; &nbsp; &nbsp; &nbsp; else if (FABS.szSizeInc.cx = 0) and (FABS.szSizeInc.cy &lt;&gt; 0)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then u := HTBOTTOM<br>&nbsp; &nbsp; &nbsp; &nbsp; else if (FABS.szSizeInc.cx &lt;&gt; 0) and (FABS.szSizeInc.cy = 0)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then u := HTLEFT;<br>&nbsp; &nbsp; &nbsp; HTBOTTOMRIGHT:<br>&nbsp; &nbsp; &nbsp; &nbsp; if (FABS.szSizeInc.cx = 0) and (FABS.szSizeInc.cy = 0)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then u := HTBORDER<br>&nbsp; &nbsp; &nbsp; &nbsp; else if (FABS.szSizeInc.cx = 0) and (FABS.szSizeInc.cy &lt;&gt; 0)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then u := HTBOTTOM<br>&nbsp; &nbsp; &nbsp; &nbsp; else if (FABS.szSizeInc.cx &lt;&gt; 0) and (FABS.szSizeInc.cy = 0)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; then u := HTRIGHT;<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br><br>&nbsp; // When the AppBar is docked, the user can resize only one edge.<br>&nbsp; // This next section determines which edge the user can resize.<br>&nbsp; // To allow resizing, the AppBar window must have the WS_THICKFRAME style<br><br>&nbsp; // If the AppBar is docked and the hittest code is a resize code...<br>&nbsp; if ((GetEdge &lt;&gt; abeFloat) and (GetEdge &lt;&gt; abeUnknown) and<br>&nbsp; &nbsp; &nbsp; (HTSIZEFIRST &lt;= u) and (u &lt;= HTSIZELAST)) then begin<br><br>&nbsp; &nbsp; if (IsEdgeLeftOrRight(GetEdge) and (FABS.szSizeInc.cx = 0)) or<br>&nbsp; &nbsp; &nbsp; &nbsp;(not IsEdgeLeftOrRight(GetEdge) and (FABS.szSizeInc.cy = 0)) then begin<br>&nbsp; &nbsp; &nbsp; // If the width/height size increment is zero, then resizing is NOT<br>&nbsp; &nbsp; &nbsp; // allowed for the edge that the AppBar is docked on<br>&nbsp; &nbsp; &nbsp; u := HTBORDER; // Pretend that the mouse is not on a resize border<br>&nbsp; &nbsp; end else begin<br>&nbsp; &nbsp; &nbsp; // Resizing IS allowed for the edge that the AppBar is docked on<br>&nbsp; &nbsp; &nbsp; // Get the location of the appbar's client area in screen coordinates<br>&nbsp; &nbsp; &nbsp; rcClient := GetClientRect;<br>&nbsp; &nbsp; &nbsp; pt.X := rcClient.Left;<br>&nbsp; &nbsp; &nbsp; pt.Y := rcClient.Top;<br>&nbsp; &nbsp; &nbsp; pt := ClientToScreen(pt);<br>&nbsp; &nbsp; &nbsp; rcClient.Left := pt.X;<br>&nbsp; &nbsp; &nbsp; rcClient.Top &nbsp;:= pt.Y;<br>&nbsp; &nbsp; &nbsp; pt.X := rcClient.Right;<br>&nbsp; &nbsp; &nbsp; pt.Y := rcClient.Bottom;<br>&nbsp; &nbsp; &nbsp; pt := ClientToScreen(pt);<br>&nbsp; &nbsp; &nbsp; rcClient.Right &nbsp;:= pt.X;<br>&nbsp; &nbsp; &nbsp; rcClient.Bottom := pt.Y;<br><br>&nbsp; &nbsp; &nbsp; u := HTBORDER; &nbsp;// Assume that we can't resize<br>&nbsp; &nbsp; &nbsp; case GetEdge of<br>&nbsp; &nbsp; &nbsp; &nbsp; abeLeft:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Msg.XPos &gt; rcClient.Right then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; u := HTRIGHT;<br>&nbsp; &nbsp; &nbsp; &nbsp; abeTop:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Msg.YPos &gt; rcClient.Bottom then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; u := HTBOTTOM;<br>&nbsp; &nbsp; &nbsp; &nbsp; abeRight:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Msg.XPos &lt; rcClient.Left then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; u := HTLEFT;<br>&nbsp; &nbsp; &nbsp; &nbsp; abeBottom:<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if Msg.YPos &lt; rcClient.Top then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; u := HTTOP;<br>&nbsp; &nbsp; &nbsp; end; // end of case<br>&nbsp; &nbsp; end; // end of else<br>&nbsp; end;<br><br>&nbsp; // Return the hittest code<br>&nbsp; Msg.Result := u;<br>end;<br><br><br>// TAppBar.OnEnterSizeMove ////////////////////////////////////////////////////<br>procedure TAppBar.OnEnterSizeMove (var Msg : TMessage);<br>begin<br>&nbsp; // The user started moving/resizing the AppBar, save its current state<br>&nbsp; FabEdgeProposedPrev := GetEdge;<br>end;<br><br><br>// TAppBar.OnExitSizeMove /////////////////////////////////////////////////////<br>procedure TAppBar.OnExitSizeMove (var Msg : TMessage);<br>var<br>&nbsp; abEdgeProposedPrev : TAppBarEdge;<br>&nbsp; rc, rcWorkArea : TRect;<br>&nbsp; w, h : Integer;<br>begin<br>&nbsp; // The user stopped moving/resizing the AppBar, set the new state<br>&nbsp; // Save the new proposed state of the AppBar<br>&nbsp; abEdgeProposedPrev := FabEdgeProposedPrev;<br><br>&nbsp; // Set the proposed state back to unknown. &nbsp;This causes GetState<br>&nbsp; // to return the current state rather than the proposed state<br>&nbsp; FabEdgeProposedPrev := abeUnknown;<br><br>&nbsp; // Get the location of the window in screen coordinates<br>&nbsp; GetWindowRect(Handle, rc);<br><br>&nbsp; // If the AppBar's state has changed...<br>&nbsp; if GetEdge = abEdgeProposedPrev then<br>&nbsp; &nbsp; case GetEdge of<br>&nbsp; &nbsp; &nbsp; abeLeft, abeRight:<br>&nbsp; &nbsp; &nbsp; &nbsp; // Save the new width of the docked AppBar<br>&nbsp; &nbsp; &nbsp; &nbsp; FABS.szDockSize.cx := rc.Right - rc.Left;<br>&nbsp; &nbsp; &nbsp; abeTop, abeBottom:<br>&nbsp; &nbsp; &nbsp; &nbsp; // Save the new height of the docked AppBar<br>&nbsp; &nbsp; &nbsp; &nbsp; FABS.szDockSize.cy := rc.Bottom - rc.Top;<br>&nbsp; &nbsp; end;<br><br>&nbsp; // Always save the new position of the floating AppBar<br>&nbsp; if abEdgeProposedPrev = abeFloat then begin<br>&nbsp; &nbsp; // If AppBar was floating and keeps floating...<br>&nbsp; &nbsp; if GetEdge = abeFloat then begin<br>&nbsp; &nbsp; &nbsp; FABS.rcFloat := rc;<br>&nbsp; &nbsp; // If AppBar was docked and is going to float...<br>&nbsp; &nbsp; end else begin<br>&nbsp; &nbsp; &nbsp; // Propose width and height depending on the current window position<br>&nbsp; &nbsp; &nbsp; w := rc.Right - rc.Left;<br>&nbsp; &nbsp; &nbsp; h := rc.Bottom - rc.Top;<br>&nbsp; &nbsp; &nbsp; // Adjust width and height<br>&nbsp; &nbsp; &nbsp; SystemParametersInfo(SPI_GETWORKAREA, 0, @rcWorkArea, 0);<br>&nbsp; &nbsp; &nbsp; if (w &gt;= (rcWorkArea.Right - rcWorkArea.Left)) or<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(h &gt;= (rcWorkArea.Bottom - rcWorkArea.Top)) then begin<br>&nbsp; &nbsp; &nbsp; &nbsp; w := FABS.rcFloat.Right - FABS.rcFloat.Left;<br>&nbsp; &nbsp; &nbsp; &nbsp; h := FABS.rcFloat.Bottom - FABS.rcFloat.Top;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; // Save new floating position<br>&nbsp; &nbsp; &nbsp; FABS.rcFloat.Left &nbsp; := rc.Left;<br>&nbsp; &nbsp; &nbsp; FABS.rcFloat.Top &nbsp; &nbsp;:= rc.Top;<br>&nbsp; &nbsp; &nbsp; FABS.rcFloat.Right &nbsp;:= rc.Left + w;<br>&nbsp; &nbsp; &nbsp; FABS.rcFloat.Bottom := rc.Top + h;<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br><br>&nbsp; // After setting the dimensions, set the AppBar to the proposed state<br>&nbsp; SetEdge(abEdgeProposedPrev);<br>end;<br><br><br>// TAppBar.OnMoving ///////////////////////////////////////////////////////////<br>procedure TAppBar.OnMoving (var Msg : TMessage);<br>var<br>&nbsp; prc &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: PRect;<br>&nbsp; pt &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : TSmallPoint;<br>&nbsp; abEdgeProposed : TAppBarEdge;<br>&nbsp; w, h &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Integer;<br>begin<br>&nbsp; // We control the moving of the AppBar. &nbsp;For example, if the mouse moves<br>&nbsp; // close to an edge, we want to dock the AppBar<br>&nbsp; // The lParam contains the window's position proposed by the system<br>&nbsp; prc := PRect(Msg.LParam);<br><br>&nbsp; // Get the location of the mouse cursor<br>&nbsp; pt := GetMessagePosition;<br><br>&nbsp; // Where should the AppBar be based on the mouse position?<br>&nbsp; abEdgeProposed := CalcProposedState(pt);<br><br>&nbsp; if ((FabEdgeProposedPrev &lt;&gt; abeFloat) and<br>&nbsp; &nbsp; &nbsp; (abEdgeProposed = abeFloat)) then begin<br>&nbsp; &nbsp; // While moving, the user took us from a docked/autohidden state to<br>&nbsp; &nbsp; // the float state. &nbsp;We have to calculate a rectangle location so that<br>&nbsp; &nbsp; // the mouse cursor stays inside the window.<br>&nbsp; &nbsp; prc^ := FABS.rcFloat;<br>&nbsp; &nbsp; w := prc^.Right - prc^.Left;<br>&nbsp; &nbsp; h := prc^.Bottom - prc^.Top;<br>&nbsp; &nbsp; with prc^ do begin<br>&nbsp; &nbsp; &nbsp; Left &nbsp; := pt.X - w div 2;<br>&nbsp; &nbsp; &nbsp; Top &nbsp; &nbsp;:= pt.Y;<br>&nbsp; &nbsp; &nbsp; Right &nbsp;:= pt.X - w div 2 + w;<br>&nbsp; &nbsp; &nbsp; Bottom := pt.Y + h;<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br><br>&nbsp; // Remember the most-recently proposed state<br>&nbsp; FabEdgeProposedPrev := abEdgeProposed;<br><br>&nbsp; // Tell the system where to move the window based on the proposed state<br>&nbsp; GetRect(abEdgeProposed, prc^);<br><br>&nbsp; // Tell our derived class that there is a proposed state change<br>&nbsp; OnAppBarStateChange(True, abEdgeProposed);<br>end;<br><br><br>// TAppBar.OnSizing ///////////////////////////////////////////////////////////<br>procedure TAppBar.OnSizing (var Msg : TMessage);<br>var<br>&nbsp; prc : PRect;<br>&nbsp; rcBorder : TRect;<br>&nbsp; nWidthNew, nHeightNew : Integer;<br>begin<br>&nbsp; // We control the sizing of the AppBar. &nbsp;For example, if the user re-sizes<br>&nbsp; // an edge, we want to change the size in discrete increments.<br>&nbsp; // The lParam contains the window's position proposed by the system<br>&nbsp; prc := PRect(Msg.LParam);<br><br>&nbsp; // Get the minimum allowed size of the window depending on current edge.<br>&nbsp; // This is the width/height of the window that must always be present<br>&nbsp; with FABS do<br>&nbsp; &nbsp; case abEdge of<br>&nbsp; &nbsp; &nbsp; abeFloat:<br>&nbsp; &nbsp; &nbsp; &nbsp; rcBorder := Rect(0, 0, nMinWidth, nMinHeight);<br>&nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; rcBorder := Rect(0, 0, szMinDockSize.cx, szMinDockSize.cy);<br>&nbsp; &nbsp; end;<br><br>&nbsp; // We force the window to resize in discrete units set by the FABS.szSizeInc<br>&nbsp; // member. &nbsp;From the new, proposed window dimensions passed to us, round<br>&nbsp; // the width/height to the nearest discrete unit<br>&nbsp; if FABS.szSizeInc.cx &lt;&gt; 0 then<br>&nbsp; &nbsp; nWidthNew &nbsp;:= ((prc^.Right - prc^.Left) - (rcBorder.Right - rcBorder.Left)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ FABS.szSizeInc.cx div 2) div FABS.szSizeInc.cx<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* FABS.szSizeInc.cx + (rcBorder.Right - rcBorder.Left)<br>&nbsp; else<br>&nbsp; &nbsp; nWidthNew &nbsp;:= prc^.Right - prc^.Left;<br><br>&nbsp; if FABS.szSizeInc.cy &lt;&gt; 0 then<br>&nbsp; &nbsp; nHeightNew := ((prc^.Bottom - prc^.Top) - (rcBorder.Bottom - rcBorder.Top)<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+ FABS.szSizeInc.cy div 2) div FABS.szSizeInc.cy<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* FABS.szSizeInc.cy + (rcBorder.Bottom - rcBorder.Top)<br>&nbsp; else<br>&nbsp; &nbsp; nHeightNew := prc^.Bottom - prc^.Top;<br><br>&nbsp; // Adjust the rectangle's dimensions<br>&nbsp; case Msg.wParam of<br>&nbsp; &nbsp; WMSZ_LEFT:<br>&nbsp; &nbsp; &nbsp; prc^.Left &nbsp; := prc^.Right &nbsp;- nWidthNew;<br><br>&nbsp; &nbsp; WMSZ_TOP:<br>&nbsp; &nbsp; &nbsp; prc^.Top &nbsp; &nbsp;:= prc^.Bottom - nHeightNew;<br><br>&nbsp; &nbsp; WMSZ_RIGHT:<br>&nbsp; &nbsp; &nbsp; prc^.Right &nbsp;:= prc^.Left &nbsp; + nWidthNew;<br><br>&nbsp; &nbsp; WMSZ_BOTTOM:<br>&nbsp; &nbsp; &nbsp; prc^.Bottom := prc^.Top &nbsp; &nbsp;+ nHeightNew;<br><br>&nbsp; &nbsp; WMSZ_BOTTOMLEFT: begin<br>&nbsp; &nbsp; &nbsp; prc^.Bottom := prc^.Top &nbsp; &nbsp;+ nHeightNew;<br>&nbsp; &nbsp; &nbsp; prc^.Left &nbsp; := prc^.Right &nbsp;- nWidthNew;<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; WMSZ_BOTTOMRIGHT: begin<br>&nbsp; &nbsp; &nbsp; prc^.Bottom := prc^.Top &nbsp; &nbsp;+ nHeightNew;<br>&nbsp; &nbsp; &nbsp; prc^.Right &nbsp;:= prc^.Left &nbsp; + nWidthNew;<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; WMSZ_TOPLEFT: begin<br>&nbsp; &nbsp; &nbsp; prc^.Left &nbsp; := prc^.Right &nbsp;- nWidthNew;<br>&nbsp; &nbsp; &nbsp; prc^.Top &nbsp; &nbsp;:= prc^.Bottom - nHeightNew;<br>&nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; WMSZ_TOPRIGHT: begin<br>&nbsp; &nbsp; &nbsp; prc^.Top &nbsp; &nbsp;:= prc^.Bottom - nHeightNew;<br>&nbsp; &nbsp; &nbsp; prc^.Right &nbsp;:= prc^.Left &nbsp; + nWidthNew;<br>&nbsp; &nbsp; end;<br>&nbsp; end; // end of case<br>end;<br><br><br>// TAppBar.OnGetMinMaxInfo ////////////////////////////////////////////////////<br>procedure TAppBar.OnGetMinMaxInfo (var Msg : TWMGetMinMaxInfo);<br>begin<br>&nbsp; if GetEdge = abeFloat then<br>&nbsp; &nbsp; with Msg.MinMaxInfo^ do begin<br>&nbsp; &nbsp; &nbsp; ptMinTrackSize.X := FABS.nMinWidth;<br>&nbsp; &nbsp; &nbsp; ptMinTrackSize.Y := FABS.nMinHeight;<br>&nbsp; &nbsp; &nbsp; ptMaxTrackSize.X := FABS.nMaxWidth;<br>&nbsp; &nbsp; &nbsp; ptMaxTrackSize.Y := FABS.nMaxHeight;<br>&nbsp; &nbsp; end<br>&nbsp; else<br>&nbsp; &nbsp; with Msg.MinMaxInfo^ do begin<br>&nbsp; &nbsp; &nbsp; ptMinTrackSize.X := FABS.szMinDockSize.cx;<br>&nbsp; &nbsp; &nbsp; ptMinTrackSize.Y := FABS.szMinDockSize.cy;<br>&nbsp; &nbsp; &nbsp; ptMaxTrackSize.X := GetSystemMetrics(SM_CXSCREEN);<br>&nbsp; &nbsp; &nbsp; ptMaxTrackSize.Y := GetSystemMetrics(SM_CYSCREEN);<br>&nbsp; &nbsp; &nbsp; if not IsEdgeTopOrBottom(GetEdge) then<br>&nbsp; &nbsp; &nbsp; &nbsp; ptMaxTrackSize.X := FABS.szMaxDockSize.cx;<br>&nbsp; &nbsp; &nbsp; if not IsEdgeLeftOrRight(GetEdge) then<br>&nbsp; &nbsp; &nbsp; &nbsp; ptMaxTrackSize.Y := FABS.szMaxDockSize.cy;<br>&nbsp; &nbsp; end;<br>end;<br><br><br>{ AppBar-specific helper functions }<br><br><br>// TAppBar.IsEdgeLeftOrRight //////////////////////////////////////////////////<br>function TAppBar.IsEdgeLeftOrRight (abEdge : TAppBarEdge) : Boolean;<br>begin<br>&nbsp; Result := (abEdge in [abeLeft, abeRight]);<br>end;<br><br><br>// TAppBar.IsEdgeTopOrBottom //////////////////////////////////////////////////<br>function TAppBar.IsEdgeTopOrBottom (abEdge : TAppBarEdge) : Boolean;<br>begin<br>&nbsp; Result := (abEdge in [abeTop, abeBottom]);<br>end;<br><br><br>// TAppBar.IsFloating /////////////////////////////////////////////////////////<br>function TAppBar.IsFloating (abEdge : TAppBarEdge) : Boolean;<br>begin<br>&nbsp; Result := (abEdge = abeFloat);<br>end;<br><br><br>// TAppBar.IsDockable /////////////////////////////////////////////////////////<br>function TAppBar.IsDockable (abFlags : TAppBarFlags) : Boolean;<br>begin<br>&nbsp; Result := ((abFlags * [abfAllowLeft .. abfAllowBottom]) &lt;&gt; []);<br>end;<br><br><br>// TAppBar.IsDockableVertically ///////////////////////////////////////////////<br>function TAppBar.IsDockableVertically (abFlags : TAppBarFlags) : Boolean;<br>begin<br>&nbsp; Result := ((abFlags * [abfAllowLeft, abfAllowRight]) &lt;&gt; []);<br>end;<br><br><br>// TAppBar.IsDockableHorizontally /////////////////////////////////////////////<br>function TAppBar.IsDockableHorizontally (abFlags : TAppBarFlags) : Boolean;<br>begin<br>&nbsp; Result := ((abFlags * [abfAllowTop, abfAllowBottom]) &lt;&gt; []);<br>end;<br><br><br>// TAppBar.ResetSystemKnowledge ///////////////////////////////////////////////<br>procedure TAppBar.ResetSystemKnowledge;<br>{$ifdef DEBUG}<br>var<br>&nbsp; abd : TAppBarData;<br>begin<br>&nbsp; abd.cbSize := sizeof(abd);<br>&nbsp; abd.hWnd := 0;<br>&nbsp; SHAppBarMessage(ABM_REMOVE, abd);<br>end;<br>{$else}<br>begin<br>&nbsp; // nothing to do when not in debug mode<br>end;<br>{$endif}<br><br><br>// TAppBar.GetEdgeFromPoint ///////////////////////////////////////////////////<br>function TAppBar.GetEdgeFromPoint (abFlags : TAppBarFlags;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pt &nbsp; &nbsp; &nbsp;: TSmallPoint) : TAppBarEdge;<br>var<br>&nbsp; rc &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : TRect;<br>&nbsp; cxScreen &nbsp; &nbsp; &nbsp; : Integer;<br>&nbsp; cyScreen &nbsp; &nbsp; &nbsp; : Integer;<br>&nbsp; ptCenter &nbsp; &nbsp; &nbsp; : TSmallPoint;<br>&nbsp; ptOffset &nbsp; &nbsp; &nbsp; : TSmallPoint;<br>&nbsp; bIsLeftOrRight : Boolean;<br>&nbsp; abSubstEdge &nbsp; &nbsp;: TAppBarEdge;<br>begin<br>&nbsp; // Let's get floating out of the way first<br>&nbsp; if abfAllowFloat in abFlags then begin<br><br>&nbsp; &nbsp; // Get the rectangle that bounds the size of the screen<br>&nbsp; &nbsp; // minus any docked (but not-autohidden) AppBars<br>&nbsp; &nbsp; SystemParametersInfo(SPI_GETWORKAREA, 0, @rc, 0);<br><br>&nbsp; &nbsp; // Leave a 1/2 width/height-of-a-scrollbar gutter around the workarea<br>&nbsp; &nbsp; InflateRect(rc,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -GetSystemMetrics(SM_CXVSCROLL),<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -GetSystemMetrics(SM_CYHSCROLL));<br><br>&nbsp; &nbsp; // If the point is in the adjusted workarea OR no edges are allowed<br>&nbsp; &nbsp; if PtInRect(rc, SmallPointToPoint(pt)) or<br>&nbsp; &nbsp; &nbsp; &nbsp;not IsDockable(abFlags) then begin<br>&nbsp; &nbsp; &nbsp; // The AppBar should float<br>&nbsp; &nbsp; &nbsp; Result := abeFloat;<br>&nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br><br>&nbsp; // If we get here, the AppBar should be docked; determine the proper edge<br>&nbsp; // Get the dimensions of the screen<br>&nbsp; cxScreen := GetSystemMetrics(SM_CXSCREEN);<br>&nbsp; cyScreen := GetSystemMetrics(SM_CYSCREEN);<br><br>&nbsp; // Find the center of the screen<br>&nbsp; ptCenter.X := cxScreen div 2;<br>&nbsp; ptCenter.Y := cyScreen div 2;<br><br>&nbsp; // Find the distance from the point to the center<br>&nbsp; ptOffset.X := pt.X - ptCenter.X;<br>&nbsp; ptOffset.Y := pt.Y - ptCenter.Y;<br><br>&nbsp; // Determine if the point is farther from the left/right or top/bottom<br>&nbsp; bIsLeftOrRight :=<br>&nbsp; &nbsp; ((Abs(ptOffset.Y) * cxScreen) &lt;= (Abs(ptOffset.X) * cyScreen));<br><br>&nbsp; // Propose an edge<br>&nbsp; if bIsLeftOrRight then begin<br>&nbsp; &nbsp; if 0 &lt;= ptOffset.X then<br>&nbsp; &nbsp; &nbsp; Result := abeRight<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; Result := abeLeft;<br>&nbsp; end else begin<br>&nbsp; &nbsp; if 0 &lt;= ptOffset.Y then<br>&nbsp; &nbsp; &nbsp; Result := abeBottom<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; Result := abeTop;<br>&nbsp; end;<br><br>&nbsp; // Calculate an edge substitute<br>&nbsp; if abfAllowFloat in abFlags then<br>&nbsp; &nbsp; abSubstEdge := abeFloat<br>&nbsp; else<br>&nbsp; &nbsp; abSubstEdge := FABS.abEdge;<br><br>&nbsp; // Check if the proposed edge is allowed. If not, return the edge substitute<br>&nbsp; case Result of<br>&nbsp; &nbsp; abeLeft &nbsp;: if not (abfAllowLeft &nbsp; in abFlags) then Result := abSubstEdge;<br>&nbsp; &nbsp; abeTop &nbsp; : if not (abfAllowTop &nbsp; &nbsp;in abFlags) then Result := abSubstEdge;<br>&nbsp; &nbsp; abeRight : if not (abfAllowRight &nbsp;in abFlags) then Result := abSubstEdge;<br>&nbsp; &nbsp; abeBottom: if not (abfAllowBottom in abFlags) then Result := abSubstEdge;<br>&nbsp; end;<br><br>end;<br><br><br>{ Public member functions }<br><br><br>// TAppBar.Create /////////////////////////////////////////////////////////////<br>constructor TAppBar.Create (Owner : TComponent);<br>begin<br>&nbsp; // Force the shell to update its list of AppBars and the workarea.<br>&nbsp; // This is a precaution and is very useful when debugging. &nbsp;If you create<br>&nbsp; // an AppBar and then just terminate the application, the shell still<br>&nbsp; // thinks that the AppBar exists and the user's workarea is smaller than<br>&nbsp; // it should be. &nbsp;When a new AppBar is created, calling this function<br>&nbsp; // fixes the user's workarea.<br>&nbsp; ResetSystemKnowledge;<br><br>&nbsp; // Set default state of AppBar to float with no width &amp; height<br>&nbsp; FABS.cbSize &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:= sizeof(TAppBarSettings);<br>&nbsp; FABS.abEdge &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:= abeFloat;<br>&nbsp; FABS.abFlags &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; := [abfAllowLeft .. abfAllowFloat];<br>&nbsp; FABS.bAutohide &nbsp; &nbsp; &nbsp; &nbsp; := False;<br>&nbsp; FABS.bAlwaysOnTop &nbsp; &nbsp; &nbsp;:= True;<br>&nbsp; FABS.bSlideEffect &nbsp; &nbsp; &nbsp;:= True;<br>&nbsp; FABS.nTimerInterval &nbsp; &nbsp;:= SLIDE_DEF_TIMER_INTERVAL;<br>&nbsp; FABS.szSizeInc.cx &nbsp; &nbsp; &nbsp;:= AB_DEF_SIZE_INC;<br>&nbsp; FABS.szSizeInc.cy &nbsp; &nbsp; &nbsp;:= AB_DEF_SIZE_INC;<br>&nbsp; FABS.szDockSize.cx &nbsp; &nbsp; := AB_DEF_DOCK_SIZE;<br>&nbsp; FABS.szDockSize.cy &nbsp; &nbsp; := AB_DEF_DOCK_SIZE;<br>&nbsp; FABS.rcFloat.Left &nbsp; &nbsp; &nbsp;:= 0;<br>&nbsp; FABS.rcFloat.Top &nbsp; &nbsp; &nbsp; := 0;<br>&nbsp; FABS.rcFloat.Right &nbsp; &nbsp; := 0;<br>&nbsp; FABS.rcFloat.Bottom &nbsp; &nbsp;:= 0;<br>&nbsp; FABS.nMinWidth &nbsp; &nbsp; &nbsp; &nbsp; := 0;<br>&nbsp; FABS.nMinHeight &nbsp; &nbsp; &nbsp; &nbsp;:= 0;<br>&nbsp; FABS.nMaxWidth &nbsp; &nbsp; &nbsp; &nbsp; := GetSystemMetrics(SM_CXSCREEN);<br>&nbsp; FABS.nMaxHeight &nbsp; &nbsp; &nbsp; &nbsp;:= GetSystemMetrics(SM_CYSCREEN);<br>&nbsp; FABS.szMinDockSize.cx &nbsp;:= 0;<br>&nbsp; FABS.szMinDockSize.cy &nbsp;:= 0;<br>&nbsp; FABS.szMaxDockSize.cx &nbsp;:= GetSystemMetrics(SM_CXSCREEN) div 2;<br>&nbsp; FABS.szMaxDockSize.cy &nbsp;:= GetSystemMetrics(SM_CYSCREEN) div 2;<br>&nbsp; FABS.abTaskEntry &nbsp; &nbsp; &nbsp; := abtFloatDependent;<br>&nbsp; FabEdgeProposedPrev &nbsp; &nbsp;:= abeUnknown;<br>&nbsp; FbFullScreenAppOpen &nbsp; &nbsp;:= False;<br>&nbsp; FbAutoHideIsVisible &nbsp; &nbsp;:= False;<br><br>&nbsp; // Set default location of the settings in the registry<br>&nbsp; with FabSettingsLocation do begin<br>&nbsp; &nbsp; RootKey := AB_DEF_ROOT_KEY;<br>&nbsp; &nbsp; KeyName := AB_DEF_KEY_NAME;<br>&nbsp; end;<br><br>&nbsp; // Call base class<br>&nbsp; inherited Create(Owner);<br>end;<br><br><br>// TAppBar.Destroy ////////////////////////////////////////////////////////////<br>destructor TAppBar.Destroy;<br>begin<br>&nbsp; ResetSystemKnowledge;<br><br>&nbsp; // Call base class<br>&nbsp; inherited Destroy;<br>end;<br><br><br>// TAppBar.UpdateBar //////////////////////////////////////////////////////////<br>procedure TAppBar.UpdateBar;<br>begin<br>&nbsp; SetEdge(GetEdge);<br>end;<br><br>// TAppBar.LoadSettings ///////////////////////////////////////////////////////<br>function TAppBar.LoadSettings : Boolean;<br>var<br>&nbsp; reg : TRegistry;<br>&nbsp; abs : TAppBarSettings;<br>begin<br>&nbsp; // Set the default return value<br>&nbsp; Result := False;<br>&nbsp; // Create a TRegistry object<br>&nbsp; reg := TRegistry.Create;<br>&nbsp; // Set the RootKey<br>&nbsp; reg.RootKey := FabSettingsLocation.nRootKey;<br>&nbsp; // Open the KeyName<br>&nbsp; if reg.OpenKey(FabSettingsLocation.KeyName, False) then<br>&nbsp; &nbsp; // Load the FABS record from the 'default' value<br>&nbsp; &nbsp; if reg.ReadBinaryData('', abs, sizeof(abs)) = sizeof(abs) then begin<br>&nbsp; &nbsp; &nbsp; FABS := abs;<br>&nbsp; &nbsp; &nbsp; Result := True;<br>&nbsp; &nbsp; end;<br>&nbsp; // Free the TRegistry object<br>&nbsp; reg.Destroy<br>end;<br><br>// TAppBar.SaveSettings ///////////////////////////////////////////////////////<br>function TAppBar.SaveSettings : Boolean;<br>var<br>&nbsp; reg : TRegistry;<br>begin<br>&nbsp; // Set the default return value<br>&nbsp; Result := False;<br>&nbsp; // Create a TRegistry object<br>&nbsp; reg := TRegistry.Create;<br>&nbsp; // Set the RootKey<br>&nbsp; reg.RootKey := FabSettingsLocation.nRootKey;<br>&nbsp; // Open the KeyName, creating it if not exists<br>&nbsp; if reg.OpenKey(FabSettingsLocation.KeyName, True) then begin<br>&nbsp; &nbsp; // Save the FABS record in the 'default' value<br>&nbsp; &nbsp; reg.WriteBinaryData('', FABS, sizeof(FABS));<br>&nbsp; &nbsp; Result := True;<br>&nbsp; end;<br>&nbsp; // Free the TRegistry object<br>&nbsp; reg.Destroy<br>end;<br><br>end.<br><br>
 
老兄:你的問題已經過期n天了,請自己結束或提前,謝謝<br>各位:拜托不要貼那麼長的代碼,看到我頭都暈了,寫關鍵代碼就可以了
 
多人接受答案了。
 
后退
顶部