/*------------------------------------------------------------
   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 第一个参数刚刚创建的窗体,第二个参数是从winmain函数中传入的,此处改成了SW_SHOWMAXIMIZED代表最大化显示
     ShowWindow (hwnd,SW_SHOWMAXIMIZED) ;
     UpdateWindow (hwnd) ;
  
   /* msg变量是型态为 MSG 的结构,型态 MSG在 WINUSER.H中定义如下:
 typedef struct tagMSG
 {
 HWND hwnd ;
 UINT message ;
 WPARAM wParam ;
 LPARAM lParam ;
 DWORD time ;
 POINT pt ;
 }
 * POINT 数据型态也是一个结构,它在 WINDEF.H 中定义如下:
 typedef struct tagPOINT
 {
 LONG x ;
 LONG y ;
 }*/
     while (GetMessage (&msg, NULL, 0, 0))
    /*GetMessage
  GetMessage (&msg, NULL, 0, 0)
  这一呼叫传给 Windows一个指标,指向名为 msg的MSG 结构。第二、第三和第四个参数设定为 NULL 或者 0,
  表示程序接收它自己建立的所有窗口的所有消息。Windows用从消息队列中取出的下一个消息来填充消息结构
  的各个字段,结构的各个字段包括:
   hwnd 接收消息的窗口句柄。在 HELLOWIN程序中,这一参数与 CreateWindow 传回的 hwnd
  值相同,因为这是该程序拥有的唯一窗口。
   message 消息标识符。这是一个数值,用以标识消息。对于每个消息,均有一个对应的标识
  符,这些标识符定义于 Windows表头文件(其中大多数在 WINUSER.H 中) ,以前缀 WM( 「window message」 ,
  窗口消息)开头。例如,使用者将鼠标光标放在HELLOWIN显示区域之内,并按下鼠标左按钮,Windows就在
  消息队列中放入一个消息,该消息的 message 字段等于 WM_LBUTTONDOWN。这是一个常数,其值为0x0201。
   wParam 一个32位的「message parameter(消息参数) 」 ,其含义和数值根据消息的不同而不
  同。
   lParam 一个32 位的消息参数,其值与消息有关。
   time 消息放入消息队列中的时间。
   pt 消息放入消息队列时的鼠标坐标。
  只要从消息队列中取出消息的 message 字段不为 WM_QUIT (其值为0x0012) , GetMessage 就传回一个非零值。
  WM_QUIT消息将导致GetMessage 传回 0。*/
  {

          TranslateMessage (&msg) ;//将 msg结构传给 Windows,进行一些键盘转换
          DispatchMessage (&msg) ;
   /* DispatchMessage又将 msg结构回传给 Windows。然后,Windows将该消息发送给适当的窗口消息处理程序,让它进   行处理。这也就是说,Windows将呼叫窗口消息处理程序。在HELLOWIN 中,这个窗口消息处理程序就是 WndProe 函   数。处理完消息之后,WndProc 传回到 Windows。此时,Windows还停留在 DispatchMessage 呼叫中。在结束DispatchMessage 呼叫的处理之后,Windows回到HELLOWIN,并且接着从下一个 GetMessage呼叫开始消息循环。*/
     }
     return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 /*窗口消息处理程序的四个参数与 MSG 结构的前四个字段是相同的。第一个参数 hwnd是接收消息的窗口
的句柄,它与 CreateWindow 函数的传回值相同。对于与HELLOWIN相似的程序(只建立一个窗口),这个参
数是程序所知道的唯一窗口句柄。如果程序是依据同一窗口类别(同时也是同一窗口消息处理程序)建立多个
窗口,则 hwnd标识接收消息的特定窗口。
第二个参数与 MSG 结构中的 message 字段相同,它是标识消息的数值。最后两个参数都是 32 位的消息参数,
提供关于消息的更多信息。这些参数包含每个消息型态的详细信息。有时消息参数是两个存放在一起的 16位
值,而有时消息参数又是一个指向字符串或数据结构的指针。
程序通常不直接呼叫窗口消息处理程序,窗口消息处理程序通常由 Windows本身呼叫。通过呼叫 SendMessage
函数,程序能够直接呼叫它自己的窗口消息处理程序。*/
{
     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:
  /* WndProc 处理的第二个消息为 WM_PAINT。这个消息在 Windows程序设计中是很重要的。当窗口显示区域的一
  部分显示内容或者全部变为「无效」,以致于必须「更新画面」时,将由这个消息通知程序。
  显示区域的显示内容怎么会变得无效呢?在最初建立窗口的时候,整个显示区域都是无效的,因为程序还没有
  在窗口上画什么东西。第一条 WM_PAINT 消息(通常发生在 WinMain 中呼叫UpdateWindow 时)指示窗口消息
  处理程序在显示区域上画一些东西。
  在使用者改变HELLOWIN窗口的大小后,显示区域的显示内容重新变得无效。读者应该还记得,HELLOWIN 中
  wndclass结构的 style字段设定为标志 CS_HREDRAW和 CS_VREDRAW,这样的格式设定指示 Windows,在窗口
  大小改变后,就把整个窗口显示内容当成无效。然后,窗口消息处理程序将收到一条 WM_PAINT 消息。
  当使用者将 HELLOWIN 最小化,然后再次将窗口恢复为以前的大小时,Windows 将不会保存显示区域的内容。
  在图形环境下,窗口显示区域涉及的数据量很大。因此,Windows令窗口无效,窗口消息处理程序接收一条
  WM_PAINT 消息,并自动恢复其窗口的内容。
  在移动窗口以致其相互重迭时,Windows不保存一个窗口中被另一个窗口所遮盖的内容。在这一部分不再被遮
  盖之后,它就被标志为无效。窗口消息处理程序接收到一条 WM_PAINT 消息,以更新窗口的内容。
  对 WM_PAINT的处理几乎总是从一个 BeginPaint呼叫开始:
  hdc = BeginPaint (hwnd, &ps) ;
  而以一个 EndPaint呼叫结束:
  EndPaint (hwnd, &ps) ;
  在这两个呼叫中,第一个参数都是程序的窗口句柄,第二个参数是指向型态为 PAINTSTRUCT 的结构指针。
  PAINTSTRUCT结构中包含一些窗口消息处理程序,可以用来更新显示区域的内容。我们将在下一章中讨论该结
  构的各个字段。现在我们只在BeginPaint和 EndPaint函数中用到它。*/
          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) ;//该函数在程序的消息队列中插入一个 WM_QUIT 消息。前面提到过,GetMessage 对于除了   WM_QUIT 之外的从消息队列中取出的所有消息都传回非 0值。而当GetMessage 得到一个 WM_QUIT 消息时,它传回 0。这将导 致WinMain 退出消息循环,并终止程序。然后程序执行下面的叙述:
          return 0 ;
     }
  //有时候,DefWindowProc处理完消息后会产生其它的消息。例如,假设使用者执行 HELLOWIN,并且使用者最
  //终单击了 Close按钮,或者假设用键盘或鼠标从系统菜单中选择了 Close, DefWindowProc 处理这一键盘或者
  //鼠标输入, 在检测到使用者选择了 Close选项之后, 它给窗口消息处理程序发送一条 WM_SYSCOMMAND消息。WndProc这个消息传给DefWindowProc。DefWindowProc 给窗口消息处理程序发送一条 WM_CLOSE消息来响
  //应之。WndProc 再次将它传给 DefWindowProc。DestroyWindow呼叫DestroyWindow 来响应这条 WM_CLOSE 消
  //息。DestroyWindow导致Windows给窗口消息处理程序发送一条 WM_DESTROY 消息。WndProc 再呼叫
  //PostQuitMessage,将一条WM_QUIT消息放入消息队列中,以此来响应此消息。这个消息导致 WinMain中的消
  //息循环终止,然后程序结束。
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

posted on 2010-10-26 22:53  TsingCai  阅读(808)  评论(0编辑  收藏  举报