windows程序内部运行原理

1、MSG结构体(消息)

typedef struct tagMSG 
{     
   HWND hwnd;  
   UINT message; 
   WPARAM wParam; 
   LPARAM lParam; 
   DWORD time; 
   POINT pt; 
} MSG;

句柄(HANDLE),资源的标识。

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

UINT:unsigned int 也就是说 message存放的是一些无符号整形变量。例如,我们按下鼠标,就会产生一个UINT数给message。这些数字是很不好记的。微软给这些UINT定义成了一些宏。这些宏是以WM_开头的。比如,按下鼠标左键为WM_LBOTTONDOWN。

WPARAM:也是一种整数类型的数据。wParam存放的是message的附加参数,比如,我们按下A键,产生一个WM_CHAR消息,但是不知道按下的是哪个按键,所以,可以将A的ASCII码放在wParam中去。

LPARAM:和WPARAM的意思一样,作用不同。

DWORD:32位无符号整数,time指定消息发布的时间

POINT:结构体,代码如下。表示了坐标值。pt指示一个光标的位置

typedef struct tagPOINT
{
LONG x;
LONG y;
} POINT;

2、入口函数

int WINAPI WinMain(
  HINSTANCE hInstance,     // 当前应用程序实例句炳
  HINSTANCE hPrevInstance, // 指向前一个运行的应用程序实例的句柄。永远为NULL
  LPSTR lpCmdLine,         // LP:长指针类型。LPWSTR:一个指向字符串的长指针。lpCmdLine是命令行的参数command line 
  int nCmdShow             // 窗口显示时的状态,来决定你的应用程序是最小化还是最大化,还是关闭窗口
);
//WinMain函数是操作系统调用的,里面的参数都是操作系统自动给的。

3、设计一个窗口类

typedef struct _WNDCLASS { 
   UINT    	style;           //窗口类样式
   WNDPROC	lpfnWndProc;     //用来接收一个函数指针。当窗口产生一个消息,需要一个回调函数来处理这个消息,这个处理消息的函数就是用lpfnWndProc来指定
   int      cbClsExtra;      //窗口类附加内存字节数,通常为0
   int     	cbWndExtra;      //窗口附加内存字节数,通常为0
   HANDLE 	hInstance;       //应用程序实例句柄
   HICON   	hIcon;           //标题栏图标
   HCURSOR 	hCursor;         //光标
   HBRUSH  	hbrBackground;   //画刷的句柄,可以设置窗口背景颜色
   LPCTSTR 	lpszMenuName;    //long pointer const string,设置菜单资源名称
   LPCTSTR 	lpszClassName;   //设置窗口类名称
} WNDCLASS; 

4、注册窗口类

用RegisterClass();

ATOM RegisterClass(
  CONST WNDCLASS *lpWndClass   //class data
)
//typedef WORD ATOM;
//typedef unsigned short WORD;
//所以说ATOM应该是无符号短整型

例如,上面我们实例化一个类对象 WNDCLASS wndclass;设置好各种参数后,再RegisterClass(&wndclass);就行了。

5、创建窗口

HWND CreateWindow( 
  LPCTSTR lpClassName,     // 已注册的窗口类名称
  LPCTSTR lpWindowName,    // 窗口的名字
  DWORD dwStyle,           // 窗口样式
  int x,                   // 窗口的水平坐标 
  int y,                   // 垂直坐标 
  int nWidth,              // 宽度
  int nHeight,             // 高度
  HWND hWndParent,         // 父窗口句柄 
  HMENU hMenu,             // 菜单句柄 
  HINSTANCE hInstance,     // 应用程序实例句柄 
  LPVOID lpParam           // long point void,没有类型的指针,用于多文档程序的附加参数,单文档为NULL
 ); 

6、显示及更新窗口

BOOL ShowWindow( 
  HWND hWnd, 
  int nCmdShow //show state 可以设置最大化显示,最小化显示
);

然后要调用UpdateWindow(hwnd);刷新窗口

7、消息循环与发送消息

MSG msg;
	while (GetMessage(&msg,NULL,0,0)) //从消息队列获取消息并在消息队列删除该消息(除WM_PAINT)
	{                                 //第二个参数设置为NULL是为了捕获任何窗口消息,如果设置为hwnd,则只会接收来自该窗口的消息
		TranslateMessage(&msg);       //消息解释
		DispatchMessage(&msg);        //将消息发送到“窗口过程”
	}

GetMessage函数体如下:

BOOL GetMessage(
            LPMSG lpMsg,              // 消息结构体指针,返回消息信息 
            HWND hWnd,                // 窗口句柄 ,通常设为NULL
           UINT wMsgFilterMin,        // 消息过滤最小值 
           UINT wMsgFilterMax         // 消息过滤最大值,如果都设置为0,函数将获取所有范围的消息。即取所有消息队列
     ); 

GetMessage函数只有在接收到WM_QUIT消息时,才返回0。-1,获取消息失败。其他,获取成功。
消息队列为空时,GetMessage会一直等待。

8、窗口过程与响应消息

LRESULT CALLBACK MyWndProc(
  HWND hwnd,             // handle to window
  UINT uMsg,             // message identifier
  WPARAM wParam,         // first message parameter
  LPARAM lParam          // second message parameter
)
//LRESULT:从窗口程序或者回调函数返回的32位值
{
     switch (uMsg)    
	{
	     case WM_PAINT:                  //WndProc处理的第二个消息为WM_PAINT。当窗口显示区域的一部分显示内容或者全部变为“无效”,以致于必须“更新画面”时,将由这个消息通知程序
	     //如,有两个窗口:A和B,B在A的上面,并遮住了A的一部分,那么A的被遮住的这部分就叫做A的无效区域,这种情况是由于有个实际存在的窗口遮住产生了无效区域
	     //但有的时候没有实际窗口,但为了重绘就手动使某区域无效,也就是InvalidiRect(),这便是“使窗口无效”的概念
         case WM_KEYDOWN:                //按键消息
         case WM_LBUTTONDOWN:            //该消息当用户在window客户区域点击鼠标左键的时候发送default: 
             return DefWindowProc(hwnd,uMsg,wParam,lParam);
             //将不感兴趣的、不需要我们处理的消息,交还给Windows操作系统为我们处理
    }
    return 0;
}

9、MessageBox

显示一个消息对话框,消息框返回一个整数值,该值指示用户单击了哪个按钮

int WINAPI MessageBox(
 
	HWND hWnd,
 
	LPCSTR lpText,             //指向消息消息框内容
 
	LPCSTR lpCaption,          //指向消息框标题
 
	UINT uType);               //指定一个决定对话框的内容和行为的位标志集,此参数可以为下列标志组中标志的组合。指定下列标志中的一个来显示消息框中的按钮以及图标

按钮:
在这里插入图片描述
图标:
在这里插入图片描述
形态:
在这里插入图片描述
其他:
在这里插入图片描述

10、win32 application实例

#include<stdio.h>
#include<windows.h>
//------------------------------------------------------------
LRESULT CALLBACK MyWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);//回调函数声明
//------------------------------------------------------------
int WINAPI WinMain(
	HINSTANCE hInstance,          // 当前应用程序实例句柄
	HINSTANCE hPrevInstance,      // 永远为NULL
	LPSTR lpCmdLine,              // 命令行参数
	int nCmdShow)                 // 窗口显示时的状态
{
	//MessageBox(NULL,lpCmdLine,"命令行参数",0);//MessageBox 弹出窗口展示消息
	WNDCLASS MyWnd;
	MyWnd.style=CS_HREDRAW|CS_VREDRAW;
	//CS_HREDRAW:当窗口水平方向的宽度变化时重绘整个窗口。CS_VREDRAW:当窗口垂直方向的宽度变化时重绘整个窗口
	MyWnd.cbClsExtra=NULL;
	MyWnd.cbWndExtra=NULL;
	MyWnd.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);//返回系统常用画刷,黑色画刷
	MyWnd.hCursor=LoadCursor(NULL,IDC_CROSS);//十字光标
	MyWnd.hIcon=LoadIcon(NULL,IDI_QUESTION);//加载问号图标
	MyWnd.hInstance=hInstance;
	MyWnd.lpfnWndProc=MyWndProc;
	MyWnd.lpszClassName="Hello";
	MyWnd.lpszMenuName=NULL;


	//对设计好的窗口类进行注册
	RegisterClass(&MyWnd);

	//创建窗口
	HWND hWnd;
	hWnd=CreateWindow("Hello","Window编程",WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
	//WS_OVERLAPPEDWINDOW:创建一个拥有各种窗口风格的窗体,包括标题,系统菜单,边框,最小化和最大化按钮等
	//CW_USEDEFAULT:设置窗口大小,位置为默认值
	
	//显示及其更新窗口
	ShowWindow(hWnd,SW_SHOW);//显示,SW_HIDE为隐藏
	UpdateWindow(hWnd);

	//消息循环
	MSG msg;
	while(GetMessage(&msg,NULL,0,0))//从消息队列中获取消息
	{
		TranslateMessage(&msg);//消息解释
		DispatchMessage(&msg);//将消息发送到“窗口过程”
	}

	return 0; 
}//winmain结束

//回调函数
LRESULT CALLBACK MyWndProc(
	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 name[20];
		sprintf(name,"Char is %d",wParam);
		MessageBox(hwnd,name,"weixin2013",0);
		break;


	case WM_LBUTTONDOWN:
		MessageBox(hwnd,"Mouse Click","weixin2013",0);
		HDC hdc;//设备描述表句柄
		hdc = GetDC(hwnd);//获取一个设备描述表
		TextOut(hdc,0,50,"计算机编程语言学习",strlen("计算机编程语言学习"));
		//0,50是x,y坐标,即设定要显示的文本在窗口中的位置
		ReleaseDC(hwnd,hdc);
		break;


	case WM_PAINT:     //窗口初始化、最小化、最大化、移动窗口、改变窗口尺寸、某些API函数、窗口无效等等
		HDC hDC;
		PAINTSTRUCT ps; //PAINTSTRUCT:结构体,包含了用于绘制窗口客户区的信息
		hDC = BeginPaint(hwnd,&ps);//获取一个设备描述表,重绘窗口
		TextOut(hDC,0,0,"计算机编程",strlen("计算机编程"));
		EndPaint(hwnd,&ps);//将窗口状态重置为有效;删除消息队列中的WM_PAINT消息
		break;


	case WM_CLOSE:
		if(IDYES == MessageBox(hwnd,"是否要关闭?","weixin2013",MB_YESNO))
			DestroyWindow(hwnd);
		break;


	case WM_DESTROY:
		PostQuitMessage(0);
		break;

	case WM_RBUTTONDOWN:
		SendMessage(hwnd,WM_SETTEXT,0,(LPARAM)"hello!");//改变窗口标题名称
		break;

	default:
		return DefWindowProc(hwnd,uMsg,wParam,lParam); 
	}
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值