How to show open windows in menubar?

How can i display all open windows and give the user the chance to switch to them as a menuItem in a MenuBar?

Michael

I created a subclass of MenuItem to create a menu item array of all open (document) windows:

[code]Class WindowListMenuItem
Inherits MenuItem

Sub EnableMenu() // This is the built-in EnableMenu event
Visible = ( Index <> 0 ) // The one with Index 0 - the one created in the IDE - is always invisible
End Sub

Sub Update()
// Start with the last menu item in the Windows menu and delete all until we are at the one with Index = 0
Do
Dim item As MenuItem = WindowMenu.Item(WindowMenu.Count - 1)
If item.Index = 0 Then
Exit
End
item.Tag = Nil // Release the Window stored in the Tag property
item.Close()
Loop

// Loop over all windows of the application and add them and their titles to arrays
Dim windows() As Window
Dim titles() As String
For i As Integer = 0 To WindowCount - 1
Dim window As Window = Window(i)
If Not window.Modal And window.Visible And window.Title <> “” Then
windows.Append(window)
titles.Append(window.Title)
End
Next

// Sort the windows by their titles
titles.SortWith(windows)

// Create a menu item for each window
For i As Integer = 0 To windows.Ubound
Dim item As MenuItem = New WindowListMenuItem()
Dim window As Window = windows(i)
item.Name = WindowListItem(0).Name
item.Index = i + 1
item.Text = window.Title
item.Tag = window
item.Checked = ( Window(0) = window And Not window.Minimized And window.Visible ) // *)
item.Enabled = Not Window(0).Modal
WindowMenu.Append(item)
Next
End Sub

// *) Minimized is an extension methods I created (for example the declare is “isMiniaturized” on Cocoa).

End Class[/code]

Then I create a „WindowListItem As WindowListMenuItem“ as last item in the Windows menu. The Index is set to 0 (so we have the menu item array start point).

In the App’s EnableMenuItems event:

WindowListItem(0).Update()

Then I created a WindowListItem menu handler in App:

Dim item As MenuItem = WindowListItem(index) Dim window As Window = item.Tag window.Show() Return True

Wow, a lot of code for this small task. No other, simpler way to do this?

Michael

Do you really think I have two solutions for this in my apps and then deliberately - out of sadism - posted the longer one?

Yes. Come on Eli, show us the short version :wink:

Look at rbstuff

For Mac OS X you can use this in the app open event:

// Automatic Window Menu
#if TargetCocoa then
// - Set-up the Window Menu #if TargetCocoa then
// - The setWindowsMenu function is a class function (shared method) of NSApplication.
// - #1 First let’s get to our NSApplication ‘sharedApplication’ object.
declare function NSClassFromString lib “Cocoa” ( className as CFStringRef ) as Ptr
declare function sharedApplication lib “Cocoa” selector “sharedApplication” ( classRef as Ptr ) as Ptr
Dim NSApplicationRef as Ptr = sharedApplication( NSClassFromString( “NSApplication” ) )
// - #2 Now that we have a NSApplicationRef, we can work with it.
// We can’t just pass the menuitem handle, we must get it’s submenu NSMenuItemRef first.
declare function getSubMenu lib “Cocoa” selector “submenu” ( NSMenuItemRef as integer ) as Ptr
declare sub setWindowsMenu lib “Cocoa” selector “setWindowsMenu:” ( appRef as Ptr, NSMenuItemRef as Ptr )
// - #3 Now we get the ‘subMenu’ NSMenuItemRef from the Xojo menuitem.
// Then we can tell the NSApplication to set the subMenu as the Windows Menu and let Cocoa
// handle the Window menu for us.
Dim subMenuRef as Ptr = getSubMenu( windowMenu.handle( menuItem.handleType.CocoaNSMenuItem ) )
setWindowsMenu( NSApplicationRef, subMenuRef )
#endif

Make a new menu in your default MenuBar.

Examples/Desktop/Menus/WindowMenu

Eli - considering that Michael didn’t say thank you - I will do it.
Thank you - I appreciate you spending the time to post that solution here. :slight_smile:

hey, hey, hey… didn’t say thank you? for me this conversation was not finished.

And my question about a shorter version was not totally useless. Paul, your example does exactly what i want.

Thank you ALL.

Interestingly my solution is shorter (in count of lines and methods) and the code is not spread all over the place.
Hey, everybody is entitled to his own opinion!

[quote=115775:@Horst Jehle]For Mac OS X you can use this in the app open event:

// Automatic Window Menu
#if TargetCocoa then
// - Set-up the Window Menu #if TargetCocoa then
// - The setWindowsMenu function is a class function (shared method) of NSApplication.
// - #1 First let’s get to our NSApplication ‘sharedApplication’ object.
declare function NSClassFromString lib “Cocoa” ( className as CFStringRef ) as Ptr
declare function sharedApplication lib “Cocoa” selector “sharedApplication” ( classRef as Ptr ) as Ptr
Dim NSApplicationRef as Ptr = sharedApplication( NSClassFromString( “NSApplication” ) )
// - #2 Now that we have a NSApplicationRef, we can work with it.
// We can’t just pass the menuitem handle, we must get it’s submenu NSMenuItemRef first.
declare function getSubMenu lib “Cocoa” selector “submenu” ( NSMenuItemRef as integer ) as Ptr
declare sub setWindowsMenu lib “Cocoa” selector “setWindowsMenu:” ( appRef as Ptr, NSMenuItemRef as Ptr )
// - #3 Now we get the ‘subMenu’ NSMenuItemRef from the Xojo menuitem.
// Then we can tell the NSApplication to set the subMenu as the Windows Menu and let Cocoa
// handle the Window menu for us.
Dim subMenuRef as Ptr = getSubMenu( windowMenu.handle( menuItem.handleType.CocoaNSMenuItem ) )
setWindowsMenu( NSApplicationRef, subMenuRef )
#endif

Make a new menu in your default MenuBar.[/quote]
Seems very familiar… Did you get this from xDev magazine?

[quote=115797:@Eli Ott]Interestingly my solution is shorter (in count of lines and methods) and the code is not spread all over the place.
Hey, everybody is entitled to his own opinion![/quote]
I have a smaller answer, but with code “spread all over the place”.

And it was XPlatform.

On the other hand: “thank you with all for the laughter.” (translated by systran).

Good reference.

Eli Thanks for the code works perfectly for what I wanted. Thanks, Joe

There is also an project in the examples folder that comes with Xojo.

Desktop/Menus/WindowMenu

Oops, I missed Paul’s reply giving the same info. Me bad