windows程序设计第三章读后摘要

Creating a window is as easy as calling the CreateWindow function.

What you may not be accustomed to is the idea of an operating system making calls to a program. Yet this is fundamental to Windows' architecture.

Every window that a program creates has an associatedwindow procedure. This window procedure is a function that could be either in the program itself or in a dynamic-link library. Windows sends a message to a window by calling the window procedure. The window procedure does some processing based on the message and then returns control to Windows.

 A window is an object. The code is the window procedure. 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.



Hello.c


/*------------------------------------------------------------
   HELLOWIN.C -- Displays "Hello, Windows 98!" in client area
                 (c) Charles Petzold, 1998
  ------------------------------------------------------------*/


#include <windows.h>


LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;


int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     static TCHAR szAppName[] = TEXT ("HelloWin") ;
     HWND         hwnd ;
     MSG          msg ;
     WNDCLASS     wndclass ;


     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;


     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
     
     hwnd = CreateWindow (szAppName,                  // window class name
                          TEXT ("The Hello Program"), // window caption
                          WS_OVERLAPPEDWINDOW,        // window style
                          CW_USEDEFAULT,              // initial x position
                          CW_USEDEFAULT,              // initial y position
                          CW_USEDEFAULT,              // initial x size
                          CW_USEDEFAULT,              // initial y size
                          NULL,                       // parent window handle
                          NULL,                       // window menu handle
                          hInstance,                  // program instance handle
                          NULL) ;                     // creation parameters
     
     ShowWindow (hwnd, SW_SHOWMAXIMIZED) ;
     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)
{
     HDC         hdc ;
     PAINTSTRUCT ps ;
     RECT        rect ;
     
     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) ;
          
          DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,
                    DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
          
          EndPaint (hwnd, &ps) ;
          return 0 ;
          
     case WM_DESTROY:
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

//

HINSTANCE
Handle to an "instance"—the program itself
HWND
Handle to a window
HDC
Handle to a device context

A handle is simply a number (usually 32 bits in size) that refers to an object.


The message loop


Windows maintains a "message queue" for each windows program currently running under Windows. When an input event occurs,Windows translates the event into a "message" that it places in the program's message queue.


A program retrieves these messages from the message queue by executing a block of code known as the "message loop".


The Window Procedure

The real action occurs in the window procedure. The window procedure determines what the window displays in its
client area and how the window responds to user input.

A window procedure is always associated with a particular window class that you register by
calling RegisterClass.


The Windows Programming Hurdles

 In HELLOWIN,  WinMaincontains only program overhead necessary to register the window class, create the window, and retrieve and dispatch messages from the message queue.

Programmers are well acquainted with the idea of calling on the operating system to do something. For example,
C programmers use the fopenfunction to open a file. The fopenfunction is implemented with a call to the
operating system to open a file. No problem


But Windows is different. Although Windows has a couple thousand function calls, Windows also makes calls to
yourprogram, specifically to the window procedure we have called WndProc.

All these calls to WndProcare in the form of messages. In most Windows programs, the bulk of the program is
dedicated to handling these messages. The messages that Windows can send to a program are generally identified
with names that begin with the letters WM and are defined in the WINUSER.H header file.


Queued and Nonqueued Messages


So, does a Windows program poll for messages (much like a character-mode program polling for keyboard input)
and then route these messages to some location(GetMessage,DispatchMessage)? Or does it receive messages directly from outside the program?Well, both.


Messages can be either "queued" or "nonqueued." 

The queued messages are those that are placed in a program's message queue by Windows. In the program's message loop, the messages are retrieved and dispatched to the window procedure. 

The nonqueued messages are the results of calls by Windows directly to the window procedure.

 It is said that queued messages are "posted" to a message queue and that nonqueued messages are
"sent" to the window procedure. In any case, the window procedure gets all the messages—both queued and
nonqueued—for the window. The window procedure is "message central" for the window.


The queued messages are primarily those that result from user input in the form of keystrokes.

The nonqueued messages are everything else. Nonqueued messages often result from calling certain Windows
functions. For example, when WinMaincalls CreateWindow, Windows creates the window and in the process sends
the window procedure a WM_CREATE message.

Although Windows programs can have multiple threads of execution, each thread's message queue handles
messages for only the windows whose window procedures are executed in that thread. In other words,the
message loop and the window procedure do not run concurrently
. When a message loop retrieves a message from
its message queue and calls  DispatchMessageto send the message off to the window procedure,DispatchMessage
does not return until the window procedure has returned control back to Windows.


However, the window procedure could call a function that sends the window procedure another message, in which
case the window procedure must finish processing the second message before the function call returns, at which
time the window procedure proceeds with the original message. For example, when a window procedure calls
UpdateWindow, Windows calls the window procedure with a WM_PAINT message. When the window procedure
finishes processing the WM_PAINT message, the UpdateWindowcall will return controls back to the window
procedure.
This means that window procedures must be reentrant. In most cases, this doesn't cause problems, but you
should be aware of it. For example, suppose you set a static variable in the window procedure while processing a
message and then you call a Windows function. Upon return from that function, can you be assured that the
variable is still the same? Not necessarily
—not if the particular Windows function you call generated another
message and the window procedure changes the variable while processing that second message. This is one of the
reasons why certain forms of compiler optimization must be turned off when compiling Windows programs




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值