完整的HelloWin程序_带注释

参考教材——windows程序设计(第5版)

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

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
//窗口回调函数声明 LRESULT是函数返回值类型被宏定义为LONG
//CALLBACK说明的是函数参数的进栈顺序(从左到右)!
//4个函数参数为message结构体中的前4个参数!

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow) 
//主函数,int为函数返回值类型,WINAPI和CALLBACK一样都函数参数的进栈顺序!
//HINSTANCE hInstance 定义一个实例句柄变量,所谓句柄的概念和指针,引用差不多,但又不太一样!自己体会一下
//其他参数看书44页!
{
     static TCHAR szAppName[] = TEXT ("HelloWin") ; 
     //定义一个字符串数组szAppName[]并赋初值!这个“HelloWin”是程序的名字
     //是要进操作系统的注册表的!是告诉操作系统你这个程序的名字是什么!
                                                   
     HWND         hwnd ; //定义窗口句柄变量!
     MSG          msg ;  //MSG是一个结构体类型,所以msg是一个结构体变量!见书54页
     WNDCLASS     wndclass ;//WNDCLASS是一个结构体类型,所以wndclass是一个结构体变量!见书47,48页

     wndclass.style         = CS_HREDRAW | CS_VREDRAW ; //为窗口风格赋值,CS_HREDRAW 为垂直重画 CS_VREDRAW为水平重画!意思就                                            

             //是如果你水平或竖直拖动窗口,他将重新显示窗口,即调用WM_PAINT消息! 
     wndclass.lpfnWndProc   = WndProc ;  //把窗口回调函数的首地址赋给wndclass.lpfnWndProc
     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) ;  
      //初始化窗口的背景画刷,如果把WHITE_BRUSH改为BLACK_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     窗口显示时左上角x坐标
                          CW_USEDEFAULT,  // initial y position     窗口显示时左上角y坐标
                          CW_USEDEFAULT, // initial x size         窗口显示时右下角x坐标
                          CW_USEDEFAULT, // initial y size         窗口显示时右下角y坐标
                          NULL,  // parent window handle   父窗口句柄,此程序没有
                          NULL,     // window menu handle     菜单句柄
                          hInstance,  // program instance handle程序实例句柄
                          NULL) ;  // creation parameters    创建参数指针
     
     ShowWindow (hwnd, iCmdShow) ;  
   //第一次调用窗口回调函数Wndproc,注意Wndproc函数不是ShowWindow函数来调用,而是
   //ShowWindow函数向操作系统发送消息,是操作系统根据发送的消息来调用Wndproc函数!
   //操作系统调用Wndproc函数后并响应WM_CREATE消息!
                                    
     UpdateWindow (hwnd) ; //刷新窗口,操作系统调用Wndproc函数,并响应WM_PAINT消息!
     
     while (GetMessage (&msg, NULL, 0, 0))
     // 这是所有WINDOWS程序的核心,消息循环处理过程!这里是接受消息和发送消息的地方!
     //GetMessage 函数从操作系统的消息队列中获得消息,一个一个的处理,来一个处理一个,
     //直到获得退出消息,也就是点击应用程序右上角的叉子!退出消息循环,并响应WM_QUIT消息
     {                                     
     
          TranslateMessage (&msg) ;  //翻译键盘消息
          DispatchMessage (&msg) ;//发送消息函数,先把msg发送给操作系统,然后由操作系统再调用Wndproc函数!
     }
     return msg.wParam ;
}//主函数结束

//窗口回调函数,此函数只有声明和定义,没有调用!这说明此函数确实是由操作系统调用的!
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)//函数的4个参数是消息结构体的前4个参数!
{
     HDC         hdc ; //设备环境描述表句柄
     PAINTSTRUCT ps ;  //绘图结构体变量
     RECT        rect ;//矩形变量
     
     switch (message)   //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) ;//处理一些闲杂以及一些不可预料的消息!
}

/*注意  1:所有的消息都由操作系统负责管理,所有的消息先进入总的系统消息队列,再由系统消息队列向各个小应用程序队列发消息!
        2:窗口回调函数Wndproc是由操作系统调用的,所有的消息进入消息循环,由消息循环把消息发到操作系统的队列中,在由操作系统
           根据消息来调用Wndproc函数,而Wndproc函数根据message的不同而调用相应的处理过程!
        3:上面这个程序你可以改造一下,在添加几个消息处理过程,比如鼠标左键按下WM_LBULLONDOWN,鼠标左键抬起WM_LBULLONUP
           定时器消息WM_TIMER,绘图消息WM_PAINT消息等等,然后把PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) 
           这个函数添加到以上各个消息处理过程中,看看结果是不是进行了相应的操作!比如,点击一下鼠标左键看看是不是发出声音了!
           可以自己试试!
        4:其实,WINDOWS程序也可以自己去创建函数!自己去自定义消息处理过程!比如,你自己定义了一个函数,想在鼠标左键点击后
           去调用这个函数,那就可以在WM_LBULLONDOWN这个消息处理过程中加上你自己定义的函数调用就可以了!
        5:上面这个程序是个非常简单的程序,但是他足以说明WINDOWS程序的消息机制!几乎所有的程序都包括上面这段代码(除了PLAYSOUND函数和
           DrawText函数),不管多么复杂的WINDOWS程序都必须包括上面这段代码,因为他是再简单不过的了,只是创建了一个窗口!但是,
           再复杂的程序无非也就是在Wndproc函数中的switch多加几个case 吗!无非就是加上什么鼠标,键盘,定时器等等,但原里都是
           一样的!他的消息处理过程都是一样的!主要是把他的消息机制弄懂,其他的都非常easy!
*/


下面是网上对杨力祥老师的评价: 有感于杨力祥老师和中科院的牛人们,进而有感于中科院和北京的学生 (2007-03-23 09:47:45) 转载▼ 还是再说一个高级Windows程序设计的杨力祥老师,周三上完课后还在回味呢,在他滔滔不绝,口若悬河的精彩讲演中深知计算机这东东的快乐是在巨大的痛若经历和深厚功底下的,当然了激情是支撑这一路下去的唯一东东。对编程的感觉就像艺术般地发挥。像那个五分钟搞出汇编把软件驱修好的牛人,与IBM的角力,小编程的演示,无不透出其出的深厚内涵 ,不禁想到自已是否可以几年以后如此这般萧洒。(总不明白为何身边有那夸夸其谈不干实事的人,不可能是物以类聚吧?呵自认是绝对勤快的人啊)。 再说中科院和北京的大学生,有他们是有那么好的机会和资源啊,不在于有多少钱有多好的硬件设施,他们可以看到的和听到的是我们所无法比的。可以请王永明,可以听INTEL的高手,见到不同的牛人,于此不会也是不可能的。呵如果这些都搬到广州就好了。为什么偏是在北京呢?如果哪天哪个领导人英明一下,大手一挥,北京只搞政治,不搞经济,别的都给我投出去,呵,这下可好了,牛人们都往南方走了。 刚才上传了CSDN把我的资源删了,不知道怎么回事。。可能是后缀名的问题 重新弄了一下。下载后把后缀名改成downlist就可以用迅雷打开了。 解压密码:abab123.gfugifyr7t565
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值