Introduction to PM Programming - Apr 1995
Written by Larry Salomon Jr.
The purpose of this column is to provide the readers out there who are not familiar with PM application development the information necessary to satisfy their curiosity, educate themselves, and give them an advantage over the documentation supplied by IBM. Of course, much of this stuff could probably be found in one of the many books out there, but the problem with books in general is that they don't answer the questions you have after you read the book the first time through.
I will gladly entertain feedback from the readers about what was "glossed over" or what was detailed well, what tangential topics need to be covered and what superfluous crap should have been removed. This feedback is essential in guaranteeing that you get what you pay for. <grin>
It should be said that you must not depend solely on this column to teach you how to develop PM applications; instead, this should be viewed as a supplement to your other information storehouses (books, the network conferences, etc.). Because this column must take a general approach, there will be some topics that you would like to see discussed that really do not belong here. Specific questions can be directed to me via email and I will do my best to answer them in a timely fashion.
The Menu Class
The menu class (WC_MENU) provides the most widely used functionality of any of the window classes, save the frame window. It is, simply put, a user-interface for a tree structure that is defined by the application. Each node on the tree, whether a leaf or branch node, has various characteristics, such as text and display attributes.
Some definitions need to be noted:
Leaf nodes (menu items) are end-selectable, a term I'll use to describe that the selecting action is terminated after the selection is made, and the identifier representing the menu item is returned to the application via the appropriate message.
Branch nodes differ from leaf nodes in that they lead to other parts of the tree. In PM parlance, branch nodes are items with sub menus associated with them and are not end-selectable.
Menu item - a single entity within the menu tree. This term is used to describe leaf nodes.
Submenu - a single entity within the menu tree. This term is used to describe branch nodes.
Pulldown - another term for submenu, since they (typically) are "pulled-down".
Pullright - another term for submenus that exist within submenus, since they (typically) are "pulled-right".
Menu item button - a menu item with the MIS_BUTTONSEPARATOR style that acts like a button on the action bar.
Action bar - this is a horizontal bar that usually is as wide as its parent. On this bar are menu items which may or may not contain submenus. To the right of the action bar there may be one or two menu item buttons.
Popup menu - this term describes a menu without an action bar which is accessed by a mouse action or keystroke. The menu "pops up" and looks like a pulldown with one or more pullrights.
Each node has a set of styles and attributes associated with it. Styles differ from attributes in that they describe what the "type" of the node is are not meant to be changed once set. Examples of styles are "submenu", "text", and "bitmap". Attributes, on the other hand, also describe appearance characteristics, but may vary from time-to-time and are frequently changed by the application in response to the state of the application. Examples of attributes are "checked" and "disabled".
Styles and Attributes
Menu item styles (MIS_) are listed below:
|MIS_BITMAP||Display a bitmap instead of text.|
|MIS_BREAK||Start a new column beginning with this item.|
|MIS_BREAKSEPARATOR||Same as MIS_BREAK except that a vertical rule is drawn to separate the columns.|
|MIS_BUTTONSEPARATOR||Positions the item at the end of the action bar and draws a vertical separator. The focus cannot be given to this item, but it may be selected with the mouse. Any menu control may have a maximum of two items with this style.|
|MIS_GROUP||This is a new style in Warp for which there is no documentation.|
|MIS_HELP||Selecting this menu item sends a WM_HELP message.|
|MIS_MULTMENU||This is a new style in Warp for which there is no documentation.|
|MIS_OWNERDRAW||This menu item is to be drawn by the application.|
|MIS_SEPARATOR||This menu item is a separator only. It is drawn as a horizontal line.|
|MIS_SINGLE||This is a new style in Warp for which there is no documentation|
|MIS_STATIC||This menu item is for informational purposes only and is not selectable.|
|MIS_SUBMENU||This menu item has a submenu associated with it.|
|MIS_SYSCOMMAND||Selecting this menu item sends a WM_SYSCOMMAND message.|
|MIS_TEXT||Display text instead of a bitmap.|
Menu item attributes (MIA_) are listed below:
|MIA_CHECKED||Place a checkbox to the left of the menu item|
|MIA_DISABLED||Do not allow the menu item to be selected|
|MIA_FRAMED||Draw a frame around the menu item|
|MIA_HILITED||Highlight the menu item when drawn|
|MIA_NODISMISS||Do not dismiss the submenu when a menu item has been selected|
From the Resource File
The general form of the menu template within a resource file is shown below:
menuitem:= MENUITEM "text", id [, style [, attribute ]] menublock:= menublock | submenu | menuitem submenu:= SUBMENU "text", id BEGIN menublock END menu:= MENU id BEGIN menublock END
My compiler teacher would kill me for writing a recursive grammar like that, but at least she can't flunk me anymore. <grin>
You can see that the top level items do not have to be submenus, even though this is not a common occurrence.
Menus are typically loaded in one of two fashions, depending on their purpose. Action bar menus are loaded by the WinCreateStdWindow function. All that you need to do is specify the FCF_MENU flag in the third parameter and insure that the id of the MENU itself matches the value specified by the eighth parameter. Popup menus are loaded using the WinLoadMenu function:
(HWND)WinLoadMenu(HWND hwndParent,HMODULE hmModule,ULONG ulId)
hwndParent, although the documentation states that this must be a frame window, is the window to own the menu. For action bar menus, it should indeed be a frame, but for popup menus, you should specify HWND_OBJECT. This is because the function automatically attaches the menu to the window specified which would display an action bar on the frame even though you were going to use it as a popup menu. hmModule is the handle of the DLL containing the menu resource. ulId specifies the id of the menu resource to be loaded.
Menu items send to the client either a WM_COMMAND, WM_SYSCOMMAND, or WM_HELP message depending on the style of the item. After receiving one of these messages, you perform the action associated with the menu item. Why would you use WM_SYSCOMMAND or WM_HELP instead of WM_COMMAND? WM_SYSCOMMAND is a "system command" such as "close the window" or "size the window" and is sent by the system menu (FCF_SYSMENU). WM_HELP is used by help related items such as "general help" or "help index".
This month we began looking at the menu control and the basic things that we need to know before moving onto the messages that the menu control accepts and sends. This will be the topic of the next column or two which will be accompanied by a sample program (or two).