Create a Dockable, AutoHide AppBar
This program demonstrates how to create an Appbar similar
to the Window's taskbar or an Explorer toolbar. Like the taskbar, the
appbar can be docked to any screen edge and can be
set to AutoHide. The core of this program is the
SHAppBarMessage api function.
While docked, the portion of the screen under the appbar is reserved and is
generally unavailable for use by other (well behaved) applications. For
example, set the taskbar to always display (Click Start, Settings, Taskbar,
uncheck Auto hide, check Always on top then click OK). Now start and
maximize Explorer. Explorer fills the entire desktop minus the
taskbar. Drag the taskbar to a different location and verify this still
holds. MDI forms created with Visual Basic automatically act this
way. For non MDI forms that you manually size, you must add this behavior
programmatically. To determine the useable area of the screen minus
appbars, taskbars, IE toolbars, etc., see the Determine
Screen Work Area code below.
An AutoHide appbar is one that is hidden from view except for a thin line along
the edge of the screen that it is docked to. When the cursor is
positioned over the appbar it becomes exposed. When the cursor
subsequently moves off the appbar, it again hides itself. Autohide
appbars are typically set to be the top most window
so that they are displayed on top of any application occupying the portion of
the desktop used by the appbar. This way the autohide appbar is always
available yet does not consume any desktop real estate.
Undocked Form
Docked Appbar
Download Source Code
This project illustrates the following concepts:
-
Creating appbars and adding them to Window's appbar list with
SHAppBarMessage.
-
Moving a form with no title bar with SetWindowPlacement.
-
Determining the cursor's screen coordinates using GetCursorPos.
-
Getting the screen resolution with GetSystemMetrics.
-
Making a window always on top using SetWindowPos.
Except for SHAppBarMessage these concepts are
discussed in detail in their own separate examples in my code library.
This code creates an appbar along the top edge of the screen. See the
pSetAppBarDimensions procedure and the declarations section of the bas module
for more details.
'
' Register a new appbar and reserve the screen area.
'
lResult = SHAppBarMessage(ABM_NEW, BarData)
lResult = SetRect(BarData.rc, 0, 0, glScreenWidth, glScreenHeight)
bSetPosition = False
'
' Set the desired appbar location.
'
With BarData
.uEdge = ABE_TOP
.rc.Top = 0
.rc.Left = 0
.rc.Right = glScreenWidth
glHeight = (frmDock.tbrToolbar.ButtonHeight + 60) \ glTwipsPerPixelY
If gbAutoHide Then
'
' If we want an AutoHide appbar, see if one exists on
' this edge of the screen. Only one can exists at a time.
'
If SHAppBarMessage(ABM_GETAUTOHIDEBAR, BarData) = 0 Then
'
' Register our appbar as AutoHide. If successful, request
' the desired position (ABM_SETPOS), retrieve its handle
' and move the form to that location.
'
.lParam = True
If SHAppBarMessage(ABM_SETAUTOHIDEBAR, BarData) <> 0 Then
.rc.Bottom =
.rc.Top + EXPOSURE
lResult = SHAppBarMessage(ABM_SETPOS, BarData)
.rc.Top = 0
lResult =SHAppBarMessage(ABM_GETAUTOHIDEBAR, BarData)
glAppBarHandle = lResult
lResult = SetWindowPos(.hwnd, HWND_TOP, .rc.Left, .rc.Top - glHeight, _
.rc.Right - .rc.Left, glHeight + EXPOSURE, SWP_NOACTIVATE)
Else
bSetPosition = True
End If
Else
'
' There was already an AutoHide appbar on this screen edge.
'
bSetPosition = True
bFail = True
End If
Else
'
' An AutoHide appbar already exists.
'
bSetPosition = True
End If
If bSetPosition Then
'
' An autohide appbar exists on this edge.
' Use a non-autohide appbar instead.
'
gbAutoHide = False
.rc.Bottom = glHeight
lResult = SHAppBarMessage(ABM_SETPOS, BarData)
lResult = SetWindowPos(.hwnd, HWND_TOP, .rc.Left, .rc.Top,
.rc.Right - .rc.Left, _
glHeight, SWP_NOACTIVATE)
End If
'
' Save the ACTUAL appbar coordinates and position the form.
' The ABM_SETPOS doesn't actually set the appbar position
' but requests the location specified by the rc structure.
' The .rc values are set to actual coordinates assigned to
' the appbar which may differ from the requested ones.
'
glAppBarTop = .rc.Top
glAppBarLeft = .rc.Left
glAppBarRight = .rc.Right
glAppBarBottom = .rc.Top + .rc.Bottom
frmDock.tbrToolbar.Align = vbAlignTop
frmDock.tbrToolbar.Height = glHeight
End With
If bFail Then
'
' Displaying a modal dialog locks up Windows so a non modal form is used.
' The message is the exact one Windows uses in this situation.
'
frmMessage.Show vbModeless
End If
Determining Screen Work Area
|
Bas module code:
Public Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" _
(ByVal uAction As Long, ByVal uParam As Long, lpvParam As Any, _
ByVal fuWinIni As Long) As Long
Form code:
Dim lLeft as Long
Dim lTop as Long
Dim lWidth as Long
Dim lHeight as Long
Dim lTwipsPerPixelX as Long
Dim lTwipsPerPixelY as Long
Dim apiRect As RECT
Const SPI_GETWORKAREA = 48
Call SystemParametersInfo(SPI_GETWORKAREA, vbNull, apiRect, 0)
lTwipsPerPixelX = Screen.TwipsPerPixelX
lTwipsPerPixelY = Screen.TwipsPerPixelY
'
' Coordinates of useable screen area.
'
lLeft = apiRect.Left * lTwipsPerPixelX
lTop = apiRect.Top * lTwipsPerPixelY
lWidth = (apiRect.Right * lTwipsPerPixelX) - lLeft
lHeight = (apiRect.Bottom * lTwipsPerPixelY) - lTop
Run the project to display the floating form.
Docking
Move the form to any screen edge to dock it. Once docked, drag it to a
different edge and notice how the desktop icons shift as the reserved/usable
portion of the desktop is changed.
Dock it to the same edge as the taskbar to see that it is docked along the
taskbar and not the screen edge. This is because the taskbar has already
reserved that portion of the desktop. If you have IE, create a toolbar
(right click the taskbar, select toolbar, links). Dock the appbar to a
screen edge then dock the IE toobar to the same edge. Notice the IE
toolbar is docked along side the appbar because the appbar already had that
screen area reserved.
Undocking
Drag the form away from the edge of the desktop to show the floating form.
Auto Hide
To autohide the form, click the second toolbar button. To turn off the
autohide feature, click the third toolbar button.
Exiting
To exit the program, click the first toolbar button.
|