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. See my Shortcut Bar page to read about a full featured version of this sample that I created for a client that is currently in production and running on computers throughout the world.

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 Appbar
Undocked Form

Docked Appbar
Docked Appbar

Download Source Code

Concepts Illustrated

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.

Appbar Discussion

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
Instructions

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.


About TheScarms
About TheScarms


Sample code
version info

If you use this code, please mention "www.TheScarms.com"

Email this page


© Copyright 2016 TheScarms
Goto top of page