MFC——1.浅谈Windows程序内部运行机制

======写在前面=====

这一系列的MFC笔记,主要参考了孙鑫老师的《VC++深入详解》和毛星云老师的《Windows游戏编程之从零开始》。

前面来源于孙鑫老师的VC++视频教程,如果大家有时间,可以在网上下载学习参考。

后面参考了毛星云老师的著作,这里也给上毛星云作者的博客地址:http://blog.csdn.net/poem_qianmo?viewmode=contents

============================


lesson1:浅谈Windows程序内部运行机制

1.Windows 消息响应机制

Windows程序不同于传统的dos方式的设计方法,它一种事件驱动的,是基于消息的,操作系统将用户的需要包装成消息,然后将消息投递到消息队列中,最后应用程序从消息队列中取走消息并进行响应。

Windows应用程序,操作系统,计算机硬件之间的相互关系:


箭头①表示操作系统能够操作输出设备,箭头③表示应用程序可以通知操作系统执行某个具体的动作,如操作系统能够控制声卡发出声音,但它并不知道应该何时发出何种声音,需要应用程序告诉操作系统该发出什么样的声音。箭头②表示操作系统能够感知输入设备状态的变换,箭头④表示操作系统能够将输入设备的变化上传给应用程序。如用户在某个程序活动时按了一下键盘,操作系统马上能够感知到这一事件,并且能够知道用户按下的是哪一个键,操作系统并不决定对这一事件如何作出反应,而是将这一事件转交给应用程序,由应用程序决定如何对这一事件作出反应。因此操作系统相当于是一个中介。

 

那么,应用程序是如何通知操作系统执行某个功能的呢?在应用程序中要完成某个功能,都是以函数调用的形式实现的,同样,应用程序也是以函数调用的方式来通知操作系统执行相应的功能的。操作系统所能够完成的每一个特殊功能通常都有一个函数与其对应,也就是说,操作系统把它所能够完成的功能以函数的形式提供给应用程序使用,应用程序对这些函数的调用就叫做系统调用,这些函数的集合就是Windows操作系统提供给应用程序编程的接口(Application ProgrammingInterface),简称Windows API。

 

操作系统是怎样将感知到的事件传递给应用程序的呢?这是通过消息机制(Message)来实现的。操作系统将每个事件都包装成一个称为消息的结构体MSG来传递给应用程序,参看MSDN。每一个应用程序都用一个消息队列,它是一个先进先出的缓冲队列,每一个元素都是一个消息。应用程序取得消息得知用户的操作。至于消息的处理,是通过消息响应程序处理的,操作系统自动调用消息响应函数,但消息的响应方式,即这个函数得自己编写。这个可以是用Windows自己默认的处理函数,和可以自己编写处理函数。MSG结构定义如下:

typedef struct tagMSG {      

          HWND  hwnd;      //窗口句柄,指定与消息相关的窗口

          UINT  message;     //用无符号整型指定消息类型,Windows的消息都是提前用整数表示好的

          WPARAM wParam;    //指定消息的附加信息

          LPARAM lParam;      //指定消息的附加信息

          DWORD time;       //指定消息投递的时间

          POINT pt;          //指定消息投递时光标的位置

} MSG;

 

2.   创建一个完整的窗口需要经过下面四个操作步骤: 

【1 设计一个窗口类】:窗口背景,鼠标,光标,窗口最大化,最小化,窗口名称,窗口设计时,有相应的窗口类,我们只需要给成员变量赋相应的值,达到我们需要的结果;

【2 注册窗口类】:向操作系统声明,有这样一种设计的窗口;

【3 创建窗口】:产生窗口;

【4 显示及更新窗口】:窗口发生变化时(移动),重新绘制窗口。

下面是程序代码,并附有完整的注释。

#include<windows.h>             //windows的头文件
#include<stdio.h>               //C语言的头文件
 
LRESULTCALLBACK WinSunProc(     //消息响应函数,函数原型的申明,以被后面调用
  HWND hwnd,     <span style="white-space:pre">		</span>// handle to window
  UINT uMsg,      <span style="white-space:pre">		</span>// message identifier  
  WPARAM wParam,  <span style="white-space:pre">		</span>// first message parameter
  LPARAM lParam   <span style="white-space:pre">		</span>// second message parameter
);
 
intWINAPI WinMain(              //Windows程序入口点函数 WinMain函数
  HINSTANCE hInstance,          // handle to current instance 当前运行实例句柄
  HINSTANCE hPrevInstance,      // handle to previous instance 先前一实例句柄(同一个应用程序之间)
  LPSTR lpCmdLine,              // command line  命令行参数
  int nCmdShow                  // show state  状态显示,指定程序窗口如何显示(最大化,最小化,隐藏等)
)
{
       WNDCLASS wndcls;        //【第一步 设计一个窗口类】</span>
       wndcls.cbClsExtra=0;    //额外的类的附加内存空间,附加字节数,通常设为0
       wndcls.cbWndExtra=0;    //窗口的附加内存空间,附加字节数
       wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);   //窗口背景  HBRUSH是数据类型强制转换
       wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);                  //光标
       wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);                      //图标
       wndcls.hInstance=hInstance;                                 //应用程序的实例号
       wndcls.lpfnWndProc=WinSunProc;                              //窗口过程函数,就是消息响应函数。操作系统自动调用这个函数,但消息响应函数得自己写收到消息时的处理动作
       wndcls.lpszClassName="Weixin2003";                          //类名
       wndcls.lpszMenuName=NULL;                                   //菜单名字(没有菜单)
       wndcls.style=CS_HREDRAW |CS_VREDRAW;                        //窗口刷新类型是水平和垂直重画,移动窗口时发生(水平/垂直坐标变换),
                                                                   //如果没有重绘,窗口移动时,上面的图片或文字不发生变化
       RegisterClass(&wndcls);                                     //【第二部 注册窗口类】</span>以被调用
 
       HWND hwnd;                                                  //【第三部 创建窗口】</span>定义句柄
       hwnd=CreateWindow("Weixin2003","北京维新科学技术培训中心",WS_OVERLAPPEDWINDOW,
              0,0,600,400,NULL,NULL,hInstance,NULL);               //(类名,窗口名字,窗口类型,窗口坐标x,y和窗口大小高、宽,
                                                                   //副窗口,菜单,实例的句柄,窗口创建的数据)
 
       ShowWindow(hwnd,SW_SHOWNORMAL);                             //【第四部 显示及更新窗口】</span>
       UpdateWindow(hwnd);
 
       MSG msg;                                                    //消息循环
       while(GetMessage(&msg,NULL,0,0))     //获得消息,返回值为真,为假程序退出所有消息都获取(消息信息,窗口句柄指定哪个窗口的消息<span style="font-family: Arial, Helvetica, sans-serif;">null表示获取所有消息,</span>                                            //最后两参数为消息过滤,最小消息值(第一个鼠标消息或键盘消息),最大消息值,当两个为0 ,表示所有消息)
       {
              TranslateMessage(&msg);                               //转换消息并投递到消息队列中
              DispatchMessage(&msg);                                //将消息从消息队列中取出并传递给窗口的过程函数(回调函数CALLBACK)
       }                                                            //可以理解为它把消息给操作系统,然后操作系统做出相应动作,动作是我们编写的CALLBACK函数
       return 0;
}
 
LRESULTCALLBACK WinSunProc(                                         //编写的响应消息的回调函数CALLBACK函数
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
)
{
       switch(uMsg)
       {
       case WM_CHAR:                                                    //输入字符
              char szChar[20];                                          //定义字符数组
              sprintf(szChar,"char is%d",wParam);                       //格式化文本到内存buffer中
              MessageBox(hwnd,szChar,"weixin",0);                       //弹出窗口内容  文本内容szChar 标题weixin 窗口类型0
              break;
       case WM_LBUTTONDOWN:                                             //左单击鼠标
              MessageBox(hwnd,"mouseclicked","weixin",0);               //弹出消息框
              HDC hdc;                                                  //定义HDC结构体 ,设备上下文句柄,device contest句柄,DC帮助我们与显示程序交互
              hdc=GetDC(hwnd);      
              TextOut(hdc,0,50,"计算机编程语言培训",strlen("计算机编程语言培训"));  //在0,50输出内容
              ReleaseDC(hwnd,hdc);                                      //释放
              break;
       case WM_PAINT:                                                   //窗口重绘
              HDC hDC                                                   //定义
              PAINTSTRUCT ps;                                           //定义结构体
              hDC=BeginPaint(hwnd,&ps);                                 //开始,这对函数只能在WM_PAINT中使用
              TextOut(hDC,0,0,"维新培训",strlen("维新培训"));
              EndPaint(hwnd,&ps);                                       //结束
              break;
       case WM_CLOSE:                                                   //关闭窗口
              if(IDYES==MessageBox(hwnd,"是否真的结束?","weixin",MB_YESNO))   //判断是否结束
              {
                     DestroyWindow(hwnd);                               //销毁窗口,此函数Y会传递一个消息位WM_DESTORY
              }                                                         //即下一个case的地方
              break;
       case WM_DESTROY:                                                 //销毁窗口
              PostQuitMessage(0);                                       //退出
              break;
       default:                                                         //返回缺省的窗口处理方式
              returnDefWindowProc(hwnd,uMsg,wParam,lParam);
       }
       return 0;
}

程序思路很简洁,WinMain为主函数,主函数进行设计、注册、产生和重绘窗口。在设计窗口的时候指定了窗口的消息响应函数WinSunProc,因此每一个消息都用WinSunProc函数进行处理。


下面是附加的参考文献:

1.      消息函数 typedef structtagMSG 

参考 http://blog.ifeng.com/article/2683896.html

2.      窗口建立函数 int WINAPI WinMain       

参考 http://blog.csdn.net/seawave/article/details/1338879


程序运行截图:

         


         


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值