《Windows 程序设计》学习笔记(三)

类别:VC语言 点击:0 评论:0 推荐:

第三章 窗口和消息

 

进行Windows程序设计实际上是创建“窗口”对象和处理窗口消息的过程,“窗口”对象不仅指应用程序窗口,还包括对话框,按钮,单选钮等许多许多。在Windows中,“窗口”是无所不在的。窗口以“消息”的形式来接收用户的输入的,而“消息”是操作系统发送给应用程序的。比如,我们用鼠标按下一个按钮时,Windows操作系统把按鼠标的这个“消息”告诉按钮:“嘿!按钮我现在正在按你呢!”,按钮收到这个“消息”后,想了想:“那我就卧倒吧。”这时我们就看到按钮被鼠标按下了。就这么简单!

每一个窗口是在特定的“窗口类”的基础上创建的,窗口类中标识了“窗口过程”,而窗口是通过窗口过程接收和处理消息的。窗口过程实际上是一个函数,函数的参数含有消息的若干信息,我们可以利用这些信息来进行相应的处理。一个窗口可以接收到许多个消息,这些消息不能同时被窗口接收处理,它们就像在食堂打饭一样按顺序排成队,一个一个被窗口处理,这就是“消息列队”;但是,也有例外的情况,如同一个人有急事可能插队打饭,有些消息可以直接发送个窗口过程,不用放入消息队列中(用SendMessage函数)。

现在我知道了:创建一个窗口首先需要注册一个窗口类,需要一个窗口过程来处理窗口消息。书中的例子说明窗口和消息到底是什么,这个例子几乎会出现在每一个Windows程序中,也就是说,每一个Windows程序都是以这个程序为基础进行扩充的。熟悉它的每一个细节非常重要。(下面程序中的注释几乎解释了每一条语句的意义)

#include <windows.h>

//申明窗口过程函数

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

//Windows程序的入口函数

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

                    PSTR szCmdLine, int iCmdShow)

{

     static TCHAR szAppName[] = TEXT ("HelloWin") ;

     HWND         hwnd ;//定义一个Windows句柄的变量

     MSG           msg ;//定义一个消息的结构变量

/             //第一步: 定义一个窗口类的结构,此结构中的10个域描述了窗口类的特征,下面依次给这10个域赋值

     WNDCLASS     wndclass ;

     wndclass.style    = CS_HREDRAW | CS_VREDRAW ;//基于此窗口类创建的窗口风格

     wndclass.lpfnWndProc   = WndProc ;//指向窗口过程函数的指针

     wndclass.cbClsExtra     = 0 ;//窗口类结构的预留空间

     wndclass.cbWndExtra    = 0 ;//同上

     wndclass.hInstance      = hInstance ;//Windows程序的实例句柄,这是由编译器提供的

    //为所有基于这个窗口类建立的窗口设置一个图标

     wndclass.hIcon  = LoadIcon (NULL, IDI_APPLICATION) ;

     //为所有基于这个窗口类建立的窗口设置一个鼠标

    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;

     //指定了基于这个窗口类创建的窗口背景颜色,用取得一个白色刷子的句柄来实现

    wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;

    //指定窗口类的菜单,用NULL赋值表示这个程序中没有菜单

   wndclass.lpszMenuName  = NULL ;

   //指定窗口类的名称

  wndclass.lpszClassName = szAppName ;

 

/           // 第二步:向Windows注册一个窗口类,如果在Win98下运行RegisterClass函数,将返回0表明有错误发生

if (!RegisterClass (&wndclass))

     {

          MessageBox (NULL, TEXT ("This program requires Windows NT!"),

                      szAppName, MB_ICONERROR) ;

          return 0 ;

     }

 //第三步:基于上面注册的窗口类创建一个窗口,分配一块内存保存窗口的信息

hwnd = CreateWindow (szAppName,    // 窗口类的名称,基于这个窗口类创建窗口

                   TEXT ("The Hello Program"), //窗口标题栏的名称

                   WS_OVERLAPPEDWINDOW,  // 窗口的风格

                   CW_USEDEFAULT,         //窗口位置的X坐标

                   CW_USEDEFAULT,         //窗口位置的Y坐标

                   CW_USEDEFAULT,         //窗口大小宽

                   CW_USEDEFAULT,         //窗口大小高

                   NULL,                   // 父窗口的句柄

                   NULL,                   // 窗口菜单的句柄

                   hInstance,                // Windows应用程序的实例句柄

                   NULL) ;        // 创建参数的指针,可以用它访问程序中的数据

 //第四步:      //第四步:显示窗口,在显示屏上显示窗口(ShowWindow),并给窗口客户区刷上背景颜色(UpdateWindow)

 ShowWindow (hwnd, iCmdShow) ;

 UpdateWindow (hwnd) ;

    

//此时窗口已经出现在显示器上等待用户的键盘和鼠标的输入,随时进行相应的处理

/       //第五步:利用下面的循环,在消息队列中不断解析消息,然后Windows把消息发给窗口过程函数进行相应的处理。

while (GetMessage (&msg, NULL, 0, 0))    //从消息队列中取得消息

  {

     TranslateMessage (&msg) ;//将msg结构传给Windows,进行一些键盘转换

     DispatchMessage (&msg) ; //Windows将消息发送给窗口过程函数(WndPro)进行相应的处理

  }

//上面循环的终止条件是:取得WM_QUIT消息。

  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:  //当创建一个窗口时,Windows向WndProc发送WM_CREATE

         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) ;//消息的默认处理

}

 

实际上Windows把消息的处理机制封装起来,使我们只要用窗口类去标识一个窗口过程函数(WndPro),就可以在这个过程函数中处理Windows向窗口发送的各种消息了。

最后,需要注意一个窗口类可以创建多个不同的窗口。

 

 

本文地址:http://com.8s8s.com/it/it2463.htm