Get a Handle on Window State
Using the IsZoomed and IsIconic API calls to return the window state (minimized, maximized, or restored) of a form, report, or Access itself.
If you use windowed forms in Access ("Overlapping Windows" as opposed to "Tabbed Documents"), then you have to be aware of the three possible states of each form or report window: minimized, maximized, or normal (restored).
Access VBA has three corresponding methods to set the window state of a form or report object:
DoCmd.Restore. What VBA does not have is any built-in way to check the state of a given form or report window. Let's address that.
IsZoomed and IsIconic API calls
Luckily for us, there are two simple Windows API calls that will provide this information. The first,
IsZoomed, will return True if the window handle passed to it belongs to a window that is maximized. The second,
IsIconic, returns True if the passed window handle belongs to a minimized window.
What the heck is a window handle?
A window handle is nothing more than a reliable way to refer to a specific window when communicating with the Windows API. That's obviously a simplification, but for our purposes it will suffice.
The typical naming convention when referring to window handles is
hWnd ("h" for handle and "Wnd" for window). Access VBA provides properties that make it easy to retrieve the window handle for the Access application itself (
Application.hWndAccessApp), as well as for form and report objects (e.g.,
On a side note, retrieving the window handle for individual controls--such as text boxes or combo boxes--is not so easy. And, yes, form controls are implemented as "windows." For an example of how some code could be simpler if Access exposed the window handles of form controls, refer to Determining Combobox's Dropped State, by Dev Ashish and Stephen Lebans.
The stackoverflow answer below provides a good explanation of the window handle concept with a bit more technical background.
'Functions return 1 for true and 0 for false; multiply result by -1 for safer Boolean use #If VBA7 Then Private Declare PtrSafe Function IsZoomed Lib "user32" (ByVal hWnd As LongPtr) As Integer Private Declare PtrSafe Function IsIconic Lib "user32" (ByVal hWnd As LongPtr) As Integer #Else Private Declare Function IsZoomed Lib "user32" (ByVal hWnd As Long) As Integer Private Declare Function IsIconic Lib "user32" (ByVal hWnd As Long) As Integer #End If Function IsMaximized(hWnd As Long) As Boolean IsMaximized = IsZoomed(hWnd) * -1 End Function Function IsMinimized(hWnd As Long) As Boolean IsMinimized = IsIconic(hWnd) * -1 End Function
Multiplying by -1?
Note that in the code above, I'm multiplying the result from the IsZoomed and IsIconic functions by -1. This is not necessary in this context, but it's a good habit to get into.
VBA stores Booleans as 16-bit signed integers. The only "False" value is zero. Anything other than zero is considered "True." Combine that with the fact that And, Or, and Not are bitwise operations, and you have a recipe for some unexpected results:
'This works how you would expect: ?CBool(-1) True ?CBool(Not -1) False 'This...probably not so much: ?CBool(1) True ?CBool(not 1) True
This topic deserves its own article, but I wanted to provide some brief background to explain this otherwise odd bit of code.
Image by Christoph Schütz from Pixabay