![]() |
![]() |
![]() |
![]() |
Conventional programming of an application involves quite some legwork, much coding effort but not exactly intellectual work. One of DLG's goals is to save you from this effort. MainWindow is the best representation of this orientation. In a purely technical sense, you could implement an application without it (if only in a long-winded way). With MainWindow however, it takes nearly half the time.
The following sections will show you some examples of
| MainWindow with Conventional Menu | |
| MainWindow with DlgMenu | |
| MainWindow with Popup Menu | |
| MainWindow with Floating UIF |
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.
| MainWindow with Conventional Menu |
![]() |
This is the simplest way of implementing an application: a perfect DLG
framework with a conventional menu built in. Well, there are more efficient ways to get an application.
It is also not a very user-friendly solution and could be done much better (see later).
But it is a solid, straight-forward implementation that is close to the thinking of conventional
programming. So you will quickly get results by it. Additionally, it opens up some subtle ways
to instil your corporate identity into the application (e.g. icon, cursor).
MainWindow ("<application title>\bBkColor=%x", RGB_LIGHT_BLUE,
"Icon=*IDI_SDI", "Cursor=*IDC_SDI",
"Menu=%x", ConvMenu(), "Accels=%x", MenuAccels(),
"CmdProc=%p", CmdProc,
0);
|
| "BkColor=%x", RGB_LIGHT_BLUE | option to make the background color of the application's main window to light-blue |
| "Icon=*IDI_SDI" | option to have an icon displayed in the application's title
bar and on its button in the task bar (in the application's .rc-file there is a line |
| "Cursor=*IDC_SDI" | option to have the cursor be changed to your custom cursor
when the mouse is on the application's main window (In the application's .rc-file there is a line |
| "Menu=%x", ConvMenu() | option to declare the menu being created by callback procedure
ConvMenu() - see the following coding scheme. (Note that the name of the callback procedure has brackets () added here, because not only its entry address is needed but the result of its execution.) |
| "Accels=%x", MenuAccels() | option to declare the accelerators table for the keyboard shortcuts (Again the result of its execution are needed, so brackets () are added here.) |
| "CmdProc=%p", CmdProc | option to declare the entry address of the callback procedure handling all WM_COMMAND messages |
The callback procedure for creation of a conventional menu looks like this:
HMENU ConvMenu()
{
HMENU hMenu, hMenu1, hMenu2, hMenu3;
hMenu1 = CreatePopupMenu();
AppendMenu (hMenu1, MF_STRING, 1000, "Item A&1\tCtrl+1");
AppendMenu (hMenu1, MF_STRING, 1001, "Item A&2\tAlt+2'");
AppendMenu (hMenu1, MF_STRING, 1002, "Item A&3\tShift+3");
hMenu2 = CreatePopupMenu();
AppendMenu (hMenu2, MF_STRING, 1100, "Item B&1\tCtrl+Alt+4");
AppendMenu (hMenu2, MF_STRING, 1101, "Item B&2\tCtrl+Shift+5");
AppendMenu (hMenu2, MF_STRING, 1102, "Item B&3\tCtrl+6");
hMenu3 = CreatePopupMenu();
AppendMenu (hMenu3, MF_STRING, 1200, "Item C&1\tCtrl+7");
AppendMenu (hMenu3, MF_STRING, 1201, "Item C&2\tCtrl+8");
AppendMenu (hMenu3, MF_STRING, 1202, "Item C&3\tCtrl+9");
hMenu = CreateMenu();
AppendMenu (hMenu, MF_POPUP, (UINT) hMenu1, "Submenu &A");
AppendMenu (hMenu, MF_POPUP, (UINT) hMenu2, "Submenu &B");
AppendMenu (hMenu, MF_POPUP, (UINT) hMenu3, "Submenu &C");
return hMenu;
}
|
For details see standard Windows help "AppendMenu"
The keyboard shortcuts are created as in the following coding scheme:
ACCELS* MenuAccels ()
{
ACCELS* pAccels = Accels (FCONTROL, '1', 1000,
FALT, '2', 1001,
FSHIFT, '3', 1002,
FCONTROL|FALT, '4', 1100,
FCONTROL|FSHIFT, '5', 1101,
FCONTROL, '6', 1102,
FCONTROL, '7', 1200,
FCONTROL, '8', 1201,
FCONTROL, '9', 1202,
0);
return pAccels;
}
|
For details compare Sample33, "Accels"
The code lines in the application's callback procedure handling the messages from the menu are looking as follows:
CmdProc (HWND hDlg, WPARAM wParam, LPARAM lParam)
{
int id = LOWORD (wParam);
switch (id)
{
case 1000: case 1001: case 1002:
MsgBox ("message from Submenu A", MB_OK,
"\tItem A%d clicked", id%10 + 1, 0);
break;
case 1100: case 1101: case 1102: ...
case 1200: case 1201: case 1202: ...
}
}
return TRUE;
}
|
For details to auxiliary procedure Accels see Sample33, "Accels". MsgBox comes with DLG Basic.
| MainWindow with DlgMenu |
![]() |
More efficient to implement, and more user-friendly, is this kind of
MainWindow . If you have statusbar
available in your DLG system, you can even declare a short explanation to every menu item. It will
be displayed in the first statusbar field, when the user is selecting a menu item. Thanks to
MainWindow this is done automatically.
An application with DlgMenu is created by something like the following coding scheme:
MainWindow ("<application title>\bBkColor=%x", RGB_LIGHT_BLUE,
"Icon=*IDI_SDI", "Cursor=*IDC_SDI",
"Menu=%x", DLGstyleMenu(), "CmdProc=%p", CmdProc,
Statusbar ("\bBkColor=%x", RGB_BEIGE,
"Font='Arial Narrow' Size=14", 200, 0),
0);
|
For details of how to declare a Statusbar see Sample 3.1
| "BkColor=%x", RGB_LIGHT_BLUE | option to make the background color of the application's main window to light-blue |
| "Icon=*IDI_SDI" | option to have an icon displayed in the application's title
bar and on its button in the task bar (in the application's .rc-file there is a line |
| "Cursor=*IDC_SDI" | option to have the cursor be changed to your custom cursor
when the mouse is on the application's main window (In the application's .rc-file there is a line |
| "Menu=%x", DLGstyleMenu() | option to declare the menu being created by callback procedure
DLGstyleMenu() - see the following coding scheme. (Note that the name of the callback procedure has brackets () added here, because not only its entry address is needed but the result of its execution.) |
| "CmdProc=%p", CmdProc | option to declare the entry address of the callback procedure handling all WM_COMMAND messages |
For creating a DlgMenu you can do the following:
HMENU DLGstyleMenu()
{
hMenu1 = DlgMenu ("CreatePopup",
"Add Id=1000 Text='Item A&1 Ctrl+1'"
"Status='Item A1' Shortcut='Ctrl + 1'",
"Add Id=1001 Text='Item A&2 Alt+2'"
"Status='Item A2' Shortcut=Alt+2",
"Add Id=1002 Text='Item A&3 Shift+3'"
"Status='Item A3' Shortcut=Shift+3",
0);
hMenu2 = DlgMenu ("CreatePopup",
"Add Id=1100 Text='Item B&1 Ctrl+Alt+4'"
"Status='Item B1' Shortcut=Ctrl+ Alt+4'",
"Add Id=1101 Text='Item B&2 Ctrl+Shift+5'"
"Status='Item B2' Shortcut=Ctrl+Shift+5'",
"Add Id=1102 Text='Item B&3 Ctrl+6'"
"Status='Item B3' Shortcut=Ctrl+6",
0);
hMenu3 = DlgMenu ("CreatePopup",
"Add Id=1200 Text='Item C&1 Ctrl+7'"
"Status='Item C1' Shortcut=Ctrl+7",
"Add Id=1201 Text='Item C&2 Ctrl+8'"
"Status='Item C2' Shortcut=Ctrl+8",
"Add Id=1202 Text='Item C&3 Ctrl+9'"
"Status='Item C3' Shortcut=Ctrl+9",
0);
HMENU hMenu = DlgMenu ("Create",
"Add Text='Submenu &A' Popup=%x", hMenu1,
"Add Text='Submenu &B' Popup=%x", hMenu2,
"Add Text='Submenu &C' Popup=%x", hMenu3,
0);
return hMenu;
}
|
| DlgMenu | DLG's auxiliary procedure for menu manipulations (see Sample33, e.g. Button Menu) |
| "CreatePopup" | option to create a popup menu (to be used as a sub-menu later) |
| "Add" | option to add a menu item |
| "Id=1000" | identifier of item to add |
| "Text='Item A&1 Ctrl+1'" | text of item to add ('Ctrl+1' indicates the keyboard shortcut of this item) |
| "Status='Item A1'" | explication of item to add, to be displayed in first field of statusbar |
| "Shortcut=Ctrl+1" | option to declare a keyboard shortcut of this item |
| "Popup=%x", hMenu1 | option to add a sub-menu to a main menu |
The other callback procedure (CmdProc) is the same as above.
| MainWindow with Popup Menu |
![]() |
More user-friendly, especially with a modern large screen,
is a MainWindow with Popup Menu.
Instead of moving the cursor far to a menu on the other side of the screen, the user just clicks
the right mouse button. Wherever the cursor is at that moment, a menu pops up. So the user can
have an application's full functionality right at hand at any time.
An application with a Popup Menu is achieved by:
MainWindow ("<application title>\bBkColor=%x", RGB_LIGHT_BLUE,
"Icon=*IDI_SDI", "Cursor=*IDC_SDI",
"Popup=%x", PopupMenu(), "CmdProc=%p", CmdProc,
"Status='Right-click or press F2 to get Popup Menu'",
Statusbar ("\bBkColor=%x", RGB_BEIGE, "Font='Arial Narrow'",
"Size=14", 200, 0),
0);
|
For details of how to declare a Statusbar see Sample 3.1
| "BkColor=%x", RGB_LIGHT_BLUE | option to make the background color of the application's main window to light-blue |
| "Icon=*IDI_SDI" | option to have an icon displayed in the application's title
bar and on its button in the task bar (in the application's .rc-file there is a line |
| "Cursor=*IDC_SDI" | option to have the cursor be changed to your custom cursor
when the mouse is on the application's main window (In the application's .rc-file there is a line |
| "Popup=%x", PopupMenu() | option to declare the popup menu being created by callback procedure
PopupMenu() - see the following coding scheme. (Note that the name of the callback procedure has brackets () added here, because not only its entry address is needed but the result of its execution.) |
| "CmdProc=%p", CmdProc | option to declare the entry address of the callback procedure handling all WM_COMMAND messages |
| "Status='Right-click or press F2 to get Popup Menu'" | option to declare the standard status text, to be displayed whenever
no other status text needs to be shown (Provides additional user friendliness, so the user never has to feel "left in the dark".) |
Creating a Popup Menu is done as follows (compare Sample33, esp. "Popup Menu"):
HMENU PopupMenu()
{
HMENU hMenu1 = DlgMenu ("CreatePopup",
"Add Id=%d", 1000, "Text='Item A&1 Ctrl+1'"
"Status='Item A1' Shortcut='Ctrl + 1'",
"Add Id=%d", 1001, "Text='Item A&2 Alt+2'"
"Status='Item A2' Shortcut='Alt+2'",
"Add Id=%d", 1002, "Text='Item A&3 Shift+3'"
"Status='Item A3' Shortcut=Shift+3",
0);
HMENU hMenu2 = DlgMenu ("CreatePopup",
"Add Id=%d", 1100, "Text='Item B&1 Ctrl+Alt+4'"
"Status='Item B1' Shortcut=Ctrl+Alt+4",
"Add Id=%d", 1101, "Text='Item B&2 Ctrl+Shift+5'"
"Status='Item B2' Shortcut=Ctrl+Shift+5",
"Add Id=%d", 1102, "Text='Item B&3 Ctrl+6'"
"Status='Item B3' Shortcut=Ctrl+6",
0);
HMENU hMenu3 = DlgMenu ("CreatePopup",
"Add Id=%d", 1200, "Text='Item C&1 Ctrl+7'"
"Status='Item C1' Shortcut=Ctrl+7",
"Add Id=%d", 1201, "Text='Item C&2 Ctrl+8'"
"Status='Item C2' Shortcut=Ctrl+8",
"Add Id=%d", 1202, "Text='Item C&3 Ctrl+9'"
"Status='Item C3' Shortcut=Ctrl+9",
0);
HMENU hMenu = DlgMenu ("CreatePopup",
"Add Text='Submenu &A' Status='Submenu A' Popup=%x", hMenu1,
"Add Text='Submenu &B' Status='Submenu B' Popup=%x", hMenu2,
"Add Text='Submenu &C' Status='Submenu C' Popup=%x", hMenu3,
0);
return hMenu;
}
|
| MainWindow with Floating UIF |
![]() |
The most efficient implementation of an application is a
MainWindow with Floating UIF.
This is also the most user-friendly solution: Not the cursor has to be moved to a distant tool,
the tool pops up where the cursor is. In addition, the user can arrange "detachable" toolbars freely on screen -
just as needed.
This is the most comfortable user interface an application can have these days. The full functionality of an application
is accessible at a minimum of cursor movements. The user is free at any time to decide what tools should be
on screen and where to place them. So far, only DLG-based applications offer that comfort.
An application with a Floating UIF is achieved by:
MainWindow ("<application title>\bBkColor=%x", RGB_LIGHT_BLUE,
"Icon=*IDI_SDI", "Cursor=*IDC_SDI",
"Popup=%x", FloatingMenu(), "CmdProc=%p", CmdProc,
"Status='Right-click or press F2 to get Floating UIF'",
Statusbar ("\bBkColor=%x", RGB_BEIGE, "Font='Arial Narrow'",
"Size=14", 200, 0),
0);
|
For details of how to declare a Statusbar see Sample 3.1
| "BkColor=%x", RGB_LIGHT_BLUE | option to make the background color of the application's main window to light-blue |
| "Icon=*IDI_SDI" | option to have an icon displayed in the application's title
bar and on its button in the task bar (in the application's .rc-file there is a line |
| "Cursor=*IDC_SDI" | option to have the cursor be changed to your custom cursor
when the mouse is on the application's main window (In the application's .rc-file there is a line |
| "Popup=%x", FloatingMenu() | option to declare the popup menu being created by callback procedure
FloatingMenu() - see the following coding scheme. (Note that the name of the callback procedure has brackets () added here, because not only its entry address is needed but the result of its execution.) |
| "CmdProc=%p", CmdProc | option to declare the entry address of the callback procedure handling all WM_COMMAND messages |
| "Status='Right-click or press F2 to get Floating UIF'" | option to declare the standard status text, to be displayed whenever
no other status text needs to be shown (Provides additional user friendliness, so the user never has to feel "left in the dark".) |
Creating a Floating UIF is done as follows (compare Sample34):
HMENU FloatingMenu()
{
HWND hTb1 = CreateSimpleDlg ("Style\bTool Detach ...",
Control (..., "ListBox", DYN_LIST | ..., ...,
"Storeback StorebackProc=%p", StatusProc,
0),
0);
HWND hTb2 = CreateSimpleDlg ("Width\bTool ...",
Control (..., "Slider", DYN_SLIDER | ..., ...,
"StorebackProc=%p", StatusProc,
0),
0);
HMENU hMenu1 = DlgMenu ("CreatePopup",
"Add Id=%d", 1000, "Text='Item A&1 Ctrl+1'"
"Status='Item A1' Shortcut='Ctrl + 1' Tool=%x", hTb1,
"Add Id=%d", 1001, "Text='Item A&2 Alt+2'"
"Status='Item A2' Shortcut='Alt+2' Tool=%x", hTb2,
"Add Id=%d", 1002, "Text='Item A&3 Shift+3'"
"Status='Item A3' Shortcut=Shift+3",
0);
HMENU hMenu2 = DlgMenu ("CreatePopup",
"Add Id=%d", 1100, "Text='Item B&1 Ctrl+Alt+4'"
"Status='Item B1' Shortcut=Ctrl+Alt+4",
"Add Id=%d", 1101, "Text='Item B&2 Ctrl+Shift+5'"
"Status='Item B2' Shortcut=Ctrl+Shift+5",
"Add Id=%d", 1102, "Text='Item B&3 Ctrl+6'"
"Status='Item B3' Shortcut=Ctrl+6",
0);
HMENU hMenu3 = DlgMenu ("CreatePopup",
"Add Id=%d", 1200, "Text='Item C&1 Ctrl+7'"
"Status='Item C1' Shortcut=Ctrl+7",
"Add Id=%d", 1201, "Text='Item C&2 Ctrl+8'"
"Status='Item C2' Shortcut=Ctrl+8",
"Add Id=%d", 1202, "Text='Item C&3 Ctrl+9'"
"Status='Item C3' Shortcut=Ctrl+9",
0);
HMENU hMenu = DlgMenu ("CreatePopup",
"Add Text='Submenu &A' Status='Submenu A' Popup=%x", hMenu1,
"Add Text='Submenu &B' Status='Submenu B' Popup=%x", hMenu2,
"Add Text='Submenu &C' Status='Submenu C' Popup=%x", hMenu3,
0);
return hMenu;
}
|
For details of how to declare a ListBox see
Sample 1.2,
for a Slider see Sample 1.7
All other coding is quite the same as with a popup menu.
| "Tool" | option to have a dialog created as a Toolwindow (extended window style WS_EX_TOOLWINDOW ) |
| "Detach" | option to make a tool detachable (It is created with a caption. The user can drag it there to any place on screen and right-click the caption, thus "docking" it to the main window. When right-clicking the toolbar once more, it is "floating" again.) |
| "Tool=%x", hTb | option to make a Toolwindow being launched when a menu item is clicked. |
Note the additional options to the Controls:
| "Storeback" | By default, a ListBox-selection is stored back to the
calling program when the user double-clicks a list item. By this option, however, it is
enough to click an item only once. (For good software design, you should consider the average type of your users. "Power-users" will appreciate this comfort, casual users might tend to feel "overwhelmed" if an entry becomes effective right away, without being asked for confirmation first.) |
| "StorebackProc=%p", StatusProc | option to declare a callback procedure
StatusProc to be executed when a
storeback is done. (In this example it is simply used to update the Statusbar fields.) |