In its simplest form, message-driven programming (also known as event-driven programming) is a process by which various subprocesses and/or applications communicate. In Windows, messages are the process used by Windows itself to manage a multitasking system and to share keyboard, mouse, and other resources by distributing information to applications, application instances, and processes within an application.
Thus, under Windows, instead of applications receiving information directly from the keyboard or the mouse driver, the operating system intercepts all input information, packaging this information using the MSG message structure (detailed in the following section) and then forwarding the prepared messages to the appropriate recipients. In turn, the recipient applications use TranslateMessage for application-specific interpretation (particularly accelerator-key assignments) before calling DispatchMessage to forward individual traffic items to their appropriate handlers.
Furthermore, the process described is not limited to keyboard and mouse events. Instead, this includes all input devices (including ports), as well as messages generated by application child and subprocesses, Windows timers, or, quite frequently, by Windows itself.
NOTE
Abstract descriptions of message-driven programming provide only a theoretical outline without really illustrating how these processes function. Therefore, a fuller explanation will be left until subsequent examples in this book can provide both hands-on experience as well as practical illustrations (beginning, of course, with messages processed by the WinHello demo).
But before we get to how messages are transmitted, let’s take a look at the message record structure and how messages are organized.
The MSG (message structure) record type is defined in WinUser.H as:
typedef struct tagMSG
{ HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt; } MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
NOTE
Both the NEAR and FAR types are essentially obsolete in 32-bit systems. Originally, NEAR meant an address within a 16KB block, and FAR indicated an address outside the “local” 16KB address space. Today, all addresses are NEAR without requiring the specification, and specifying FAR is obsolete. However, there are no penalties or conflicts arising for continuing to use FAR, and this term does continue to appear in many structure and function definitions, as in the MSG definition shown here.
The POINT data type is defined in WinDef.H as:
typedef struct tagPOINT
{ int x;
int y; } POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;
The message-event fields defined are used as:
Note that these last two fields, time and pt, are not passed to the WndProc procedure. Instead, these two fields are used only by Windows, principally to resolve any conflict over the order of events and, of course, to determine where a specific event should be addressed.
NOTE
Each application is itself composed of a series of separate windows. These windows include the frame, the caption bar, the system menu, and minimize and maximize buttons, as well as the application’s main display, which is referred to as the client window or, occasionally, the display window. Normally, only messages directed to the client window will be forwarded by the DispatchMessage procedure to the application’s WndProc procedure. Messages directed to other application windows are generally handled indirectly (by Windows 98), even though this may result, in turn, in further messages being sent to the client window.