黑马程序员MFC三天教程-底层窗口实现-vc6.0代码


教程地址:

以下内容来源于网络

在线完整视频: http://yun.itheima.com/course/235.html?2009sjnqq 
网盘完整视频: https://pan.baidu.com/s/1v-WGz4KE48UDT5rmT9E-sw 提取码lty2
配套资料:https://pan.baidu.com/s/1JXqN-ghsf5nbJIyQrGY_1Q 提取码:hguy
MSDN Library的文档,有需要的拿走哦 链接: https://pan.baidu.com/s/1hEh9nd0U2JY_e5jKdC9tkw 提取码: kdvj

VC++ 6.0(SP6)代码:

#include 	//底层实现的窗口的头文件

//6、处理消息(窗口过程)
LRESULT CALLBACK WindowProc(
	HWND hwnd,
	UINT uMsg,
	WPARAM wParam,
	LPARAM lParam
	)
{
	switch (uMsg)
	{
	case WM_CLOSE:
		//所以以xxxWindow为结尾的方法,都不会进入消息队列中,而是直接运行
		DestroyWindow(hwnd);	//DestroyWindow被调用后,发送另一个消息,WM_DESTROY
		break;
	case WM_DESTROY:
		PostQuitMessage(0);	// 0返回给第5步的while循环里的getMessage.
		break;
	case WM_LBUTTONDOWN:	//鼠标左键按下
		{
			int xPos = LOWORD(lParam);
			int yPos = HIWORD(lParam);

			char buf[1024];		//建立数组,存放坐标字符串
			wsprintf(buf, TEXT("x = %d, y = %d"), xPos, yPos);

			MessageBox(hwnd,buf, TEXT("鼠标左键按下"), MB_OK);
		}
		break;
	case WM_KEYDOWN:	//键盘
		MessageBox(hwnd, TEXT("键盘按下"), TEXT("键盘按下提示"), MB_OK);
		break;
	case WM_PAINT:
		{
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hwnd, &ps);
			TextOut(hdc,100,100,TEXT("hello"), strlen("hello"));
			EndPaint(hwnd,&ps);
		}
		break;
	}
	
	//返回值默认处理方式
	return DefWindowProc(hwnd,uMsg,wParam,lParam);
}


int WINAPI WinMain(
	HINSTANCE hInstance,	//应用程序实例句柄
	HINSTANCE hPrevInstance,	//上一个应用程序句柄,在Win32环境下,参数一般为NULL,不起作用
	LPSTR lpCmdLine,	//char * argv[]
	int nShowCmd	//显示命令:最大化、最小化、正常(居中)
	)
{
	//1.设计窗口
	//2.注册窗口
	//3.创建窗口
	//4.显示和更新
	//5.通过循环取消息
	//6.处理消息(窗口过程)

	HWND hwnd;
	MSG msg;

	//1.设计窗口
	WNDCLASS wc;
	wc.cbClsExtra = 0; //类的额外内存
	wc.cbWndExtra = 0; //窗口额外内存
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置背景
	//视频教程中是 LoadCursor(NULL, IDC_HAND),但VC6.0中没有HAND,所以随便选个CROSS(十字)代替
	//LoadCursor具体包含哪些光标,可以在LoadCursor单词位置鼠标右键“转到LoadCursor定义”
	//然后按Ctrl+F组合键,搜索IDC关键字即可看到支持的光标
	wc.hCursor = LoadCursor(NULL, IDC_CROSS); //设置光标,如果第一个参数为NULL,代表使用系统提供的
	wc.hIcon = LoadIcon(NULL, IDI_ERROR); //设置图标,如果第一个参数为NULL,代表使用系统提供的
	wc.hInstance = hInstance; //应用程序实例句柄,传入WinMain中的形参即可
	wc.lpfnWndProc = WindowProc; //回调函数,处理消息(窗口过程)
	wc.lpszClassName = TEXT("WIN");  //指定窗口类型名称
	wc.lpszMenuName = NULL; //菜单名称
	wc.style = 0;  //显示风格 0代表默认风格

	//2.注册窗口类
	RegisterClass(&wc);  //设计好的窗口类,放到注册类里

	//3.创建窗口
	/*
	lpClassName,	//窗口类名
	lpWindowName,	//标题名
	dwStyle,		//非客户区风格,WS_OVERLAPPEDWINDOW
	x,				//坐标x,默认值CW_USEDEFAULT,系统决定
	y,				//坐标y,默认值CW_USEDEFAULT,系统决定
	nWidth,			//窗体宽度,默认值CW_USEDEFAULT,系统决定
	nHeight,		//窗体高度,默认值CW_USEDEFAULT,系统决定
	hWndParent,		//父窗口,没有,NULL
	hMenu,			//菜单,没有,NULL
	hInstance,		//实例句柄,WinMain传入的形参
	lpParam			//附加值,NULL
	*/

	// hwnd是接受CreateWindow创建后的返回句柄(返回值)
	//HWND hWnd;	// 视频教程中写在此处,但VC6.0中需要将声明放最前面
	hwnd = CreateWindow(	
	wc.lpszClassName,
	TEXT("windows"),
	WS_OVERLAPPEDWINDOW,
	CW_USEDEFAULT,
	CW_USEDEFAULT,
	CW_USEDEFAULT,
	CW_USEDEFAULT,
	NULL,
	NULL,
	hInstance,
	NULL
	);

	//4.显示和更新窗口
	ShowWindow(hwnd, SW_SHOWNORMAL);
	UpdateWindow(hwnd);

	//5.循环取窗口接收到的消息
	/*
	HWND        hwnd;		//产生消息的窗口句柄
    UINT        message;	//具体消息的名称
    WPARAM      wParam;		//附加消息,键盘按键消息
    LPARAM      lParam;		//附加消息,鼠标按键消息
    DWORD       time;		//消息产生时间
    POINT       pt;			//附加消息,鼠标坐标位置消息
	*/
	//MSG msg;   // 视频教程中写在此处,但VC6.0中需要将声明放最前面

	//while (1)
	while (GetMessage(&msg,NULL,0,0))	//优化,直接把退出条件写到while里,这样就不用if去判断
	{
		/*
		LPMSG lpMsg,		//消息
		HWND hWnd ,			//捕获窗口,填NULL代表捕获所有的窗口
		UINT wMsgFilterMin,	//最大和最小的过滤消息,一般填0
		UINT wMsgFilterMax	//填0代表捕获所有消息
		*/
		//if(GetMessage(&msg,NULL,0,0) == FALSE )
		//{
		//	break;
		//}

		//翻译组合键消息,翻译后重新放到列队中,等待DispatchMessage分发
		TranslateMessage(&msg);
		
		//不为false 
		//分发消息
		DispatchMessage(&msg);

	}



	return 0;
}  

注意:VC++6.0代码和教程中代码,因编译器版本不同,有两处不一样地方.

  1.教程中是 LoadCursor(NULL, IDC_HAND),但VC6.0中没有HAND,所以随便选个CROSS(十字)代替.

  2.HWND hwnd; 和 MSG msg; 定义必须写到离 "{"  (左花括号)最近的地方,也就是尽量写花括号里的代码第一行,否则编译报错。

     3.教程中,老师使用的是VS2013版本编译器

编译执行,效果图: