Re: Testing for Open Navigation Pane

S

Sky

Sky said:
' API function to find a child window for an application handle.
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA"
(ByVal hwndParent As Long, ByVal hwndChildAfter As Long, ByVal lpszClass
As String, ByVal lpszWindow As String) As Long

' API function that returns 1 if a window handle is visible, 0 if
invisible or the handle is zero
Private Declare Function isWindowVisible Lib "user32" Alias
"IsWindowVisible" (ByVal hwnd As Long) As Long

' Returns True if the navigation window or database window is visible,
otherwise False.
' Example: ?isDbWindowVisible()

Public Function isDbWindowVisible() As Boolean
Dim hwnd As Long
If isAcc2007() Then ' Access 2007 Navigation Pane is a client of Access
itself
hwnd = FindWindowEx(Application.hWndAccessApp, 0,
"NetUINativeHWNDHost", vbNullString)
Else ' Database Browser is a subwindow of MDIClient inside
of Access
hwnd = FindWindowEx(Application.hWndAccessApp, 0, "MDIClient",
vbNullString) ' get Access MDI client Window
hwnd = FindWindowEx(hwnd, 0, "Odb", vbNullString) ' get the Access
Database Window
End If
isDbWindowVisible = (isWindowVisible(hwnd) <> 0)
End Function

- Steve

I've done some more testing with this, and I've seen it reposted elsewhere,
so I thought I should update it.

At least with Access 2007 SP1, there is an additional child window to more
accurately get the navigation pane status. So here is the corrected code.

' Returns True if the Access Navigation Pane or Database Window is visible,
otherwise False.
' Example: ?isDbWindowVisible()

Public Function isDbWindowVisible() As Boolean
Dim hWindow As Long
If Int(SysCmd(acSysCmdAccessVer)) >= 12 Then ' Access 2007 Navigation
Pane
hWindow = FindWindowEx(Application.hWndAccessApp, 0,
"NetUINativeHWNDHost", vbNullString)
hWindow = FindWindowEx(hWindow, 0, "NetUIHWND", vbNullString)
Else ' Access 20003 Database Window
hWindow = FindWindowEx(Application.hWndAccessApp, 0, "MDIClient",
vbNullString)
hWindow = FindWindowEx(hWindow, 0, "Odb", vbNullString)
End If
isDbWindowVisible = (isWindowVisible(hWindow) <> 0)
End Function


The above code can be used to hide the Navigation Pane such as in the
function below:

' Hide the Access Database Window or Navigation Pane.
' Example: DbWindowHide

Function DbWindowHide() As Boolean

If isDbWindowVisible() Then
Application.Echo False

'The following always works in Access 2007, but it does not compile
in prior Access versions.
'If Int(SysCmd(acSysCmdAccessVer)) >= 12 Then
' DoCmd.NavigateTo "acNavigationCategoryObjectType" ' not
documented properly in help
'End If

'The following SelectObject works in Access 2007 or prior, but in
2007 only if the Navigation Pane category
'is set to ObjectType and the Tables group is EXPANDED; otherwise
the Pane does not get the focus.
'If no object is visible at all, then the Pane automatically gets
the focus anyway, so expanded status does not matter.
DoCmd.SelectObject acTable, vbNullString, True

' hide the window
DoCmd.RunCommand acCmdWindowHide
Application.Echo True
End If

End Function

Why bother with hiding the navigation pane during run time? Theoretically,
if you set the database properties to disable the Navigation Pane in the
first place, the above code should not be needed at all. Unfortunately,
certain Access operations using DoCmd seem to make the Navigation Pane
reappear (such as any of the Transfer operations). Perhaps this will be
fixed in a future service pack.

Also, you may want to temporarily select an object in the database window to
run a built-in wizard, such as ad-hoc data import or export, and then hide
the window, although usually it is better to select a foreground object or
code around this.

An interesting "feature" of the Navigation Pane is that it is not guaranteed
to get the focus in a DoCmd.SelectObject command. If no other object is open
whatsoever, then it always has focus so there is no problem. But if there is
any other object on the screen, then DoCmd.SelectObject acTable,,True FAILS
to select the Navigation Pane UNLESS its category is set to Object Type and
it is EXPANDED for the tables group. Otherwise the Navigation Pane never
gets the focus, and the wrong object is hidden in the code above. At least
this is what I have found in some frustrating testing. So for the above to
work, make sure your Navigation Pane is displayed correctly first.

If you are coding only for Access 2007, then
DoCmd.NavigateTo "acNavigationCategoryObjectType"
is more reliable in putting the focus on the Pane independent of status.
Unfortunately, this line cannot compile in earlier Access versions if you
are trying to build a compatible version. Note that the string constant
"acNavigationCategoryObjectType" above is not a typo, it is indeed a weird
constant expressed as a string in quotes (the help file is wrong here).

With the ability to control categories and groups in the Navigation Pane, it
might become useful for a custom user interface itself, similar to Outlook.
(You can use the MSysNavPane tables to fill in the categories, groups and
objects programmatically.) But personally I dislike the Pane unless you have
VERY few objects indeed. It simply takes too many keystrokes or mouse clicks
to filter and select what you want, even with the useful Find/Filter tool at
the top. Perhaps Microsoft's vaunted "user interface testing" had very few
objects in their databases.

Rant: I also hate the arcane hotkey sequences in the ribbons; the key
strokes are totally unintuitive and even require double key strokes to
select some ribbon tabs and items. Most ribbon selections seem to require 4
or 5 keystrokes. This is improvement? I guess all their users tested by
clicking with the mouse. Ok, enough ranting.

- Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top