![]() |
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 |
![]() |
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 ('')! |
| 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 |
| Toolbar Menu |
![]() |
![]() |
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)
|
| 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 |
| 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 |