<Win32_1>深入浅出windows消息机制

上学期学习了Java ,感觉Java写一个窗口真心简单,很易上手,也就难怪很多开发人员选择Java作为自己的开发编程语言。但是由于自身对windows的热爱,让我觉得c、c++语言才是我亲睐的编程语言,虽然难度大些,但是这才能体现能力所在。其实之前一直想自学一下win32,但是由于时间的显示和种种原因而耽搁了,于是今年暑假决心深入学习win32。

在学习过程中呢,我会在此留下自己的学习心得,当做自己的笔记。初学者可以借鉴,高手可以多多指教,呵呵……

好了,今天开始做第一课的笔记吧:

学习Win32最好是对windows操作系统有较为深入的理解,这样才能学得深入、扎实。因此学习Win32的第一步就是了解windows

操作系统的消息机制,这个可是重中之重

首先上一张自己亲手绘制的图,能很清晰地表示windows消息机制的工作原理

也许你初次看到这张图,感觉密密麻麻的,不是很懂,别担心,我将逐步讲解:

(1) 数字1箭头: 表示windows(os)将消息传递到应用程序的消息队列中

(2) 数字2箭头: 表示应用程序通过消息循环在消息队列中读取消息

(3) 数字3箭头: 表示应用程序的消息循环将读取到的消息告诉给windows(os)

(4) 数字4箭头: 表示windows(os)通过应用程序传递的消息来调用应用程序绑定的回调函数(WndProc) , 根据回调函数 , 来确定是否做出响应

到这里,想必你能从本质上了解到windows的消息机制了吧

讲程序终究和代码脱不了关系,下面我借用一下P先生(Charles Petzold)的第一个例子(HelloWin.c),不过里面包含了我自己的东西,你一看就知道了:

//windows程序的基础代码
#include<windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//回调函数声明

int WINAPI WinMain(HINSTANCE hInstance,		// 程序的当前实例句柄
				   HINSTANCE hPrevInstance, // 程序的上一个实例句柄 , 在win32程序中 , 它始终是NULL
                   PSTR szCmdLine,			// 命令行
				   int iCmdShow)			// 窗口显示状态
{
	static	TCHAR	szAppName[] = TEXT("HelloWin");	//以'\0'字符结尾的字符串 , 这里是程序的名称(实际用作后面的窗口类的名字)
	HWND			hwnd;							//窗口句柄
	MSG				msg;							//消息结构体
	WNDCLASS		wndclass;						//窗口类
	
	wndclass.style			= CS_HREDRAW | CS_VREDRAW;				//窗口类的风格
	wndclass.lpfnWndProc	= WndProc;								//窗口类绑定的回调函数(也称为窗口过程)
	wndclass.cbClsExtra		= 0;									//窗口类额外参数(默认为0)
	wndclass.cbWndExtra		= 0;//窗口类额外参数(默认为0)	
	wndclass.hInstance		= hInstance;							//程序的当前实例句柄 , 绑定到窗口类中
	wndclass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);		//加载程序图标
	wndclass.hCursor		= LoadCursor(NULL, IDC_ARROW);			//加载光标
	wndclass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_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,					//窗口类的名字
						TEXT("The Hello Program"),	//窗口名称(标题栏显示的内容)
						WS_OVERLAPPEDWINDOW,		//窗口的风格
						CW_USEDEFAULT,				//窗口x坐标
						CW_USEDEFAULT,				//窗口y坐标
						CW_USEDEFAULT,				//窗口宽度
						CW_USEDEFAULT,				//窗口长度
						NULL,						//父窗口句柄
						NULL,						//菜单句柄
						hInstance,					//程序的当前实例
						NULL);						//窗口创建数据

	/* 程序运行完CreateWindow , 还没运行ShowWindow时 , 
	windows向窗口的WndProc发送了第一条消息: WM_Create */

	ShowWindow(hwnd, iCmdShow);	//显示窗口
	UpdateWindow(hwnd);			//更新窗口
	/* 运行完UpdateWindow后 , windows向窗口的WndProc
	发送了第二条消息: WM_PAINT . 如果ShowWindow没有调用或是调用失败 , WM_PAINT消息是不会发送的*/
	
	//消息循环
	while(GetMessage(&msg, NULL, 0, 0))//这里的NULL不能写成hwnd , 否则程序不能正常运行
	{
		TranslateMessage(&msg);//转换键盘消息
		DispatchMessage(&msg);//将消息传送给windows(os) , 由windows来回调
	}
	
	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:
	  //PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;//播音
	  return 0 ;

	//窗口客户区重绘消息
	case WM_PAINT:
		PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;//播音
		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对于消息的默认处理
	//(注意: 第三个和第四个参数不能传递错误!!!)
}


没错,我逐行注释了,这样我觉得很好,对于掌握和理解是很有帮助的,ni不放试试……

好了,今天到此为止吧,下次继续了^_^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值