Sample33: Menu

Screenshot: Sample33.exe

Menus are a very powerful method to offer the user an abundance of functionality within a minimum of screen space. However, to the programmer menus are very tedious to handle; often it requires programming in 2 or 3 files concurrently.
Here, DLG means a significant boost of productivity. In standard Windows there are some 30 procedures for menu handling. In DLG they all are packed in one procedure. Most operations are one code line only. If you want, you can handle many menu items by one call. With DLG you can do in a few minutes what in conventional programming would take you a full working day!

The following sections will show you some examples of

Window Menu
Button Menu
Toolbar Menu
Statusbar Menu
Pop-up Menu

After each section you will find a bookmark at the right edge of the screen (top). You can jump back to the top by clicking on it.


Window Menu


Screenshot: Window menu

The simplest kind of menu is a "Window menu", a menu constantly associated with a Window. The menu bar is always at the same place and cannot be colored or painted. A Window menu is useful in small applications only. In major applications you would soon have menus all over the screen: the notorious setting of working on the computer, the nightmare of many users!

In DLG you can associate a menu with a window simply by one of the following code lines:

DlgBox ( ..., Dlg ( ..., "...\bMenu=*%x", hMenu, ... );
CreateDlg ( ..., Dlg ( ..., "...\bMenu=*%x", hMenu, ... );
SimpleDlgBox ("...\bMenu=*%x", hMenu, ... );
CreateSimpleDlg ("...\bMenu=*%x", hMenu, ... );

If you want to know more about launching dialogs in DLG,
see Sample 2.1, Sample 2.2 and Sample 2.3

Or, if you launched a conventional dialog by any of these methods, you can upgrade it:

UpgradeDlg ("Menu=*%x", hMenu, ... );

For upgrading a conventional dialog to full DLG functionality see Sample 2.1, "Upgrading"

"Menu=*%x", hMenu DLG-option to associate a menu with a window
(usually this window will be a dialog)

You can build a Window menu simply by a call of auxiliary procedure  DlgMenu :

HWND hPopup1 =  DlgMenu ("CreatePopup",
			 "Add ... ",		// item 0
			 "Add ... ",		// item 1
			   :
			 0);
HWND hPopup2 =  DlgMenu ("CreatePopup",
			 "Add ... ",		// item 0
			 "Add ... ",		// item 1
			   :
			 0);
HWND hMenu  =  DlgMenu("Create",
			"Add Text='Popup 1' Popup=%x", hPopup1,
			"Add Text='Popup 2' Popup=%x", hPopup2,
		  0);


"CreatePopup" action keyword to create a pop-up menu (empty at first!)
"Create" action keyword to create a window-menu (empty at first!)
"Add" action keyword to add an item to a menu
"Text=" option to define the text of a menu item
Note that multi-word text is bracketed in single apostrophes ('')!

top

Button Menu


Screenshot: Button menu

In DLG you can associate a menu with a button that you can arrange everywhere on screen, just where you think it is best for the user. Thus you can make sure the user always has all the operations right at hand that would make sense in the current context. You can minimize the chance to go astray in your application.

A menu is associated with a button simply by something like the following code lines:

HWND hPopup =  DlgMenu ("CreatePopup",
			"Add ... ",
			  :
			0);
CreateCtl ( ..., "Button\b ... CustomOp=%d,%d", CO_POPUP, hPopup);

For details of how to declare a button see Sample 1.1
especially "Pop-up Menu"

Or, if the button is part of a conventional dialog, you can upgrade it by:

UpgradeCtl (id, "CustomOp=%d,%d", CO_POPUP, hPopup1, ..., 0);

For upgrading a control to full DLG functionality see Sample 1.0, "Upgrading"

DlgMenu DLG procedure combining the functionality of 30 standard Windows proc's
"CustomOp=%d,%d", CO_POPUP, hPopup option to attach a custom operation (presenting pop-up menu  hPopup ) to a button
(for details see Sample 1.11, CO_POPUP)

In DLG the most frequently needed menu manipulations can be done by a single code line:

DlgMenu ("Gray Id=%d", id, "Menu=%x", hPopup, 0););
DlgMenu ("Enable Menu=%x", hPopup, "Id=%d", id, 0);
DlgMenu ("Remove Id=%d", id, "Menu=%x", hPopup, 0);
DlgMenu ("Insert Text=... Id=%d", id, "Menu=%x", hPopup, "Status='... ...'", 0);
DlgMenu ("Insert Separator Menu=%x", hPopup1, 0);

Note that the order of options after the action keyword (Gray , Enable, etc.) does not matter!

"Menu=%x", hPopup option to define the menu which the action refers to
Id=%d", id option to define the identifier of the menu item which the action refers to
"Status='... ...'" option to define the text to appear in the Statusbar when this menu item is selected
Note that multi-word text is bracketed in single apostrophes ('')!
"Separator" option to add/insert a menu separator

top

Toolbar Menu


Screenshot: Toolbar Menu (toolbar docked) Screenshot: Toolbar Menu (toolbar floating)

In many applications it is not very user-friendly to offer a menu far away from the user's task at hand, especially on larger screens. In DLG you can provide buttons on a  toolbar  that can be made  relocatable.  Thus, if menus are associated with the buttons, the user can shift this "menu bar" to any screen position that seems appropriate for the current task. In addition, toolbars can be colored, making the color to a subtle indicator of what the menus are referring to.

You can associate a menu with a toolbar button by the following code lines:

Toolbar ("...\bReloc ... ",
Control (..., "Button", ... , "...\b ... CustomOp=%d,%d", CO_POPUP, hPopup, 0),
:
0)

For details of how to declare a toolbar see Sample 3.2, especially section "Menubar"

In a DLG menu you can associate a menu item with any of the predefined operations, simply by using its DLG-specific constant (CO_...) as the item identifier:

char	szFilter [] = ".cpp-files\0*.cpp\0";
char	szFile [256];
HWND hPopup = DlgMenu ("CreatePopup",
	"Add Id=%d", CO_FILE, "Text='&open ...\tCtl+O' Shortcut=O",
	"File=%p", szFile, "MaxFile=%d", sizeof(szFile), 
	"Filter=%p", szFilter, 
	"Status='operation CO_FILE'",
	0)

If you want to know more about predefined operations, see Sample 1.6 and Sample 1.11

CO_FILE DLG-constant to associate the menu item with predefined operation  'Open' sub-dialog 
(details see Sample 1.6, "sub-dialog for file selection"
Shortcut=O option to make this menu item accessible by pressing the key combination  Ctrl + O 

A more versatile way to declare keyboard shortcuts to menu items is using auxiliary procedure  Accels :

HWND hPopup = DlgMenu ("CreatePopup",
	"Add Id=%d", CO_FILE, "Text='&open ...\tCtl+O'",
	:
	0)
	ACCELS*	pAccels = Accels (FCONTROL, 'O', CO_FILE,	
				  :
				  0);

Accels DLG auxiliary procedure to declare a shortcut to a menu item
(programmer jargon: "keyboard accelerator")
FCONTROL Parameter to declare this shortcut as a combination with the  Ctrl  key. As well, combinations with  Alt  or  Shift  can be declared by this parameter.
(for details see standard Windows help to  ACCEL  structure)
O Parameter to make this menu item accessible by pressing the key combination  Ctrl + O 
CO_FILE DLG-constant to associate the menu item with the predefined operation  'Open'sub-dialog 
(details see Sample 1.6, "sub-dialog for file selection")

The application's main window of which this menu is part of must have an option  Accels=  then. For example:

MainWindow ("<application title>\b"Accels=%x", pAccels,
	    :
	    0)

top

Statusbar Menu


Screenshot: Statusbar menu

Statusbar menus are hardly ever used till now, though they would add a good deal of user-friendliness to an application. It is well known that users tend to discern UIF elements by their position on screen, rather than by reading their text labels, etc.
So, you could improve the screen layout of your applications. For example, menus needed in everyday work could be arranged in the usual way, somewhere near the top of the screen. Menus offering more delicate operations that should be used more considerately should be arranged somewhere else, deliberately far apart from the "everyday" menus. The Statusbar would be a good place to do that.

A Statusbar button is associated with a menu similarly to a Toolbar:

Statusbar ("...", ...,
Control (..., "Button", ... , "...\b ... CustomOp=%d,%d Bottom", CO_POPUP, hPopup, 0),
  :
0)

For details of how to declare a Statusbar see Sample 3.1,
for Button see Sample 1.1
for CO_POPUP see Sample 1.11

"CustomOp=%d,%d", CO_POPUP, hPopup option to attach a custom operation (presenting pop-up menu  hPopup ) to a button
Bottom attribute option to have the pop-up menu bottom-aligned with statusbar

You can associate a menu item with an application-specific callback procedure by an option  Proc= :

HWND hPopup =  DlgMenu ("CreatePopup",
		"Add Id=%d", uId, "Text='&callback ...'"
		"Proc=%p", CallbackProc, "Param=%x", dwParam, 
		"Status='trigger callback proc'",
		0)

"Proc=%p", CallbackProc option to associate the menu item with the callback procedure  CallbackProc 
"Param=%x", dwParam option to have the 32bit-variable  dwParam  passed as parameter when calling the callback procedure

top

Pop-up Menu


Screenshot: Pop-up menu

In some applications it is not very meaningful to offer a relatively invariant menu at a fix place - according to the cursor position the context might change dramatically within a fraction of an inch. So it is more evident to the user, to press (e.g. the right) mouse button and to get a "context menu" offering exactly those operations that are reasonable at the current cursor position.

This user-friendliness you can provide simply by a few lines of code:

case WM_RBUTTONDOWN:	DlgMenu ("Track Menu=%x", hPopup, 
				 "Window=%x", hDlg, "lParam=%x", lParam,
				 0);
			break;

"Window=%x", hDlg option to define dialog window  hDlg  as the window where to display the pop-up menu  hPopup 
"lParam=%x", lParam option to define dialog parameter  lParam  as the 32-bit value determining the point where to display the pop-up menu  hPopup 

The framework of a callback procedure is as follows:

void CallbackProc (UINT uId, DWORD dwParam)
{
	:
}

uId identifier of menu item that triggered the callback procedure
(to make one callback procedure being able to handle several menu items)
dwParam 32bit-variable, declared as  "Param=%x", dwParam  when building the menu

top

Home | Outline | DLG