Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

List of Open Windows

63 views
Skip to first unread message

~ -------- Nic -------- ~

unread,
Dec 22, 1999, 3:00:00 AM12/22/99
to
How can I recreate the list of opened Windows which appear
in the Windows Menu? I thought about using DoCmd but couldn't
find a suitable command.

Tom van Stiphout

unread,
Dec 22, 1999, 3:00:00 AM12/22/99
to
On Wed, 22 Dec 1999 12:53:55 -0000, "~ -------- Nic -------- ~"
<memn...@geocities.com> wrote:

You will have to loop over the Forms collection:
Dim frm As Form
For Each frm In Forms
Debug.Print frm.Name
Next frm

-Tom.

~ -------- Nic -------- ~

unread,
Dec 22, 1999, 3:00:00 AM12/22/99
to
Yes, but that will not give me a list of opened windows in the Window menu
so that the User can select and activate the required window.

Tom van Stiphout <to...@syspac.com> wrote in message
news:3860cf1...@news.syspac.com...

Arvin Meyer

unread,
Dec 22, 1999, 3:00:00 AM12/22/99
to
Why reinvent the wheel? Use the window menu on the standard menubar, or make
your own menubar with customized choices.
---
Arvin Meyer

~ -------- Nic -------- ~ wrote in message
<945872572.25997.0...@news.demon.co.uk>...

Gary Rockley

unread,
Dec 22, 1999, 3:00:00 AM12/22/99
to
Nic,

This was kind of done on the fly so the code is not too fancy and it
only refers to open forms - although the principle is the same for other
objects.

1. You will need a form with a ListBox and a CmdButton for Requerying.
For the purposes of this exercise,
Name the form: FrmShowOpenForms
Name the ListBox: LstOpenForms
Name the CmdButton: CmdGetFormsList

For the ListBox, I'm using two columns bound on the first with the width
of the first column set to zero. This way the form caption is displayed
in the list box and not the proper form name. Double clicking the list
box moves the focus to the named form.
_____________________________________________________

2. This code populates the ListBox and is attached the the CmdButton.

Private Sub CmdGetFormsList_Click()

Dim frm As Form, intI As Integer
Dim intJ As Integer, CurOpenForms As String
Dim intControls As Integer, intForms As Integer
intForms = Forms.Count

If intForms > 0 Then
For intI = 0 To intForms - 1
Set frm = Forms(intI)
If Not frm.Caption = "" Then CurOpenForms = CurOpenForms &
frm.Name & ";" & frm.Caption & ";"
Next intI
End If

LstOpenForms.RowSource = CurOpenForms
LstOpenForms.Requery

End Sub
______________________________________________________________

3. This code allows switching the focus to the specified form.

Private Sub LstOpenForms_DblClick(Cancel As Integer)
On Error GoTo SelectForm_Err
Dim Myform As Form, Mycontrol As Control, Variable1 As String
Variable1 = LstOpenForms

Set Myform = Forms(Variable1)
Myform.SetFocus
Set Myform = Nothing
Exit Sub

SelectForm_Err:
DoCmd.OpenForm (Variable1) 'This re-opens a closed form still
displayed in the list box.
Set Myform = Nothing
Resume NextLine
NextLine:
End Sub
_________________________________________________________

Obviously, if a form has no caption it will not be displayed. If you
want the proper form name displayed, reverse the columns.

You could call the CmdGetFormsList_Click on form load and also call this
from every form as it closes in order that the list is always current.

Gary

Gary Rockley

unread,
Dec 22, 1999, 3:00:00 AM12/22/99
to
Nic,

I should have started my previous reply by saying, If you must do this
by code...

The code which I posted earlier is taken from a scheduler/contact
tracker which provides a constant reference for open items rather than
having to click Window.

...Otherwise, why not use a custom menubar and drag the Window item from
the Built-In Menus list. In a run-time app, this will display the open
windows/forms.

Gary

~ -------- Nic -------- ~

unread,
Dec 22, 1999, 3:00:00 AM12/22/99
to
The reason why I'm asking is thus:

On the Window Item from the Built-In Menu's list, there are the
items UnHide and Hide, both of these functions I want to remove.
However, if you was to remove them from the Built-In Menu they
would also disappear from the Main Menu which totally defeats the
object.

It seems the Built-In Menus are not copies of the original and I can't
see how I can create a copy of the Built-In Menu for tailoring.

Most of the Menu functions can be replicated using Macros and
AddMenuItem commands but the list of Opened Windows is not one
of them.

Gary Rockley <g...@mn.mediaone.net> wrote in message
news:3860F692...@mn.mediaone.net...

JWild

unread,
Dec 22, 1999, 3:00:00 AM12/22/99
to

~ -------- Nic -------- ~ wrote in message
<945879027.28729.0...@news.demon.co.uk>...

>The reason why I'm asking is thus:
>
>On the Window Item from the Built-In Menu's list, there are the
>items UnHide and Hide, both of these functions I want to remove.
>However, if you was to remove them from the Built-In Menu they
>would also disappear from the Main Menu which totally defeats the
>object.
>
>It seems the Built-In Menus are not copies of the original and I can't
>see how I can create a copy of the Built-In Menu for tailoring.

Create a new Custom Menu and set it's property to Menu Bar.
Go to Commands tab in Customize and choose New Menu Category,
Add the New menu to your custom menu, change the name to what you wish.
Now Ctrl drag the commands you want on this from the Window menu. It will
not alter the built in Window menu.

Joan

Peter Walker

unread,
Dec 23, 1999, 3:00:00 AM12/23/99
to
Arvin
That's not as dumb as it sounds, I have a *really* good macro driven menu
system incorporating some current_user_group() stuff for a version 2.0 app,
and I am considering the port to 2000, I would like to keep it, and the code
involved in porting to command bars is going to be a job and a half. (lets
not start the macro war again!). As I recall, there is some glr api stuff
for playing with menus that will work with macro menus but not command bars
masquerading as such, Although I realise that such solutions are not for the
beginner :-)

peter walker

"Arvin Meyer" <a...@m.com> wrote in message
news:83qnvg$q1s$1...@nntp5.atl.mindspring.net...


> Why reinvent the wheel? Use the window menu on the standard menubar, or
make
> your own menubar with customized choices.
> ---
> Arvin Meyer
>

> ~ -------- Nic -------- ~ wrote in message

Gary Rockley

unread,
Dec 23, 1999, 3:00:00 AM12/23/99
to
Nic,

I hadn't noticed this before and now I catch your drift, you appear to
be correct.

The only thing I'd suggest is to move the Hide/UnHide to a new menu
item. At least that way you still have them accessible through the
menubar - just not with the Window option.

The previously supplied code is useful for populating a form but I can
see that's not what you were after.

Gary.

Dimitri Furman

unread,
Dec 23, 1999, 3:00:00 AM12/23/99
to
Nic,

I have some code that dynamically builds a list of all open MDI windows
(forms, reports, etc(?)) under the Window menu on a custom commandbar.
Naturally, it needs to be run every time a window is opened/closed,
which is some pain and may require certain timer-based tricks.
Unfortunately, the code is entangled within an app so I can't post
something that works by itself right now. If you are interested, let me
know, I'll try so send you something to get you started.

etha...@my-deja.com

unread,
Dec 23, 1999, 3:00:00 AM12/23/99
to
Why is this better than the first suggestion to just loop through the
forms collection and see if the form IsLoaded()?

-E
http://www.freetechnicaltraining.com

In article <38621A6D...@cloud9.net>,


Sent via Deja.com http://www.deja.com/
Before you buy.

~ -------- Nic -------- ~

unread,
Dec 23, 1999, 3:00:00 AM12/23/99
to
I'd love to see it.

Dimitri Furman <dfu...@cloud9.net> wrote in message
news:38621A6D...@cloud9.net...

Dimitri Furman

unread,
Dec 23, 1999, 3:00:00 AM12/23/99
to
Well, I believe the purpose here is to have a standard MDI Windows menu
on the app's menubar where all open *windows* (not forms only) are
listed. It's easy to find out if an object is loaded, but we are talking
about having them all on a menu which activates corresponding window
when clicked.

etha...@my-deja.com wrote:
>
> Why is this better than the first suggestion to just loop through the
> forms collection and see if the form IsLoaded()?
>
> -E
> http://www.freetechnicaltraining.com
>
> In article <38621A6D...@cloud9.net>,
> Dimitri Furman <dfu...@cloud9.net> wrote:

> > Nic,
> >
> > I have some code that dynamically builds a list of all open MDI
> windows
> > (forms, reports, etc(?)) under the Window menu on a custom commandbar.
> > Naturally, it needs to be run every time a window is opened/closed,
> > which is some pain and may require certain timer-based tricks.
> > Unfortunately, the code is entangled within an app so I can't post
> > something that works by itself right now. If you are interested, let
> me
> > know, I'll try so send you something to get you started.
> >
> > ~ -------- Nic -------- ~ wrote:
> > >
> > > How can I recreate the list of opened Windows which appear
> > > in the Windows Menu? I thought about using DoCmd but couldn't
> > > find a suitable command.
> >
>

Dimitri Furman

unread,
Dec 23, 1999, 3:00:00 AM12/23/99
to
OK, here some code quickly slapped together, but it seems to work. At
least it's a start. The UpdateMenu function needs to be called after each
window is opened/closed for that window to appear on the Window menu.
The code for getting all forms in Z-order was originally written by
Terry Kreft (big thanks to him!) and posted in
microsoft.public.access.modulesdaovba group. The code to get a
window's class name is from Dev's website. Watch out for line wraps.

***code start***
Option Explicit
Option Base 0
'code by Dimitri Furman unless otherwise noted

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWndParent As Long, ByVal hWndChildAfter As Long, ByVal lpClassname As String, ByVal lpWindowName As String) As Long
Private Declare Function apiGetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function apiIsWindowVisible Lib "user32" Alias "IsWindowVisible" (ByVal hwnd As Long) As Long
Private Const mcWSVISIBLE = &H10000000
Private Const mcGWLSTYLE = (-16)

Private Declare Function apiGetClassName Lib "user32" Alias _
"GetClassNameA" (ByVal hwnd As Long, _
ByVal lpClassname As String, _
ByVal nMaxCount As Long) As Long

Public Function UpdateMenu()
'adds a Window menu with all currently open forms
'and reports to a custom menubar
On Error GoTo Err_Handler
Dim cbActive As CommandBar
Dim mnWindow As CommandBarPopup
Dim cbb As CommandBarButton
Dim varOpenObjects As Variant
Dim intCount As Integer
Dim strCaption As String

Set cbActive = CommandBars.ActiveMenuBar 'assume custom bar
If cbActive.BuiltIn Then GoTo Exit_Here
If Not (cbActive.Type = msoBarTypeMenuBar) Then GoTo Exit_Here

varOpenObjects = MDIWindowsZ 'get all open objects

On Error Resume Next
Set mnWindow = cbActive.Controls("Window")
On Error GoTo Err_Handler

If Not mnWindow Is Nothing Then mnWindow.Delete 'always build fresh

If IsArray(varOpenObjects) Then 'there are some open objects, build the Window menu
Set mnWindow = cbActive.Controls.Add(Type:=msoControlPopup, id:=1, Temporary:=True)
mnWindow.Caption = "&Window"
For intCount = LBound(varOpenObjects, 2) To UBound(varOpenObjects, 2) 'adding a window to the menu
Set cbb = mnWindow.Controls.Add(Type:=msoControlButton, id:=1, Temporary:=True)
strCaption = varOpenObjects(0, intCount).Caption & vbNullString
If Not Len(strCaption) > 0 Then strCaption = varOpenObjects(0, intCount).Name
cbb.Caption = "&" & CStr(intCount + 1) & " " & strCaption
cbb.OnAction = "=SwitchActiveObject(" & varOpenObjects(1, intCount) & ", " & Chr(34) & varOpenObjects(0, intCount).Name & Chr(34) & ")"
If intCount = 0 Then 'top MDI window
cbb.State = msoButtonDown
Else
cbb.State = msoButtonUp
End If
cbb.Style = msoButtonCaption
Next intCount
End If

cbActive.RowIndex = msoBarRowFirst

Exit_Here:
On Error Resume Next
Set cbb = Nothing
Set mnWindow = Nothing
Set cbActive = Nothing
Exit Function

Err_Handler:
MsgBox "Error " & Err.Number & ": " & Err.Description, vbCritical
Resume Exit_Here

End Function

Function MDIWindowsZ() As Variant
'*******************************************
'Purpose: Get Z order of open non-modal Forms
'Author: Terry Kreft, modified by Dimitri Furman to return reports too
'Date: December 01, 1998, 03:36:02 PM
'Called by: Any
'Calls: FindWindowEx (API)
'Inputs: None
'Output: Variant array of forms in Z Order
'*******************************************
Dim hWndMDIClient As Long
Dim hWndChildAfter As Long
Dim lngRet As Long
Dim varRet As Variant
Dim loform As Form, rpt As Report
Dim intLBound As Integer
Dim intUbound As Integer
Dim strClassName As String
Dim lngStyle As Long

varRet = Array(vbNullString)
ReDim varRet(1, 0)
hWndMDIClient = FindWindowEx(hWndAccessApp, 0&, "MDIClient", vbNullString)
hWndChildAfter = 0&

Do
hWndChildAfter = FindWindowEx(hWndMDIClient, hWndChildAfter, vbNullString, vbNullString)
If hWndChildAfter <> 0& Then
strClassName = fGetClassName(hWndChildAfter)
lngStyle = apiGetWindowLong(hWndChildAfter, mcGWLSTYLE)
If (strClassName = "OForm" Or strClassName = "OReport") And (lngStyle And mcWSVISIBLE) Then
varRet(0, UBound(varRet, 2)) = hWndChildAfter
ReDim Preserve varRet(1, UBound(varRet, 2) + 1)
End If
End If
Loop Until hWndChildAfter = 0&

If UBound(varRet, 2) > 0 Then
ReDim Preserve varRet(1, UBound(varRet, 2) - 1)
End If

intUbound = UBound(varRet, 2)
For intLBound = 0 To intUbound
For Each loform In Forms
If loform.hwnd = varRet(0, intLBound) Then
Set varRet(0, intLBound) = loform
varRet(1, intLBound) = acForm
Exit For
End If
Next loform
Set loform = Nothing

If Not IsObject(varRet(0, intLBound)) Then 'hwnd not in Forms
For Each rpt In Reports
If rpt.hwnd = varRet(0, intLBound) Then
Set varRet(0, intLBound) = rpt
varRet(1, intLBound) = acReport
Exit For
End If
Next rpt
Set rpt = Nothing
End If
Next intLBound

If IsObject(varRet(0, 0)) Then MDIWindowsZ = varRet

End Function

Function fGetClassName(hwnd As Long)
'Code courtesy of Dev Ashish
Dim strBuffer As String
Dim intCount As Integer

Const mconMAXLEN = 255

strBuffer = String$(mconMAXLEN - 1, 0)
intCount = apiGetClassName(hwnd, strBuffer, mconMAXLEN)
If intCount > 0 Then
fGetClassName = Left$(strBuffer, intCount)
End If

End Function

Function SwitchActiveObject(intObjType As Integer, strObjName As String)
On Error Resume Next

DoCmd.SelectObject intObjType, strObjName, False
Call UpdateMenu

End Function
***code end***


~ -------- Nic -------- ~ wrote:
>

> I'd love to see it.
>
> Dimitri Furman <dfu...@cloud9.net> wrote in message
> news:38621A6D...@cloud9.net...

0 new messages