【MFC】1.Windows程序内部运行原理

1.原理与内容

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


向下的箭头③表示应用程序可以通知操作系统执行某个具体的动作,如操作系统能够控制声卡发出声音,但它并不知道应该何时发出何种声音,需要应用程序告诉操作系统该发出什么样的声音。这个关系好比有个机器人能够完成行走的功能,但是,如果人们不告诉它往哪个方向上走,机器人是不会主动行走的。这里的机器人就是操作系统,人们就是应用程序。

向上的箭头④表示操作系统能够将输入设备的变化上传给应用程序。如用户在某个程序活动时按了一下键盘,操作系统马上能够感知到这一事件,并且能够知道用户按下的是哪一个键,操作系统并不决定对这一事件如何作出反应,而是将这一事件转交给应用程序,由应用程序决定如何对这一事件作出反应。好比有个蚊子叮了我们一口,我们的神经末梢(相当于操作系统)马上感知到这一事件,并传递给了我们的大脑(相当于应用程序),我们的大脑最终决定如何对这一事件作出反应,如将蚊子赶走,或是将蚊子拍死。对事件作出反应的过程就是消息响应。 

句柄(HANDLE),资源的标识。操作系统要管理和操作这些资源,都是通过句柄来找到对应的资源。按资源的类型,又可将句柄细分成图标句柄(HICON),光标句柄(HCURSOR),窗口句柄(HWND),应用程序实例句柄(HINSTANCE)等等各种类型的句柄。操作系统给每一个窗口指定的一个唯一的标识号即窗口句柄。 

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

(1)设计一个窗口类;

(2)注册窗口类;

(3)创建窗口;

(4)显示及更新窗口。

2.API程序代码

#include<windows.h>
#include<stdio.h>
 
//回调函数声明
LRESULT CALLBACK WindowProc(
   HWND hwnd,      // handle to window
   UINT uMsg,      // message identifier
   WPARAM wParam,  // first message parameter
   LPARAM lParam   // second message parameter
);
 //操作系统调用,并给WINMAIN分配一个实例号,并传递参数
int WINAPI WinMain(
   HINSTANCE hInstance,      // handle to current instance
   HINSTANCE hPrevInstance,  // handle to previous instance
   LPSTR lpCmdLine,          // pointer to command line
   int nCmdShow              // show state of window  最大化显示 还是最小化显示
)
{
   //第一步:设计窗口类
   WNDCLASS wndcls;							        
   wndcls.style = CS_HREDRAW | CS_VREDRAW; 
   // 水平和垂直重画,在窗口调整大小的时候告知
   // 是否需要重画,如果填写两参数,表示重画,窗口内容将清除重画


   wndcls.lpfnWndProc = WindowProc; // 回调函数
                   // 当应用程序收到某个窗口的消息,消息与窗口相关,需要调用一个函数作相应,
<span style="white-space:pre">		</span>   // 这些工作本来是有操作系统进行处理的,但是需要我们进行通知
                   // 不同的窗口有特定回调函数

   wndcls.cbClsExtra = 0;  //类额外数据,内存空间称为类的附加内存
   wndcls.cbWndExtra = 0;  //窗口附加内存
   wndcls.hInstance  = hInstance;  //当前实例号,即利用操作系统传进来的形参hInstance进行复制
   
   wndcls.hIcon = LoadIcon(NULL,IDI_ERROR ); //微软的标准图标第一个参数皆为NULL

   wndcls.hCursor = LoadCursor(NULL,IDC_ARROW); //如用预定义光标,第一参数为NULL,IDC_CROSS

   wndcls.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); //得到预定义的画刷,画笔等

   wndcls.lpszMenuName = NULL; //窗口菜单名
   wndcls.lpszClassName = "winmain"; //给本窗口类取个名字
   

   //第二步:注册窗口类
   RegisterClass(&wndcls); //向操作系统注册
  
   //第三步:创建窗口
   HWND hwnd; //句柄,标识/特征等,分配资源
   hwnd = CreateWindow("winmain",  //操作系统认识的名字
		<span style="white-space:pre">	</span>"第一个实验!", //标题栏的名字
			WS_OVERLAPPEDWINDOW /* &~WS_MAXIMIZEBOX */,
			0,//CW_USEDEFAULT,//窗口显示的时候,采用操作系统默认为位置及大小
			0,//CW_USEDEFAULT,
			200,//CW_USEDEFAULT,
			200,//CW_USEDEFAULT, /*自主设定0,0,100,200*/
			NULL,       //父窗口的句柄         
			NULL,      //菜单的句柄
			hInstance, //当前的实例,操作系统传的值
			NULL);
 
   //第四步:显示窗口
   ShowWindow(hwnd,SW_SHOWNORMAL); //显示哪一个窗口???
 
   //第五步:更新窗口,可有可无
   UpdateWindow(hwnd);
 
   MSG msg;
   //每次循环从消息队列中取出一条消息进行处理
   while(GetMessage(&msg,NULL,0,0)) //NULL  调用线程任意窗口的消息
   {
        //该语句将类似于WM_KeyDown和WM_KeyUp转换生成新WM_CHAR投递给系统处理
        TranslateMessage(&msg);
        //将消息投递出去给操作系统,操作系统会自动调用回调函数处理
        DispatchMessage(&msg);
   }
   return 0;
}
 
LRESULT CALLBACK WindowProc(
   HWND hwnd,      // handle to window
   UINT uMsg,      // message identifier
   WPARAM wParam,  // first message parameter
   LPARAM lParam   // second message parameter
                                    )
{
   HDC hdc;
   switch(uMsg) {
   case WM_PAINT:
        PAINTSTRUCT ps;
        hdc=BeginPaint(hwnd,&ps);
        TextOut(hdc,0,10,"hello world!",strlen("hello world!"));
        EndPaint(hwnd,&ps);
        break;
   case WM_CHAR:
        char szChar[20];
        sprintf(szChar,"char is %d",wParam);
        MessageBox(hwnd,szChar,"Warnning!",MB_OK);
   case WM_LBUTTONDOWN:
        hdc=GetDC(hwnd); //得到当前窗口的上下文句柄
        TextOut(hdc,0,50,"沈春旭作品",strlen("沈春旭作品"));
        ReleaseDC(hwnd,hdc);
        break;
   case WM_CLOSE:
        if(IDOK==MessageBox(hwnd,"确认要退出嘛?","Warning!",MB_OK))
        {
              //销毁窗口,但进程中还是保留的,该函数直接抛出WM_DESTROY消息
              DestroyWindow(hwnd);
        }
        break;
   case WM_DESTROY:
        PostQuitMessage(0); //终止消息循环,并抛出WM_QUIT消息,从而导致上面的消息循环退出
   default:
        //对于代码中没有涉及到的消息,由提交给系统处理,此句一定要加,否则窗口不会出现
        return DefWindowProc(hwnd,uMsg,wParam,lParam);
   }
   return 0;
}

3.执行结果








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值