Window Programming
Window Programming
The entry point for a Windows program is a function named WinMain, but most of the
action takes place in a function known as the window procedure. WinMain creates the
window and then enters a message loop, alternately retrieving messages and dispatching
them to the window procedure. Messages wait in a message queue until they are retrieved.
The message loop ends when a WM_QUIT message is retrieved from the message queue,
signaling that it is time for the application to end. When the message loop ends, WnMain
returns and the application terminates. The window procedure processes messages sent to
the window. The code provided to process a particular message is known as a message
1.1
VJS/Sr. AP/MCA/JCE
handler. Messages that an application doesn't process are passed on to an API function
named DefWindowProc, which provides default responses to unprocessed messages.
The second step is to bind event handlers to events so that the correct function is
called when the event takes place. Graphical editors combine the first two steps: double-
click on a button, and the editor creates an (empty) event handler associated with the user
clicking the button and opens a text window so you can edit the event handler.
The third step in developing an event-driven program is to write the main loop. This
is a function that checks for the occurrence of events, and then calls the matching event
handler to process it. Most event-driven programming environments already provide this
main loop, so it need not be specifically provided by the application programmer.
GUI Concepts
A graphical user interface (GUI), pronounced G-U-I, is a type of user interface
that allows users to interact with programs in more ways than typing. A GUI consists of one
or more windows and each window contains one or more controls. GUIs are "event driven"
which means “react to events” - like a button that is clicked. A GUI offers graphical icons,
and visual indicators to fully represent the information and actions available to a user.
1.2
AU / MCA / R2009 / II Yr / IV Sem / MC9243 / VP / Unit I
The real beauty of Windows lies in its ability to offer the world’s
richest set of Graphical User Interface (GUI) development APIs
(Application Programming Interface). By utilizing the strengths of the GUI
environment, applications can be improved to the point that end user
training and problems are minimized, and a higher level of satisfaction is
obtained by the vast majority of end users.
An Architectural Overview
The various push buttons, radio buttons, check boxes, list boxes, scroll bars, and
text-entry fields that adorn the surfaces of dialog boxes are called “child windows” or
“control windows” or “child window controls”.
The user sees these windows as objects on the screen and interacts directly with
them using the keyboard or the mouse. The window receives the user input in the form of
“messages”. A window also uses messages to communicate with other windows.
The use of a window class allows multiple windows to be based on the same
window class and hence use the same window procedure. For example, all buttons in all
Windows programs are based on the same window class. This window class is associated
with a window procedure located in a Windows dynamic-link library that processes
messages to all the button windows.
In object-oriented programming, an object is a combination of code and data. A
window is an object. The code is the window procedure. A window procedure processes
messages to the window. The data is information retained by the window procedure and
information retained by Windows for each window and window class that exists in the
system.
1.3
VJS/Sr. AP/MCA/JCE
During the compile stage, the compiler generates an .OBJ file from the C source
code file. During the link stage, the linker combines the .OBJ file with .LIB files to create
the .EXE file.
Creating a window first requires registering a window class, and that requires a
window procedure to process messages to the window.
#include <windows.h>
1.4
AU / MCA / R2009 / II Yr / IV Sem / MC9243 / VP / Unit I
WNDCLASS wndclass ;
if (!RegisterClass (&wndclass)) {
MessageBox (NULL, TEXT ("This program requires appropriate OS"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
return msg.wParam ;
}
switch (message) {
case WM_CREATE:
PlaySound (TEXT ("HelloWin.wav"), NULL,
SND_FILENAME|SND_ASYNC) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
1.5
VJS/Sr. AP/MCA/JCE
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
GetStockObject Obtains a graphic object – in this case a brush used for painting the
window’s background.
1.6
AU / MCA / R2009 / II Yr / IV Sem / MC9243 / VP / Unit I
Uppercase Identifiers
Prefix Constant
WPARAM - UINT
LRESULT - LONG
A handle is simply a number (32 bits in size) that refers to an object. A program
obtains a handle by calling a Windows function.
1.7
VJS/Sr. AP/MCA/JCE
#ifdef UNICODE
typedef WNDCLASSW WNDCLASS ;
typedef PWNDCLASSW PWNDCLASS ;
typedef NPWNDCLASSW NPWNDCLASS ;
typedef LPWNDCLASSW LPWNDCLASS ;
#else
1.8
AU / MCA / R2009 / II Yr / IV Sem / MC9243 / VP / Unit I
WNDCLASS wndclass ;
typedef struct {
UINT style ;
WNDPROC lpfnWndProc ;
int cbClsExtra ;
int cbWndExtra ;
HINSTANCE hInstance ;
HICON hIcon ;
HCURSOR hCursor ;
HBRUSH hbrBackground ;
LPCTSTR lpszMenuName ;
LPCTSTR lpszClassName ;
}
WNDCLASS, *PWNDCLASS;
1. Combines two 32-bit “class style” identifiers with a “|” symbol. The
WINUSER.H defines these identifiers
Identifiers defined in this way are called “bit flags” because each identifier sets a
single bit in a composite value.
1.9
VJS/Sr. AP/MCA/JCE
2. The address of a window procedure used for all windows based on this class.
3. Used to reserve some extra space in the class structure that Windows maintains
internally.
4. Used to reserve some extra space in the window structure that Windows
maintains internally.
6. Sets an icon for all windows created based on this window class. The icon is a
small bitmap picture that represents the program to the user. To obtain a handle
to a predefined icon, call LoadIcon with the first argument set to NULL. While
loading a customized icons that are stored in the program’s .exe file on disk, this
argument would be set to hInstance, the instance handle of the program. The
second argument identifies the icon. For the predefined icons, this argument is
an identifier beginning with the prefix IDI defined in WINUSER.H. The
LoadIcon function returns a handle to this icon.
8. Specifies the background color of the client area of windows created based on
this class. A brush is a graphics term that refers to a colored pattern of pixels
used to fill an area.
10. The text name of the window class. This may be whatever the user wants. In
programs that create only one window, the window class name is commonly set
to the name of the program.
The client area is the part of the window on which a program is free to draw and
deliver visual information to the user. Displaying text or graphics in the client area is said
to be painting the client area.
This message informs the window procedure that the client area must be painted. A
window procedure receives a WM_PAINT message whenever one of the following events
occurs:
1.10
AU / MCA / R2009 / II Yr / IV Sem / MC9243 / VP / Unit I
• A previously hidden area of the window is brought into view when a user moves a
window or uncovers a window.
• The program uses the ScrollWindow or ScrollDC function to scroll part of its client
area.
In some cases when part of the client area is temporarily written over, Windows
attempts to save the area of display and restore it later. This is not always successful.
Windows may sometimes post a WM_PAINT message when:
• Windows removes a dialog box or message box that was overlaying part of the
window.
In a few cases, Windows always saves the area of the display it overwrites and then
restores it. This is the case whenever:
Although a window procedure should be prepared to update the entire client area
whenever it receives a WM_PAINT message, it often needs to update only a small area,
most often a rectangular area within the client area. This area is known as an “invalid
region” or “update region”.
A window procedure can invalidate a rectangle in its own client area by calling
InvalidateRect. If the message queue already contains a WM_PAINT message, Windows
calculates a new invalid rectangle. Otherwise, it places a WM_PAINT message in the
message queue. A window procedure can obtain the coordinates of the invalid rectangle
1.11
VJS/Sr. AP/MCA/JCE
when it receives a WM_PAINT message. It can also obtain these coordinates at any other
time by calling GetUpdateRect.
After the window procedure calls BeginPaint during the WM_PAINT message, the
entire client area is validated. A program can also validate any rectangular area within the
client area by calling the ValidateRect function. If this call has the effect of validating the
entire invalid area, then any WM_PAINT message currently in the queue is removed.
An Introduction To GDI
To paint the client area of the window, use Window’s Graphics Device Interface
(GDI) functions.
A handle, is a number that Windows uses for internal reference to an object. The
handle is obtained from Windows.
The device context (DC) is a data structure maintained internally by GDI. A device
context is associated with a particular display device.
When a program needs to paint, it must first obtain a handle to a device context.
When the handle is obtained, Windows fills the internal device context structure with
default attribute values. These defaults can be changed by calling various GDI functions.
After a program has finished painting its client area, it should release the device context
handle.
This method is used when the WM_PAINT messages are processed. Two functions
are involved: BeginPaint and EndPaint. These two functions require the handle to the
window, which is passed to the window procedure as an argument, and the address of the
structure variable of type PAINTSTRUCT, which is defined in the WINUSER.H header
file. Windows programmers usually name this structure variable ps and define it within the
window procedure like: PAINTSTRUCT ps ;
To get a handle to the device context of the client area of the window, call GetDC to
obtain the handle and ReleaseDC after done with it.
Like BeginPaint and EndPaint, the GetDC and ReleaseDC functions should be
called in pairs. Unlike the device context handle returned from BeginPaint, the device
context handle returned from GetDC has a clipping rectangle equal to the entire client area.
1.12
AU / MCA / R2009 / II Yr / IV Sem / MC9243 / VP / Unit I
Unlike BeginPaint, GetDC does not validate any invalid regions. To validate the entire
client area, call
TextOut
TextOut is the most common GDI function for displaying text. Its syntax is
The attributes of the device context, control the characteristics of the displayed text.
For instance, the default text color is black and text background color is white. When a
program writes text to the display, Windows uses this background color to fill in the
rectangular space surrounding each character, called the “character box”.
The system font is a “raster font”, which means that the characters are defined as
blocks of pixels. The size of the characters in the system font is based on the size of the
video display. The system font is designed to allow at least 25 lines of 80 character text to
fit on the screen.
A program can determine information about the sizes (or metrics) of user interface
items by calling the GetSystemMetrics function.
Windows copies the various values of text metrics into a structure of type
TEXTMETRIC defined in WINGDI.H. The TEXTMETRIC structure has 20 fields, but
knowing about only the first seven is necessary.
1.13
VJS/Sr. AP/MCA/JCE
TEXTMETRIC, * PTEXTMETRIC ;
TEXTMETRIC tm ;
When there is a need to determine the text metrics, get a handle to a device context and call
GetTextMetrics:
hdc = GetDC (hwnd) ;
GetTextMetrics (hdc, &tm) ;
ReleaseDC (hwnd, hdc) ;
The TEXTMETRIC structure provides various types of information about the font
currently selected in the device context.
tmHeight – The sum of tmAscent and tmDescent. These two values represent the
maximum vertical extends of characters in the font above and below
the baseline.
tmInternalLeading - Specifies the amount of leading (space) inside the bounds set by the
tmHeight. Accent marks and other diacritical characters may occur in
this area. The designer may set this member to zero.
tmExternalLeading – This is an amount of space that the designer of the font suggests be
added between successive rows of displayed text.
tmAveCharWidth - Specifies the average width of characters in the font. This value does
not include the overhang required for bold or italic characters.
Scroll Bars
Scroll bars are needed to display anything that requires more space than the space
available in the window’s client area. Scroll bars are positioned either vertically (for up and
down movement) or horizontally (for left and right movement). User can click with the
mouse the arrows at each end of a scroll bar or the area between the arrows. A “scroll box”
(or “thumb”) travels the length of the scroll bar to indicate the approximate location of the
material shown on the display in relation to the entire document. The thumb can also be
dragged with the mouse to move to a particular location.
1.14
AU / MCA / R2009 / II Yr / IV Sem / MC9243 / VP / Unit I
The scroll bars specified in the CreateWindow function are always placed against the right
side or bottom of the window and extend the full length or width of the client area. The
client area does not include the space occupied by the scroll bars. The width of the vertical
scroll bar and the height of the horizontal scroll bar are constant for a particular video driver
and display resolution.
Windows takes care of processing all mouse messages to the scroll bars. However,
scroll bars do not have an automatic keyboard interface.
Every scroll bar has an associated “range” and “position”. The scroll bar range is a
pair of integers representing a minimum or maximum value associated with the scroll bar.
The position is the location of the thumb with the range. When the thumb is at the top (or
left) of the scroll bar, the position of the thumb is the minimum value of the range and at the
bottom (or right) of the scroll bar, the thumb position is the maximum value of the range.
By default, the range of a scroll bar is 0 (top or left) through 100 (bottom or right).
To change the range
iPos - the new position and must be within the range of iMin and iMax
To obtain the current range and position of a scroll bar
- GetScrollRange
- GetScrollPos
When the scroll bars are used within the program, responsibilities are shared with
Windows for the maintaining the scroll bars and updating the position of the scroll bar
thumb.
Windows’ responsibilities:
- Handle all processing of mouse messages to the scroll bar.
- Provide a reverse-video when the user clicks the scroll bar.
- Move the thumb as the user drags the thumb within the scroll bar.
- Send scroll bar messages to the window procedure of the window containing the
scroll bar.
1.15
VJS/Sr. AP/MCA/JCE
The wParam message parameter is divided into a low word and high word. The low
word of the wParam is a number that indicates what the mouse is doing to the scroll bar.
This number is referred to as a “notification code”. Notification codes have values defined
by identifiers that begin with SB, which stands for “scroll bar”. The notification codes are:
SB_LINEUP 0
SB_LINELEFT 0
SB_LINEDOWN 1
SB_LINERIGHT 1
SB_PAGEUP 2
SB_PAGELEFT 2
SB_PAGEDOWN 3
SB_PAGERIGHT 3
SB_THUMBPOSITION 4
SB_THUMBTRACK 5
SB_TOP 6
SB_LEFT 6
SB_BOTTOM 7
SB_RIGHT 7
SB_ENDSCROLL 8
The identifiers containing the words LEFT and RIGHT are used for horizontal scroll bars,
and the identifiers with UP, DOWN, TOP and BOTTOM with vertical scroll bars.
When the mouse button is held down on the various parts of the scroll bar (except
thumb) the program can receive multiple scroll bar messages. When the mouse button is
released, the program gets a message with a notification code of SB_ENDSCROLL; these
messages are generally ignored.
When the position of the mouse cursor is over the scroll bar thumb and the mouse
button is pressed, the thumb can be moved. This generates scroll bar messages with
notification codes of SB_THUMBTRACK and SB_THUMBPOSITION. When the low
word of wParam is SB_THUMBTRACK, the high word of wParam is the current position
of the scroll bar thumb as the user is dragging it. When the low word of wParam is
1.16
AU / MCA / R2009 / II Yr / IV Sem / MC9243 / VP / Unit I
SB_THUMBPOSITION, the high word of wParam is the final position of the scroll bar
thumb when the user releases the mouse button.
The Keyboard
Keyboard Basics
As the user presses and releases keys on the keyboard, Windows and the keyboard
device driver translate the hardware scan codes into formatted messages. These messages
are not placed in an application’s message queue. Instead, Windows stores these messages
in the system message queue. The system message queue is a single message queue
maintained by Windows specifically for the preliminary storage of user input from the
keyboard and the mouse. Windows will take the next message from the system message
queue and place it in an application’s message queue only when a Windows application has
finished processing a previous user input message.
The reason for this is that the window that is supposed to receive keyboard input is
the window with the input focus. A user can be typing faster than an application can handle
the keystrokes, and a particular keystroke might have the effect of switching focus from one
window to another. Subsequent keystrokes should then go to another window. But they
won’t if the subsequent keystrokes have already been addressed with a destination window
and placed in an application message queue.
When text is typed into a program, a little underline, vertical bar, or a box shows
where the next character to be typed will appear on the screen. This may be known as a
“cursor”. In Windows, it is called the “caret”. The word “cursor” is reserved for the little
bitmap image that represents the mouse position.
1.17
VJS/Sr. AP/MCA/JCE
In Windows, the caret is customarily a horizontal line or box that is the size of a
character, or a vertical line that is the height of a character. The vertical line caret is
recommended to be used with proportional font in which the characters are not of a fixed
size.
Using the caret is simple: in window procedure call CreateCaret during the
WM_SETFOCUS message and call DestroyCaret during the WM_KILLFOCUS message.
The caret is created hidden. After calling CreateCaret the window procedure must call
ShowCaret for the caret to be visible. In addition, the window procedure must hide the
caret by calling HideCaret whenever it draws something on its window during a message
other than WM_PAINT. After it finishes drawing on the window, the program must call
ShowCaret to display it.
WM_KEYDOWN Message
Posted to the window with the keyboard focus when a nonsystem key is pressed. A
nonsystem key is a key that is pressed when the ALT key is not pressed.
wParam
lParam
Other parameters
WM_CHAR Message
Posted to the window with the keyboard focus when a WM_KEYDOWN message is
translated by the TranslateMessage function. The WM_CHAR message contains the
character code of the key that was pressed.
1.18
AU / MCA / R2009 / II Yr / IV Sem / MC9243 / VP / Unit I
SendMessage Function
Sends the specified message to a window or windows. The SendMessage function calls the
window procedure for the specified window and does not return until the window procedure
has processed the message.
switch (message)
{
case WM_CREATE:
ReleaseDC(hwnd, hdc);
return 0;
case WM_SIZE:
// Determine the width of the client area, in pixels and in number of characters.
cxClient = LOWORD(lParam);
cxClientChar = max(1, cxClient/cxChar);
// Determine the height of the client area, in pixels and in number of characters
1.19
VJS/Sr. AP/MCA/JCE
cyClient = HIWORD(lParam);
cyClientChar = max(1, cyClient/cyChar);
if (pTextMatrix != NULL)
free(pTextMatrix);
// If there is enough memory, allocate space for the text input buffer.
if (pTextMatrix == NULL) {
MessageBox(NULL,TEXT("Not enough memory."),TEXT("Error"),
MB_ICONERROR);
return 0;
}
else
for (y = 0; y < cyClientChar; y++)
for (x = 0; x < cxClientChar; x++)
TEXTMATRIX(x, y) = ' ';
SetCaretPos(0, 0);
return 0;
case WM_KEYDOWN:
switch (wParam)
{
case VK_HOME: // Home
caretX = 0;
break;
1.20
AU / MCA / R2009 / II Yr / IV Sem / MC9243 / VP / Unit I
HideCaret(hwnd);
hdc = GetDC(hwnd);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
ReleaseDC(hwnd, hdc);
ShowCaret(hwnd);
break;
}
1.21
VJS/Sr. AP/MCA/JCE
// virtual-key processing.
return 0;
case WM_CHAR:
switch (wParam)
{
case 0x08: // Backspace
// Move the caret back one space, and then
// process this like the DEL key.
if (caretX > 0)
{
caretX--;
SendMessage(hwnd, WM_KEYDOWN, VK_DELETE, 1L);
}
break;
do
{
SendMessage(hwnd, WM_CHAR, ' ', 1L);
} while (caretX % 4 != 0);
break;
caretX = 0;
if (++caretY == cyClientChar)
caretY = 0;
break;
default:
// Add the character to the text buffer.
1.22
AU / MCA / R2009 / II Yr / IV Sem / MC9243 / VP / Unit I
HideCaret(hwnd);
hdc = GetDC(hwnd);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
ReleaseDC(hwnd, hdc);
ShowCaret(hwnd);
if (++caretX == cxClientChar)
{
caretX = 0;
if (++caretY == cyClientChar)
caretY = 0;
}
break;
}
return 0;
case WM_PAINT:
// Draw all the characters in the buffer, line by line.
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
1.23
VJS/Sr. AP/MCA/JCE
EndPaint(hwnd, &ps);
case WM_SETFOCUS:
ShowCaret(hwnd);
break;
case WM_KILLFOCUS:
// The window is losing the input focus,
// so destroy the caret.
DestroyCaret();
break;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
The Mouse
The mouse is a pointing device.
1.24
AU / MCA / R2009 / II Yr / IV Sem / MC9243 / VP / Unit I
When the user moves the mouse, Windows moves a small bitmapped picture on the
display. This is called the “mouse cursor”. The mouse cursor has a single-pixel “hot spot”
that points to a precise location on the display.
Windows supports several predefined mouse cursors that programs can use.
IDC_ARROW- slanted arrow. The hot spot is the tip of the arrow.
IDC_CROSS - cross. The hot spot is the center of the crosshair pattern.
IDC_WAIT - hourglass. Used by programs to indicate they are busy.
Programmers can also design their own cursors. The default cursor for a particular window
is specified when defining the window class structure.
The buttons on a mouse are called the left button, the middle button, and the right
button. The identifiers defined in the Windows header files related to these buttons are
LBUTTON, MBUTTON, and RBUTTON respectively.
Windows sends keyboard messages only to the window that has the input focus.
But a window procedure receives mouse messages whenever the mouse passes over the
window or is clicked within the window, even if the window is not active or does not have
the input focus.
Windows defines 21 messages for the mouse. 11 of these messages do not relate to
the client area. These are called “nonclient-area messages”.
When the mouse is moved over the client area of a window, the window procedure
receives the message WM_MOUSEMOVE. When a mouse button is pressed or released
within the client area of a window, the window procedure receives the following messages:
1.25
VJS/Sr. AP/MCA/JCE
For all these messages, the value of lParam contains the position of the mouse. The
low word is the x-coordinate, and the high word is the y-coordinate relative to the upper left
corner of the client area of the window. These values can be extracted using the LOWORD
and HIWORD macros:
x = LOWORD (lParam) ;
y = HIWORD (lParam) ;
The value of wParam indicates the state of the mouse buttons and the Shift and Ctrl
keys. The MK prefix stands for “mouse key”.
switch (message)
{
case WM_LBUTTONDOWN:
iCount = 0 ;
InvalidateRect (hwnd, NULL, TRUE) ;
return 0 ;
case WM_MOUSEMOVE:
if (wParam & MK_LBUTTON && iCount < MAXPOINTS)
{
pt[iCount].x = LOWORD (lParam) ;
pt[iCount++].y = HIWORD (lParam) ;
1.26
AU / MCA / R2009 / II Yr / IV Sem / MC9243 / VP / Unit I
}
return 0 ;
case WM_LBUTTONUP:
InvalidateRect (hwnd, NULL, FALSE) ;
return 0 ;
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
for (i=0; i<iCount-1; i++) {
for (j=i+1; j<iCount; j++) {
MoveToEx (hdc, pt[i].x, pt[i].y, NULL) ;
LineTo (hdc, pt[j].x, pt[j].y) ;
}
}
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
To know the status of the mouse buttons or shift key or control key call the function
GetKeyState using virtual key codes VK_LBUTTON, VK_MBUTTON, VK_RBUTTON,
VK_SHIFT and VK_CONTROL. The button or key is down if the value returned from
GetKeyState is negative.
Moue Double-Clicks
1.27
VJS/Sr. AP/MCA/JCE
If the mouse is outside a window’s client area but within the window, Windows
sends the window procedure a “nonclient-area” mouse message. The nonclient area of a
window includes the title bar, the menu, and the window scroll bars.
The nonclient-area mouse messages are almost like the client-area mouse messages.
The message identifiers include the letters “NC” to indicate “nonclient”. For example, if
the mouse is moved within a nonclient area of a window, the window procedure receives
the message WM_NCMOUSEMOVE. The mouse buttons generate messages similar to
this.
The wParam parameter indicates the nonclient area where the mouse was moved or
clicked. It is set to one of the identifiers beginning with HT (standing for “hit-test”).
The lParam parameter contains an x-coordinate in the low word and a y-coordinate
in the high word. These are screen coordinates. For screen coordinates, the upper-left
corner of the display area has x and y values of 0. Values of x increase towards the right
and values of y increase towards down.
The last message is WM_NCHITTEST, which stands for “nonclient hit test”. This
message precedes all other client-area and nonclient-are mouse messages. The lParam
parameter contains the x and y screen coordinates of the mouse position. The wParam
parameter is not used. Windows applications generally pass this message to
DefWindowProc.
Note:
1.28
AU / MCA / R2009 / II Yr / IV Sem / MC9243 / VP / Unit I
ShowCursor (FALSE) ;
int x = cursorPos.x ;
int y = cursorPos.y ;
Menus
A menu is a list of available options. A menu tells the user what operations an
application is capable of performing.
A menu is the most important part of the user interface in Windows programs. For
adding a menu to the program: define the menu and specify the name of the menu in the
window class structure. Each selectable menu item is given a unique ID number. When the
user chooses a menu item, Windows sends the program a WM_COMMAND message
containing that ID.
Keyboard accelerators are key combinations that are used to duplicate menu
functions.
Menu Concepts
A window’s menu bar is displayed immediately below the caption bar. This menu
bar is also called a program’s “main menu” or the “top-level menu”. Items listed in the top-
level menu usually invoke drop-down menus, which are also called “popup menus” or
“submenus”. Multiple nesting of popup can be defined. Sometimes items in popup menus
invoke a dialog box for more information.
1.29