Informatics, Uncategorized

Hide MS Access window from code

Suppose you’re building an application in MS Access, and your user interface consists of only one form. You don’t want to show the main application window, just the form you’ve designed. The most obvious way to do this is by making your form a popup form and do a call to the Windows API

ShowWindow Application.hWndAccessApp, SW_HIDE

from the Form_Open event to hide the main Access window. This will work, but there is a catch. Your application won’t be visible anymore in the windows taskbar and will easily get lost behind other programs.

A better way is to not hide the main Access window, but to resize it and position it behind your form. Put the following code in your form’s VBA module.

Option Compare Database
Option Explicit

Private Const sIconPath = "C:\MyAccessApp\AppIcon.ico"

Private rcMainWindow As RECT
Private rcForm As RECT

Private Sub Form_Close()
    SetWindowPos Application.hWndAccessApp, HWND_TOP, _
            rcMainWindow.Left, rcMainWindow.Top, _
            rcMainWindow.Right - rcMainWindow.Left, _
            rcMainWindow.Bottom - rcMainWindow.Top, SW_SHOWWINDOW
End Sub

Private Sub Form_Open(Cancel As Integer)
    Dim hIcon As Long
   
    GetWindowRect Application.hWndAccessApp, rcMainWindow
    GetWindowRect Me.hWnd, rcForm
   
    SetWindowPos Application.hWndAccessApp, HWND_TOP, _
            rcForm.Left, rcForm.Top, rcForm.Right - rcForm.Left, _
            rcForm.Bottom - rcForm.Top, SW_SHOWWINDOW
   
   hIcon = LoadImage(0&, sIconPath, IMAGE_ICON, 16, 16, LR_LOADFROMFILE)
   SendMessage Me.hWnd, WM_SETICON, 0, ByVal hIcon
End Sub
 

When your form is opened, the dimensions of the main window are stored for future reference. Then it’s size and position are set to match that of your form’s. Also note that an icon for the form is loaded from file.

Because a form can be dragged across the screen we need to check if it’s position has changed. This is done using a timer. Set the form’s timer interval to about 100 milliseconds and place the following code in the form’s On Timer event procedure:

Private Sub Form_Timer()
    Dim rc As RECT
    Dim rcMain As RECT
    GetWindowRect Me.hWnd, rc
    GetWindowRect Application.hWndAccessApp, rcMain
   
    If rc.Left <> rcForm.Left Or rc.Top <> rcForm.Top Or _
       rcMain.Right <> rc.Right Or rcMain.Bottom <> rc.Bottom Then
        GetWindowRect Me.hWnd, rcForm
        SetWindowPos Application.hWndAccessApp, HWND_TOP, _
            rc.Left, rc.Top, rc.Right - rc.Left, _
            rc.Bottom - rc.Top, SW_SHOWWINDOW
    End If
End Sub

To make these API calls work, you need to put the following declarations and constants in a separate module

Option Compare Database
Option Explicit

Public Const HWND_TOP = 0
Public Const SW_SHOWWINDOW = &H40

Public Const WM_GETICON = &H7F
Public Const WM_SETICON = &H80
Public Const ICON_SMALL = 0
Public Const ICON_BIG = 1

Public Const IMAGE_BITMAP = 0
Public Const IMAGE_ICON = 1
Public Const IMAGE_CURSOR = 2
Public Const IMAGE_ENHMETAFILE = 3
 

Public Const LR_DEFAULTCOLOR = &H0
Public Const LR_MONOCHROME = &H1
Public Const LR_COLOR = &H2
Public Const LR_COPYRETURNORG = &H4
Public Const LR_COPYDELETEORG = &H8
Public Const LR_LOADFROMFILE = &H10
Public Const LR_LOADTRANSPARENT = &H20
Public Const LR_DEFAULTSIZE = &H40
Public Const LR_LOADMAP3DCOLORS = &H1000
Public Const LR_CREATEDIBHeader = &H2000
Public Const LR_COPYFROMRESOURCE = &H4000
Public Const LR_SHARED = &H8000
 

Public Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
 

Declare Function GetWindowRect Lib "user32" _
    (ByVal hWnd As Long, lpRect As RECT) As Long
Declare Function SetWindowPos Lib "user32" _
    (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, _
    ByVal x As Long, ByVal y As Long, ByVal cx As Long, _
    ByVal cy As Long, ByVal wFlags As Long) As Long
 

Public Declare Function LoadImage Lib "user32" _
    Alias "LoadImageA" (ByVal hInst As Long, _
   ByVal lpsz As String, ByVal un1 As Long, _
   ByVal n1 As Long, ByVal n2 As Long, _
   ByVal un2 As Long) As Long
  
Public Declare Function SendMessage Lib "user32" _
    Alias "SendMessageA" (ByVal hWnd As Long, _
   ByVal wMsg As Long, ByVal wParam As Long, LParam As Any) As Long
 

Happy coding!

4 Comments

speak up

Add your comment below, or trackback from your own site.

Subscribe to these comments.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*Required Fields