The Windows Programming Model ----- Messages

zhaozj2021-02-17  58

Messages, Messages, And More Messages

Where do messages come from, and what kinds of information do they convey? Windows defines hundreds of different message types. Most messages have names that begin with the letters "WM" and an underscore, as in WM_CREATE and WM_PAINT. These messages can be classified in various ways, but for the moment classification is not nearly as important as realizing the critical role messages play in the operation of an application. The following table shows 10 of the most common messages. A window receives a WM_PAINT message, for example, when its interior needs repainting. One way to characterize a Windows program is to think of it as a collection of message handlers. to a large extent, it is a program's unique way of responding to messages that gives it its personality.

Common Windows Messages

MessageSent WhenWM_CHARA character is input from the keyboard.WM_COMMANDThe user selects an item from a menu, or a control sends a notification to its parent.WM_CREATEA window is created.WM_DESTROYA window is destroyed.WM_LBUTTONDOWNThe left mouse button is pressed.WM_LBUTTONUPThe left mouse button is Released.wm_mousemove the mouse pointer is moved.wm_painta window needs repainting.wm_quitthe application is about to terminate.wm_sizea window is resize.

A message manifests itself in the form of a call to a window's window procedure Bundled with the call are four input parameters:. The handle of the window to which the message is directed, a message ID, and two 32-bit parameters known as wParam and lParam. The window handle is a 32-bit value that uniquely identifies a window. Internally, the value references a data structure in which Windows stores relevant information about the window such as its size, style, and location on the screen. The message ID is a numeric value that identifies the message type:.. WM_CREATE, WM_PAINT, and so on wParam and lParam contain information specific to the message type When a WM_LBUTTONDOWN message arrives, for example, wParam holds a series of bit flags identifying the state of the Ctrl and Shift keys and of the mouse buttons. lParam holds two 16-bit values ​​identifying the location of the mouse pointer when the click occurred. Together, these parameters provide the window procedure with all the inform Ation it Needs to process the wm_lbuttondown message.windows programming, SDK-Style

If you have not programmed Windows in C before, it's instructive to see what the source code for a simple program looks like. The program listed in Figure 1-2 creates a window and responds to WM_PAINT messages by drawing an ellipse in the window's upper Left Corner. This Core is Similar To The Source Code You'll Find in Books Such As Charles Petzold's Programming Windows (1998, Microsoft Press) And Other Books That Teach Windows Programming IN C.

Figure 1-2. C Source Code for a Simple Windows Program.

#include

Long WinApi WndProc (HWND, UINT, WPARAM, LPARAM);

Int WinApi Winmain (Hinstance Hinstance, Hinstance Hprevinstance, LPSTR LPSZCMDLINE, INT NCMDSHOW)

{

WNDCLASS WC;

Hwnd hwnd;

MSG msg;

wc.style = 0; // Class Style

wc.lpfnwndproc = (wndproc) WndProc; // WINDOW Procedure Address

wc.cbclsextra = 0; // Class Extra Bytes

wc.cbWndextra = 0; // WINDOW Extra Bytes

wc.hinstance = Hinstance; // Instance Handle

wc.hicon = loading (null, idi_winlogo); // icon handle

wc.hcursor = loadingcursor (null, idc_arrow); // Cursor Handle

Wc.hbrbackground = (Hbrush) (Color_Window 1); // Background Color

wc.lpsz GeneNuname = null; // menu Name

wc.lpszclassname = "myWndclass"; // WNDCLASS NAME

RegisterClass (& WC);

HWND = CREATEWINDOW

"MyWndclass", // WNDCLASS NAME

"SDK Application", // WINDOW TITLE

WS_OVERLAPPEDWINDOW, // WINDOW STYLE

CW_USEDEFAULT, // Horizontal Position

CW_USEDEFAULT, / / ​​VERTICAL POSITION

CW_USEDEFAULT, // Initial Width

CW_USEDEFAULT, // Initial Height

HWND_DESKTOP, // Handle of Parent Window

Null, // Menu Handle

Hinstance, // Application's Instance Handle

Null // WINDOW-CREATION DATA

);

ShowWindow (HWND, NCMDSHOW);

UpdateWindow (HWND);

While (GetMessage (& MSG, NULL, 0, 0)) {

TranslateMessage (& MSG);

DispatchMessage (& MSG);

}

Return msg.wparam;

}

LResult Callback WndProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM,

LPARAM LPARAM) {

Paintstruct PS;

HDC HDC;

Switch (Message) {

Case WM_Paint:

HDC = BeginPaint (HWND, & PS);

Ellipse (HDC, 0, 0, 200, 100);

Endpaint (hwnd, & ps);

Return 0;

Case WM_DESTROY:

PostquitMessage (0);

Return 0;

}

Return DefWindowProc (Hwnd, Message, WPARAM, LPARAM);

}

WinMain begins by calling the API function RegisterClass to register a window class. The window class defines important characteristics of a window such as its window procedure address, its default background color, and its icon. These and other properties are defined by filling in the fields of a WNDCLASS structure, which is subsequently passed to RegisterClass. An application must specify a window class when it creates a window, and a class must be registered before it can be used. That's why RegisterClass is called at the outset of the program. Keep in mind that a WNDCLASS-type window class is not the same as a C window class. to avoid confusion, I'll use the term WNDCLASS throughout this book to refer to classes registered with RegisterClass. The term window class will refer to C classes Derived from MFC's CWND Class.

Once the WNDCLASS is registered, WinMain calls the all-important CreateWindow function to create the application's window. The first parameter to CreateWindow is the name of the WNDCLASS from which the window will be created. The second parameter is the text that will appear in the window's title bar. The third specifies the window style. WS_OVERLAPPEDWINDOW is a commonly used style that creates a top-level window with a resizing border, a title bar, a system menu, and buttons for minimizing, maximizing, and closing the window.

. The next four parameters specify the window's initial position and size CW_USEDEFAULT tells Windows to use default values ​​for both The final four parameters specify, in order, the handle of the window's parent window (HWND_DESKTOP for an application's main window);. The handle of the menu associated with the window, if any; the application's instance handle (a value that lets the programmer differentiate between the program itself and the modules-that is, DLLs-that it loads); and a pointer to application-specific window-creation data. I could easily devote a section of this book to CreateWindow and its parameters, but as you'll see later, MFC hides much of this detail inside the class library. A typical MFC application does not have a WinMain function (at least not one you can see), and it does not call RegisterClass or CreateWindow.The window that CreateWindow creates is not initially visible on the screen because it was not created with the WS_VISIBLE style. (Had it been used, WS_VISI BLE would have been combined with WS_OVERLAPPEDWINDOW in the call to CreateWindow.) Therefore, WinMain follows CreateWindow with calls to ShowWindow and UpdateWindow, which make the window visible and ensure that its WM_PAINT handler is called immediately.

Next comes the message loop. In order to retrieve and dispatch messages, WinMain executes a simple while loop that calls the GetMessage, TranslateMessage, and DispatchMessage API functions repeatedly. GetMessage checks the message queue. If a message is available, it is removed from the queue and copied to msg;. otherwise, GetMessage blocks on the empty message queue until a message is available msg is an instance of the structure MSG, whose fields contain pertinent message parameters such as the message ID and the time at which the message was placed in the queue. TranslateMessage converts a keyboard message denoting a character key to an easier-to-use WM_CHAR message, and DispatchMessage dispatches the message to the window procedure. The message loop executes until GetMessage returns 0, which happens only when a WM_QUIT message is Retrieved from the message queue. When THIS OCCURS, Winmain Ends and The Program Terminates.

. Messages dispatched with DispatchMessage generate calls to the window procedure WndProc The sample program in Figure 1-2 processes just two message types, WM_PAINT and WM_DESTROY; all other messages are passed to DefWindowProc for default processing A switch-case block inspects the message ID. passed in the message parameter and executes the appropriate message handler. The WM_PAINT handler calls the BeginPaint API function to obtain a device context handle before painting begins and the EndPaint API function to release the handle when painting is finished. in between, the Ellipse API function draws an ellipse that is 200 pixels wide and 100 pixels high. A device context handle is the "magic cookie" that permits a Windows application to draw on the screen. Without it, functions such as Ellipse will not work.The WM_DESTROY handler calls THE POSTQUITMESSAGE API FUNCTION TO POST A WM_QUIT Message To The Message Queue and Ultimately Cause The Program To Terminate. The WM_DESTROY Message IS S ent to a window just before it is destroyed. A top-level window must call PostQuitMessage when it receives a WM_DESTROY message, or else the message loop will not fall through and the program will never end.

Hungarian NOTATION AND Windows Data Types

Another aspect of Figure 1-2 that deserves mentioning is the variable naming convention that it uses Veteran Windows programmers know it as Hungarian notation, in which each variable name begins with one or more lowercase characters identifying the variable's type:. H for handle, n for integer, and so on. The table below lists some of the commonly used Hungarian prefixes. prefixes are often combined to form other prefixes, as when p and sz are joined to form psz, which stands for "pointer to zero-terminated string. "Many of the data types shown in this table are not standard C / C data types but rather are" special "data types defined in the Windows header files. COLORREF, for example, is the Windows data type for 24-bit RGB color values. A BOOL is a Boolean data type that stores TRUE / FALSE values, while a DWORD is a 32-bit unsigned integer. Over time, you'll come to know these data types as well as you know your compiler's native data types.

Common hungarian notation prefixes

Prefixdata Typebboolc Or Ch Charclrcolorrefcx, Cyhorizontal or Vertical DistancedwdWordhhandLellongnintppointerszzRo-Terminated StringWword

Most MFC programmers use Hungarian notation, too. Glance through the source code for a typical MFC program and you'll see hundreds of hs and lps and other familiar prefixes as well as prefixes representing MFC's own data types (for example, wnd for CWnd variables ). It's also common to prefix member variables with m_ so that it's obvious whether a variable is a member of a class. A temporary CString variable created on the stack might have the name strWndClass, but if it's a member variable it will probably be called m_strWndClass. You do not have to abide by these rules yourself, of course, but observing established naming conventions will make your code more readable to other programmers who do.SDK Programming in Perspective

转载请注明原文地址:https://www.9cbs.com/read-30688.html

New Post(0)