抢分喽
<br>{<br> FILE: APPBAR.PAS by Eric Janssen (e.janssen@libertel.nl)<br><br> DESCRIPTION: Encapsuling of SHAppBarMessage<br>}<br>unit AppBar;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br> ShellApi;<br><br>const<br> WM_APPBAR = WM_USER +1;<br><br>type<br> TEdge = (abeLeft, abeTop, abeRight, abeBottom);<br><br> TQuerySizeEvent = procedure(Sender: TObject; Edge: TEdge; var Width, Height: Integer) of object;<br><br> TAppBar = class(TComponent)<br> private<br> { Private declarations }<br> m_ABD: TAppBarData;<br> m_WndProc: TWndMethod;<br> m_Edge: TEdge;<br> m_QuerySize: TQuerySizeEvent;<br> procedure SetEdge(const Value: TEdge);<br> procedure WndProc(var Msg: TMessage);<br> protected<br> { Protected declarations }<br> procedure ABRegister; virtual;<br> procedure ABUnregister; virtual;<br> procedure ABSetPos; virtual;<br> procedure ABPosChanged; virtual;<br> procedure ABFullScreenApp(Enabled: Boolean); virtual;<br> procedure ABSetAutoHide(Enabled: Boolean); virtual;<br> public<br> { Public declarations }<br> constructor Create(AOwner: TComponent); override;<br> destructor Destroy; override;<br><br> procedure Loaded; override;<br> published<br> { Published declarations }<br> property Edge: TEdge read m_Edge write SetEdge;<br> property QuerySize: TQuerySizeEvent read m_QuerySize write m_QuerySize;<br> end;<br><br>procedure Register;<br><br>implementation<br><br>procedure Register;<br>begin<br> RegisterComponents('Libertel', [TAppBar]);<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.ABRegister;<br>begin<br> // check if we are not in the Delphi IDE<br> if not (csDesigning in ComponentState) then<br> begin<br> // make sure we get the notification messages<br> m_WndProc:= TWinControl(Owner).WindowProc;<br> TWinControl(Owner).WindowProc:= WndProc;<br><br> m_ABD.cbSize:= SizeOf(TAppBarData);<br> m_ABD.hWnd:= TWinControl(Owner).Handle;<br> m_ABD.uCallbackMessage:= WM_APPBAR;<br><br> // register the application bar within the system<br> if SHAppBarMessage(ABM_NEW, m_ABD) = 0 then<br> raise Exception.Create(SysErrorMessage(GetLastError()));<br><br> // make it a toolwindow with no caption<br> if SetWindowLong(m_ABD.hWnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW or WS_EX_DLGMODALFRAME) = 0 then<br> raise Exception.Create(SysErrorMessage(GetLastError()));<br><br> if SetWindowLong(m_ABD.hWnd, GWL_STYLE, 0) = 0 then<br> raise Exception.Create(SysErrorMessage(GetLastError()));<br><br> SetWindowPos(m_ABD.hWnd, m_ABD.hWnd, 0, 0, 0, 0, SWP_FRAMECHANGED or SWP_NOACTIVATE or SWP_NOSIZE or SWP_SHOWWINDOW);<br> end;<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.ABSetPos;<br>var Height, Width: Integer;<br>begin<br> if not (csDesigning in ComponentState) then<br> begin<br> // default size<br> Width:= TWinControl(Owner).Width;<br> Height:= TWinControl(Owner).Height;<br><br> // request the new size<br> if Assigned(m_QuerySize) then<br> m_QuerySize(Self, m_Edge, Width, Height);<br><br> m_ABD.rc.Right:= GetSystemMetrics(SM_CXSCREEN);<br> m_ABD.rc.Bottom:= GetSystemMetrics(SM_CYSCREEN);<br><br> if (m_ABD.uEdge = ABE_LEFT) or (m_ABD.uEdge = ABE_RIGHT) then<br> begin<br> if m_ABD.uEdge = ABE_LEFT then m_ABD.rc.Left:= 0<br> else m_ABD.rc.Left:= GetSystemMetrics(SM_CXSCREEN) - Width;<br> m_ABD.rc.Top:= 0;<br> end else<br> begin<br> if m_ABD.uEdge = ABE_TOP then m_ABD.rc.Top:= 0<br> else m_ABD.rc.Top:= GetSystemMetrics(SM_CYSCREEN) - Height;<br> m_ABD.rc.Left:= 0;<br> end;<br><br> // query the new position<br> if SHAppBarMessage(ABM_QUERYPOS, m_ABD) = 0 then<br> raise Exception.Create(SysErrorMessage(GetLastError()));<br><br> // calculate the size<br> case m_ABD.uEdge of<br> ABE_LEFT:<br> m_ABD.rc.Right:= m_ABD.rc.Left + Width;<br> ABE_RIGHT:<br> m_ABD.rc.Left:= m_ABD.rc.Right - Width;<br> ABE_TOP:<br> m_ABD.rc.Bottom:= m_ABD.rc.Top + Height;<br> ABE_BOTTOM:<br> m_ABD.rc.Top:= m_ABD.rc.Bottom - Height;<br> end;<br><br> // set the new size<br> if SHAppBarMessage(ABM_SETPOS, m_ABD) = 0 then<br> raise Exception.Create(SysErrorMessage(GetLastError()));<br><br> // move the form<br> MoveWindow(m_ABD.hWnd, m_ABD.rc.Left, m_ABD.rc.Top,<br> m_ABD.rc.Right - m_ABD.rc.Left,<br> m_ABD.rc.Bottom - m_ABD.rc.Top, TRUE);<br><br> end;<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.ABUnregister;<br>begin<br> // check if the form is not being destroyed and not in the Delphi IDE<br> if not (csDesigning in ComponentState) then<br> begin<br> if not (csDestroying in ComponentState) then<br> TWinControl(Owner).WindowProc:= m_WndProc;<br><br> // remove the application bar<br> if SHAppBarMessage(ABM_REMOVE, m_ABD) = 0 then<br> raise Exception.Create(SysErrorMessage(GetLastError()));<br> end;<br>end;<br>//------------------------------------------------------------------------------<br>constructor TAppBar.Create(AOwner: TComponent);<br>var I: Cardinal;<br>begin<br> inherited Create(AOwner);<br><br> // check if we have an owner<br> if Assigned(AOwner) then<br> begin<br> // we could turn everything with a handle into a application-bar, but for<br> // for Delphi we only use descendants of TCustomForm<br> if (AOwner is TCustomForm) then<br> begin<br> // make sure we are the only one<br> for I:=0 to AOwner.ComponentCount -1 do<br> begin<br> if (AOwner.Components
is TAppBar) and (AOwner.Components <> Self) then<br> raise Exception.Create('Ooops, you need only *ONE* of these');<br> end;<br> end else<br> raise Exception.Create('Sorry, can''t do this only with TCustomForms');<br><br> end else<br> raise Exception.Create('Sorry, can''t do this without an owner');<br>end;<br>//------------------------------------------------------------------------------<br>destructor TAppBar.Destroy;<br>begin<br> ABUnregister();<br><br> inherited Destroy();<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.Loaded;<br>begin<br> inherited Loaded();<br><br> ABRegister();<br> ABSetPos();<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.SetEdge(const Value: TEdge);<br>begin<br> if (m_Edge <> Value) then<br> begin<br> m_Edge:= Value;<br> case m_Edge of<br> abeLeft:<br> m_ABD.uEdge:= ABE_LEFT;<br> abeTop:<br> m_ABD.uEdge:= ABE_TOP;<br> abeBottom:<br> m_ABD.uEdge:= ABE_BOTTOM;<br> abeRight:<br> m_ABD.uEdge:= ABE_RIGHT;<br> end;<br><br> ABSetPos();<br> end;<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.WndProc(var Msg: TMessage);<br>begin<br> if (Msg.Msg = WM_APPBAR) then<br> begin<br> case Msg.wParam of<br> ABN_STATECHANGE, ABN_POSCHANGED:<br> ABPosChanged();<br><br> ABN_FULLSCREENAPP:<br> ABFullScreenApp(Msg.lParam <> 0);<br> end;<br> end;<br><br> if (Msg.Msg = WM_WINDOWPOSCHANGED) then<br> begin<br> SHAppBarMessage(ABM_WINDOWPOSCHANGED, m_ABD);<br> end;<br><br> if (Msg.Msg = WM_ACTIVATE) then<br> begin<br> SHAppBarMessage(ABM_ACTIVATE, m_ABD);<br> end;<br><br> // call the original WndProc<br> if Assigned(m_WndProc) then<br> m_WndProc(Msg);<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.ABPosChanged;<br>var rc, rcWindow: TRect;<br> Height, Width: Integer;<br>begin<br> rc.Top:= 0;<br> rc.Left:= 0;<br> rc.Right:= GetSystemMetrics(SM_CXSCREEN);<br> rc.Bottom:= GetSystemMetrics(SM_CYSCREEN);<br><br> GetWindowRect(m_ABD.hWnd, rcWindow);<br><br> Height:= rcWindow.Top - rcWindow.Bottom;<br> Width:= rcWindow.Right - rcWindow.Left;<br><br> case m_ABD.uEdge of<br> ABE_TOP:<br> rc.Bottom:= rc.Top + Height;<br><br> ABE_BOTTOM:<br> rc.Top:= rc.Bottom - Height;<br><br> ABE_LEFT:<br> rc.Right:= rc.Left + Width;<br><br> ABE_RIGHT:<br> rc.Left:= rc.Right - Width;<br> end;<br><br> ABSetPos();<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.ABFullScreenApp(Enabled: Boolean);<br>var State: Integer;<br> Flags: HWND;<br>begin<br> State:= SHAppBarMessage(ABM_GETSTATE, m_ABD);<br><br> if Enabled then<br> begin<br> if (State and ABS_ALWAYSONTOP) <> 0 then<br> Flags:= HWND_TOPMOST<br> else<br> Flags:= HWND_BOTTOM;<br><br> SetWindowPos(m_ABD.hWnd, Flags, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);<br> end else<br> begin<br> if (State and ABS_ALWAYSONTOP) <> 0 then<br> SetWindowPos(m_ABD.hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);<br> end;<br>end;<br>//------------------------------------------------------------------------------<br>procedure TAppBar.ABSetAutoHide(Enabled: Boolean);<br>begin<br> if not (csDesigning in ComponentState) then<br> begin<br> if Enabled then m_ABD.lParam:= -1<br> else m_ABD.lParam:= 0;<br><br> if SHAppBarMessage(ABM_SETAUTOHIDEBAR, m_ABD) <> 0 then<br> raise Exception.Create(SysErrorMessage(GetLastError()));<br> end;<br>end;<br>//------------------------------------------------------------------------------<br><br>end.