Menu Bar Creation ================= In WPY a menu bar is a class with a number of menu items. Each menu item has a specified parent which controls where it appears in the menu. Menu items are the usual buttons, check and radio buttons, and dividing lines. You don't create an instance of your class. Just create a class derived from CMenu and create the menu items in the __init__() method. Then register the menu in your template in your app's InitInstance() method. The system will create the menu from your class when it needs to. For example: class MyMenu(CMenu): # The only method is __init__() def __init__(self): CMenu.__init__(self) # Must call the base class! file = MenuFile(self) edit = MenuEdit(self) # file items: MenuFileNew(file) MenuFileClose(file) CMenuLine(file) # etc.... class MyApp(CWinApp): def InitInstance(self): templ = CMultiDocTemplate(MyDoc, MyFrame, MyView, MyMenu) Menu Items ========== In practice, most menu items you use will be the standard menu items discussed below. But for your own custom menu items use these classes. The "parent" is "self" within the menu class derived from CMenu. This represents the top menu bar. For non-top items, the parent is the button below which the item appears. The "text" is the text to appear on the button. Place the "&" character in the text to underline the next character. The system will use the underlined character for keyboard menu traversal. For example, "E&xit" will cause the "x" to be underlined. class CMenuButton # A normal menu button def __init__(self, parent, text): class CMenuCheck # Shows a check mark # The checked state of this button is self.wpyCheckValue (0 or 1) def __init__(self, parent, text): def SetCheck(self, check = 1): Call SetCheck to set/unset the checked state from your code. The WPY system maintains the checked state itself for user menu selections. class CMenuRadio # Part of a radio group # Specify the head button of the radio group as "group = None" # Specify the other buttons of the radio group as "group" = head button def __init__(self, parent, text, group = None): def SetCheck(self): Call SetCheck to make this button the selected button. The WPY system maintains the checked state itself for user menu selections. For any button in a radio group, the selected button is self.wpyRadioSelected. class CMenuLine def __init__(self, parent): Menu items on a menu bar may be positioned on the right side by setting the attribute item.wpyRightSide = 1. This is ineffective on Windows. Menu Message Handlers ===================== When the user selects a menu item, the handler for the item is searched for in the same way as a button press. See the button class for the search order. When a button is constructed, the default handler name (except for standard menu items) is "OnMenu" plus the capitalized text from each level of the menu. For example, the handler name for a File/Fix item is "OnMenuFileFix". You can change the handler name if you want: b = CMenuButton(file, "Fix") b.wpyHandler = "FixFile" The standard menu items have their own non-standard handler names. If you change the handler name, it converts the button to use your handler. Menu Update Handlers ==================== When a menu is about to be shown, it may be convenient to get a message so that the state of the menu can be altered, for example in order to enable or disable certain menu items. The WPY system will send a message in exactly the same way as the menu message handlers discussed above. The handler name is the same as the regular handler plus "UI". For example, "OnMenuFileFixUI" would be called. Each menu item may specify its own handler, or you could put all updates in a single handler. Popup Menus =========== A WPY popup menu is a menu not on the menu bar which probably was created by clicking a mouse button. For example: def OnRButtonDown(self, x, y, flags): pop = CMenu() # Construct a popup menu rect = self.GetWindowRect() # Get our window position pop.wpyLocX = rect.wpyLocX + x # Place popup at mouse position pop.wpyLocY = rect.wpyLocY + y i1 = CMenuButton(pop, "Button 1") # Make some menu items i2 = CMenuButton(pop, "Button 2") i3 = CMenuButton(pop, "Button 3") pop.TrackPopupMenu(self.wpyParent) # Show the popup Note that TrackPopupMenu(win) needs a frame window as win. The name of a popup is "", so the handler name of item "Button 1" is "OnMenuButton1". Menu items behave as usual, so you can change the handler names if you want. Accelerators ============ You can assign a key to a menu item so that when that key is pressed the menu item is invoked. This should be done with care, since this makes the key unavailable to OnChar() and OnVChar(). You may also assign several keys by using MakeAccel() more than once. CMenu::MakeAccel(self, obj, key, flags, text) obj The menu item. key The key as would be sent to OnChar() or OnVChar(). flags The flags as would be sent to OnChar() or OnVChar(). text Text to add to the menu item's text, such as "Ctrl+X". Or use "" for no added text. For example: b = CMenuButton(file, "Fix") # Add an accelerator key Control-F self.MakeAccel(b, "\006", wpycon.MK_CONTROL, "Ctrl+F") Imitating a Menu Selection ========================== Sometimes you may want to call the handler of a menu item from your code. The result is the same as the user selecting the menu button. To do that, call the Post() or Send() method of the menu button. For example: b = CMenuButton(file, "Fix..") global menu_file_fix = b # Could also use attrib. of wpyApp ... menu_file_fix.Post() You need to refer to the original menu button since it has the correct handler name and other attributes. But for the standard menu items, you do not need the original button, because all attributes are built in. So you can make a new button using a parent of None: MenuFileClose(None).Post() # Easier way to call standard menu item The Post() method will execute the menu command the next time the system is idle. The Send() method calls the command at once. Standard Menu Items =================== Most of the usual menu items such as File/Open and File/Close have a standard implementation in WPY. To use one, just add it to your menu. The WPY system provides the implementation, and there is nothing else you need to do. These standard buttons come with their own text, message text and handlers. The handlers have a non-standard name so they don't interfere with your code. That is, the handler for the File/Open menu item is NOT OnMenuFileOpen(). You can override a standard menu item by just changing the handler name. You could choose any name, but the usual standard name is probably a good choice. For example: b = MenuFileClose(parent) # Construct standard menu item b.wpyHandler = "OnMenuFileClose" # Replace default handler Of course, you could also just make a new custom button: b = CMenuButton(file, "Close") but then you would need to create the message text. If you need to "call the base class" of a standard menu item, use the Post() method discussed above. These are the standard menu items. The constructors are all of the usual menu item form, for example MenuFileNew(self, parent, text) but the text is provided, and should be omitted. So just enter the parent argument. For example: f = MenuFile(self) x = MenuFileNew(f) MenuLine(): # Just an alias for CMenuLine # Standard menu buttons for "File": MenuFile() Commands to open/close/save the document MenuFileNew() Create a new document MenuFileOpen() Open an existing document MenuFileClose() Close the active document MenuFileSave() Save the active document MenuFileSaveas() Save the active document with a new name MenuFilePrint() Print the current document MenuFilePrintersetup() Change printer settings, Windows only MenuFileExit() Quit the application # Standard menu buttons for "Edit": MenuEdit() Commands to edit the document MenuEditUndo() Undoes the last change, Windows only MenuEditRedo() Redoes the previously undone action, Windows only MenuEditCut() Removes the selection and puts it on the Clipboard MenuEditCopy() Copies the selection and puts it on the Clipboard MenuEditPaste() Inserts Clipboard contents at the insertion point MenuEditDelete() Erases the selection MenuEditSelectall() Selects the entire document # Standard menu buttons for "View": MenuView() Commands to change what is viewed MenuViewStatusbar(CMenuCheck) Show or hide the status bar # Standard menu buttons for "Window": MenuWindow() Commands to arrange the windows MenuWindowNewwindow() Open another window for the active document MenuWindowCascade() Arrange windows so they overlap, Windows only MenuWindowTilehorz() Arrange windows as non-overlapping tiles, Windows only MenuWindowTilevert() Arrange windows as non-overlapping tiles, Windows only MenuWindowArrangeicons() Arrange icons at the bottom of the window, Windows only # Standard menu buttons for "Help": MenuHelp() Commands to display program information MenuHelpAbout() Display program information, version number and copyright Misc ==== class WpyMenuItem(CMenu) An abstract class with methods inherited by the menu buttons. Methods Destroy(self) Destroy a menu button. Insert(self, index=999) Insert the menu button in its parent at "index". Index is 0, 1, ..., and an index past the end means to append the menu item.