









Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
An in-depth exploration of menus and dialogs in windows programming. It covers menu structures, menu item identification, menu states, and the use of separators. Additionally, it discusses the system menu, time differences, and time information in windows. The document concludes with an explanation of dialog boxes, their types, and the creation of modal dialogs.
Typology: Study notes
1 / 16
This page cannot be seen from the preview
Don't miss anything!










We have discussed Menus in our previous lecture, here we will know more about menus and their use in Windows Applications.
When the user chooses a command item, the system sends a command message to the window that owns the menu. If the command item is on the window menu, the system sends the WM_SYSCOMMAND message. Otherwise, it sends the WM_COMMAND message.
Handle is associated with each menu item that opens a submenu. When the user points to such an item, the system opens the submenu. No command message is sent to the owner window. However, the system sends a WM_INITMENUPOPUP message to the owner window before displaying the submenu. You can get a handle to the submenu associated with an item by using the GetSubMenu or GetMenuItemInfo function.
A menu bar typically contains menu names, but it can also contain command items. A submenu typically contains command items, but it can also contain items that open nested submenus. By adding such items to submenus, you can nest menus to any depth. To provide a visual cue for the user, the system automatically displays a small arrow to the right of the text of a menu item that opens a submenu.
Associated with each menu item is a unique, application-defined integer, called a menu- item identifier. When the user chooses a command item from a menu, the system sends the item's identifier to the owner window as part of a WM_COMMAND message. The window procedure examines the identifier to determine the source of the message, and processes the message accordingly. In addition, you can specify a menu item using its identifier when you call menu functions; for example, to enable or disable a menu item.
Menu items that open submenus have identifiers just as command items do. However, the system does not send a command message when such an item is selected from a menu. Instead, the system opens the submenu associated with the menu item.
To retrieve the identifier of the menu item at a specified position, use the GetMenuItemID or GetMenuItemInfo function.
GetMenuState function to determine whether a menu item is currently selected or cleared.
Instead of CheckMenuItem and GetMenuState , you can use the GetMenuItemInfo and SetMenuItemInfo functions to retrieve and set the check state of a menu item.
Sometimes, a group of menu items corresponds to a set of mutually exclusive options. In this case, you can indicate the selected option by using a selected radio menu item (analogous to a radio button control). Selected radio items are displayed with a bullet bitmap instead of a check mark bitmap. To check a menu item and make it a radio item, use the CheckMenuRadioItem function.
By default, the system displays a check mark or bullet bitmap next to selected menu items and no bitmap next to cleared menu items. However, you can use the SetMenuItemBitmaps function to associate application-defined selected and cleared bitmaps with a menu item. The system then uses the specified bitmaps to indicate the menu item's selected or cleared state.
Application-defined bitmaps associated with a menu item must be the same size as the default check mark bitmap, the dimensions of which may vary depending on screen resolution. To retrieve the correct dimensions, use the GetSystemMetrics function. You can create multiple bitmap resources for different screen resolutions; create one bitmap resource and scale it, if necessary; or create a bitmap at run time and draw an image in it. The bitmaps may be either monochrome or color. However, because menu items are inverted when highlighted, the appearance of certain inverted color bitmaps may be undesirable. For more information, see Bitmaps.
A menu item can be enabled, grayed, or disabled. By default, a menu item is enabled. When the user chooses an enabled menu item, the system sends a command message to the owner window or displays the corresponding submenu, depending on what kind of menu item it is.
When menu items are not available to the user, they should be grayed or disabled. Grayed and disabled menu items cannot be chosen. A disabled item looks just like an enabled item. When the user clicks on a disabled item, the item is not selected, and nothing happens. Disabled items can be useful in, for example, a tutorial that presents a menu that looks active but isn't.
An application grays an unavailable menu item to provide a visual cue to the user that a command is not available. You can use a grayed item when an action is not appropriate (for example, you can gray the Print command in the File menu when the system does not have a printer installed).
The EnableMenuItem function enables, grays, or disables a menu item. To determine whether a menu item is enabled, grayed, or disabled, use the GetMenuItemInfo function.
Instead of GetMenuItemInfo , you can also use the GetMenuState function to determine whether a menu item is enabled, grayed, or disabled.
The system automatically highlights menu items on menus as the user selects them. However, highlighting can be explicitly added or removed from a menu name on the menu bar by using the HiliteMenuItem function. This function has no effect on menu items on menus. When HiliteMenuItem is used to highlight a menu name, though, the name only appears to be selected. If the user presses the ENTER key, the highlighted item is not chosen. This feature might be useful in, for example, a training application that demonstrates the use of menus.
An application can completely control the appearance of a menu item by using an owner- drawn item. Owner-drawn items require an application to take total responsibility for drawing selected (highlighted), selected, and cleared states. For example, if an application provided a font menu, it could draw each menu item by using the corresponding font; the item for Roman would be drawn with roman, the item for Italic would be drawn in italic, and so on. For more information, see Creating Owner-Drawn Menu Items.
The system provides a special type of menu item, called a separator , which appears as a horizontal line. You can use a separator to divide a menu into groups of related items. A separator cannot be used in a menu bar, and the user cannot select a separator.
When a menu bar contains more menu names than will fit on one line, the system wraps the menu bar by automatically breaking it into two or more lines. You can cause a line break to occur at a specific item on a menu bar by assigning the MFT_MENUBREAK type flag to the item. The system places that item and all subsequent items on a new line.
When a menu contains more items than will fit in one column, the menu will be truncated. You can cause a column break to occur at a specific item in a menu by assigning the MFT_MENUBREAK type flag to the item or using the MENUBREAK option in the MENUITEM statement. The system places that item and all subsequent items in a new column. The MFT_MENUBARBREAK type flag has the same effect, except that a vertical line appears between the new column and the old.
wParam Indicates whether various virtual keys are down. This parameter can be one or more of the following values. MK_CONTROL: The CTRL key is down. MK_LBUTTON: The left mouse button is down. MK_MBUTTON: The middle mouse button is down. MK_RBUTTON: The right mouse button is down. MK_SHIFT: The SHIFT key is down. MK_XBUTTON lParam The low-order word specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area. The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.
Return Value:
If an application processes this message, it should return zero
POINT structure contains LONG (long)x and LONG y.
typedef struct tagPOINT { LONG x; //horizontal number LONG y; //vertical number } POINT;
POINTS structure contains SHORT (short) x, and SHORT y
typedef struct tagPOINTS { SHORT x; //horizontal short integer SHORT y; //vertical short integer } POINTS;
POINTS pts; POINT pt; … … … … case WM_RBUTTONDOWN:
pts = MAKEPOINTS(lParam); pt.x = pts.x; pt.y = pts.y;
ClientToScreen(hWnd, &pt); //convert the window coordinates to the screen coordinates
result = TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON, pt.x, pt.y, 0, hWnd, 0 );
The SetMenuInfo function sets information for a specified menu.
BOOL SetMenuInfo(
HMENU hmenu , //handle to the menu LPCMENUINFO lpcmi //menu informations );
hmenu: Handle to a menu.
lpcmi: Pointer to a MENUINFO structure for the menu.
Return Value:
If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError.
SC_SIZE Size SC_CLOSE Close
There are two time differences are available in windows one is
Local Time - And UTC (Universal Coordinated Time) historically GMT (Greenwich Mean Time)
VOID GetSystemTime( LPSYSTEMTIME lpSystemTime // system time );
This function retrieves the system time in UTC format.
VOID GetLocalTime( LPSYSTEMTIME lpSystemTime // system time );
This function retrieves the current local date and time.
IDR_FIRST_MENU MENU DISCARDABLE BEGIN POPUP "&File" BEGIN MENUITEM "E&xit", ID_FILE_EXIT n END POPUP "F&ormat" BEGIN MENUITEM "&UTC", ID_FORMAT_UTC MENUITEM "&Local Time", ID_FORMAT_LOCALTIME END END
static SYSTEMTIME st; enum Format { UTC, LOCAL }; static enum Format format;
case WM_CREATE: SetTimer(hWnd, ID_TIMER, 1000, NULL);
format=LOCAL; GetLocalTime(&st); hOurMenu = GetMenu(hWnd); CheckMenuItem(hOurMenu, ID_FORMAT_LOCALTIME, MF_BYCOMMAND | MF_CHECKED); Break;
case WM_COMMAND: switch(LOWORD(wParam)) { case ID_FORMAT_UTC: if(format == UTC) break; format = UTC; hOurMenu = GetMenu(hWnd); result = CheckMenuItem(hOurMenu, ID_FORMAT_UTC, MF_BYCOMMAND | MF_CHECKED); result = CheckMenuItem(hOurMenu, ID_FORMAT_LOCALTIME, MF_BYCOMMAND | MF_UNCHECKED); DrawMenuBar(hWnd); (format == UTC)? GetSystemTime(&st) : GetLocalTime(&st); GetClientRect(hWnd, &rect); InvalidateRect(hWnd, &rect, TRUE); break;
case WM_PAINT: hDC = BeginPaint(hWnd, &ps); wsprintf(msg, "Hour: %2d:%02d:%02d", st.wHour, st.wMinute, st.wSecond); TextOut(hDC, 10, 10, msg, lstrlen(msg)); EndPaint(hWnd, &ps); break;
case WM_TIMER: if(wParam == ID_TIMER) { (format == UTC)? GetSystemTime(&st) : GetLocalTime(&st); GetClientRect(hWnd, &rect); InvalidateRect(hWnd, &rect, TRUE); break; } break;
When the owner window is not already disabled, the system automatically disables the window and any child windows belonging to it when it creates the modal dialog box. The owner window remains disabled until the dialog box is destroyed. Although a dialog box procedure could potentially enable the owner window at any time, enabling the owner defeats the purpose of the modal dialog box and is not recommended. When the dialog box procedure is destroyed, the system enables the owner window again, but only if the modal dialog box caused the owner to be disabled.
As the system creates the modal dialog box, it sends the WM_CANCELMODE message to the window (if any) currently capturing mouse input. An application that receives this message should release the mouse capture so that the user can move the mouse in the modal dialog box. Because the system disables the owner window, all mouse input is lost if the owner fails to release the mouse upon receiving this message.
To process messages for the modal dialog box, the system starts its own message loop, taking temporary control of the message queue for the entire application. When the system retrieves a message that is not explicitly for the dialog box, it dispatches the message to the appropriate window. If it retrieves a WM_QUIT message, it posts the message back to the application message queue so that the application's main message loop can eventually retrieve the message.
The system sends the WM_ENTERIDLE message to the owner window whenever the application message queue is empty. The application can use this message to carry out a background task while the dialog box remains on the screen. When an application uses the message in this way, the application must frequently yield control (for example, by using the PeekMessage function) so that the modal dialog box can receive any user input. To prevent the modal dialog box from sending the WM_ENTERIDLE messages, the application can specify the DS_NOIDLEMSG style when creating the dialog box.
An application destroys a modal dialog box by using the EndDialog function. In most cases, the dialog box procedure calls EndDialog when the user clicks Close from the dialog box's window menu or clicks the OK or Cancel button in the dialog box. The dialog box can return a value through the DialogBox function (or other creation functions) by specifying a value when calling the EndDialog function. The system returns this value after destroying the dialog box. Most applications use this return value to determine whether the dialog box completed its task successfully or was canceled by the user. The system does not return control from the function that creates the dialog box until the dialog box procedure has called the EndDialog function.
A modeless dialog box should be a pop-up window having a window menu, a title bar, and a thin border; that is, the dialog box template should specify the WS_POPUP, WS_CAPTION, WS_BORDER, and WS_SYSMENU styles. The system does not automatically display the dialog box unless the template specifies the WS_VISIBLE style.
An application creates a modeless dialog box by using the CreateDialog or CreateDialogIndirect function. CreateDialog requires the name or identifier of a resource containing a dialog box template; CreateDialogIndirect requires a handle to a memory object containing a dialog box template. Two other functions, CreateDialogParam and CreateDialogIndirectParam, also create modeless dialog boxes; they pass a specified parameter to the dialog box procedure when the dialog box is created.
CreateDialog and other creation functions return a window handle for the dialog box. The application and the dialog box procedure can use this handle to manage the dialog box. For example, if WS_VISIBLE is not specified in the dialog box template, the application can display the dialog box by passing the window handle to the ShowWindow function.
A modeless dialog box neither disables the owner window nor sends messages to it. When creating the dialog box, the system makes it the active window, but the user or the application can change the active window at any time. If the dialog box does become inactive, it remains above the owner window in the Z order, even if the owner window is active.
The application is responsible for retrieving and dispatching input messages to the dialog box. Most applications use the main message loop for this. To permit the user to move to and select controls by using the keyboard, however, the application must call the IsDialogMessage function. For more information about this function, see Dialog Box Keyboard Interface.
A modeless dialog box cannot return a value to the application as a modal dialog box does, but the dialog box procedure can send information to the owner window by using the SendMessage function.
An application must destroy all modeless dialog boxes before terminating. It can destroy a modeless dialog box by using the DestroyWindow function. In most cases, the dialog box procedure calls DestroyWindow in response to user input, such as clicking the Cancel button. If the user never closes the dialog box in this way, the application must call DestroyWindow.
DestroyWindow invalidates the window handle for the dialog box, so any subsequent calls to functions that use the handle return error values. To prevent errors, the dialog box procedure should notify the owner that the dialog box has been destroyed. Many applications maintain a global variable containing the handle for the dialog box. When the dialog box procedure destroys the dialog box, it also sets the global variable to NULL, indicating that the dialog box is no longer valid.
The dialog box procedure must not call the EndDialog function to destroy a modeless dialog box.
Modal Dialog runs the dialog modal loop. And handle all the messages in message queue.
INT_PTR DialogBox( HINSTANCE hInstance, // handle to module LPCTSTR lpTemplate, // dialog box template HWND hWndParent, // handle to owner window DLGPROC lpDialogFunc // dialog box procedure );
In this lecture, we studied about menus and dialogs. Dialogs are another useful and multipurpose resource in windows. Dialogs are used to display temporary information and other data. Dialogs are of two types: One is modal dialogs and second is modeless dialogs. Modal dialogs do not return control to the application until they are not ended or destroyed. Modeless dialogs act like a normal windows they return control after they have created. Message boxes are normally modal dialog boxes.