Have you ever wondered how REALbasic is able to let you refer to menus by name, and how that works? For example, if you have a MenuItem named SpiffyMenu, then you can write code that accesses the SpiffyMenu item by name, like this:
[rbcode]
SpiffyMenu.Text = "&New Text"
SpiffyMenu.Tag = new Dictionary[/rbcode]
Well, it's a simple magical namespace that REALbasic provides for you. And whenever you hear "magical", you know it's going to be interesting.
Each class has its own namespace which defines a certain set of scope rules. So, for example, if you have the following class structure:
[rbcode]
Class MySpiffyClass
Function Foobar() as SomethingCool
return new SomethingCool
End Function
End Class[/rbcode]
Then you're able to call Foobar within any method of MySpiffyClass without qualifying it. You use this sort of functionality all the time, probably without even noticing it. But this is the functionality that makes the magic menu names work.
When you go to compile your application, the IDE will automatically render extra functions for you to handle magic menu names. Basically, it takes note of what MenuBar you have set for the window or App class. Then it takes every single menu item on that MenuBar and makes a function call for it, sort of like this:
[rbcode]
Function FileQuit() as MenuItem
return MenuBar.Child( "FileMenu" ).Child( "FileQuit" )
End Function[/rbcode]
That means that a magic menu name is nothing more than a function call which looks up the MenuItem. There's really nothing too magical about it aside from the fact that it's automatically done for you. And since the method lives within the scope of the App or Window class, the "proper" item is returned. If you ever run into compiler errors where the compiler doesn't know about the name of a MenuItem -- that's because the magic name wasn't created for some reason (such as the MenuBar not being set properly).
So now that you understand a bit more about how it works under the hood, here's some important things to take note of.
If you change your MenuBar at runtime, then it's entirely possible for a magic menu name to be nil. Here's a quick example of how that would work. Make a second MenuBar in your application, and remove the File and Edit menus from it. Give it a new Menu named "Foobar" with a child on it that says "Terminate" (and make sure you set its super to QuitMenuItem). Then add this code in the App.Open event:
[rbcode]
me.MenuBar = MenuBar2
FileQuit.Text = "Hello World"[/rbcode]
When you run the application, you'll see that it compiles just fine. However, you'll get a NilObjectException on the line changing FileQuit's text. You get this because the magic name resolves to Nil since the MenuBar property now points to something which can't be resolved.
The basic rule to follow is this -- if you change the MenuBar at runtime, or you start monkeying with items on the menu bar (by removing them), then you should not rely on magic menu names to work. They may resolve to something which wasn't intended (if the names happen to match), or may not resolve at all.
Now you should have a better understanding of how magic menu names work in REALbasic, which should help you to make better use of them.
Leave a comment