底层窗口的实现

这篇博客其实只是了解,没必要完全理解并搞清楚每一个步骤的含义:

1.首先了解一下什么叫 句柄:句柄是整个Windows编程的基础。一个句柄是指使用的一个唯一的整数值,即一个4字节(64位程序中为8字节)长的数值,来标识应用程序中的不同对象和同类对象中的不同的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。应用程序能够通过句柄访问相应的对象的信息。

2.下载MSDN软件并学会如何查找函数参数和作用

解释在代码中:

# include <windows.h> //底层实现窗口的文件
//6.处理窗口过程     此过程可先跳过   是最后一步
LRESULT CALLBACK WindowProc(
	HWND hwnd,           //消息所属的窗口句柄
	UINT uMsg,               //具体消息名称  WM_XXXXX
	WPARAM wParam,            //键盘附加消息
	LPARAM lParam)          //鼠标附加消息
{
	switch (uMsg)   //判断具体的消息名称
	{
	//一下俩个case是相关联的,第一个处理后的结果交给第二个才能退出窗口
	case WM_CLOSE:
		DestroyWindow(hwnd);//DESTROYWIDON发送另一个消息  WM_DESTROY
	case WM_DESTROY:
		PostQuitMessage(0);   //退出窗口
		break;
	case WM_LBUTTONDOWN:
	{
		int xpoint = LOWORD(lParam);  //鼠标附加消息
		int ypoint = HIWORD(lParam);
		char buf[1024];
		wsprintf(buf,TEXT("x=%d,y=%d"),xpoint,ypoint);
		MessageBox(hwnd, TEXT("WINDOWS"), TEXT("鼠标按下"), MB_OK);  //MessageBoxe的功能是实现一种小型窗口,以后我会有实例
	}
	}
	//返回值用默认的处理方式
	return DefWindowProc(hwnd, uMsg, wParam, lParam);  //就是结构体的成员
};

//程序入口函数

//WINAPI 代表__stdcall 参数得到传递顺序,从右到左,依次入栈,并且在函数返回前清空栈
int WINAPI WinMain(
	HINSTANCE hInstance,           //应用程序句柄  
	HINSTANCE hPrevInstance,         //上一个应用程序句柄,在win32环境下,参数一般为NULL,不起作用
	LPSTR lpCmdLine,                    //char *argv[] ,可以不用管,我也是照搬的
	int nShonwCmd)                    //显示命令,最大化,最小化,正常,可以利用MSDN软件查找nShonwCmd 里边有窗口的类型
{
                //窗口实现的六个步骤
	//1,设计窗口
	//2。注册窗口
	//3.创建窗口
	//4.显示和更新
	//5.通过循环取消息
	//6.处理消息(窗口过程)

	//1.设计窗口
	WNDCLASS wc;   //定义一个窗口类对象
                //以下两个不需了解
	wc.cbClsExtra = 0;       //类的额外的内存
	wc.cbWndExtra = 0;           //窗口的额外的内存
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);    //设置背景,HBRUSH是一种画刷类型,把GetStockObject()返回值强制类型转化,其中GetStockObject参数多种多样,在MSDN中都可以找到
	wc.hCursor = LoadIcon(NULL, IDI_HAND);    //设置光标,如果第一个参数为NULL,代表使用系统提供的光标
	wc.hInstance = hInstance;          //应用程序实例句柄 ,传入WinMain中的形参即可
	wc.lpfnWndProc=WindowProc;              回调函数  窗口过程
	wc.lpszClassName = TEXT("WIN");          //指定窗口类名称
	wc.lpszMenuName = NULL;                 //菜单名称
	wc.style = 0;               //0代表默认风格

	//2.注册窗口
	RegisterClass(&wc);

	//3.创建窗口
                //CreateWindow的九个参数的意义
	/*
	lpClassName,     类名
	lpWindowName,     标题名
	dwStyle,       WS_OVERLAPPEDWINDOW 风格
	x, y,\    显示坐标              CW_USEDEFAULT   为默认值
	nWidth, nHeight,             //宽高 默认值
	hWndParent,               父窗口 NULL
	hMenu,        菜单NULL
	hInstance,    实例句柄
	lpParam      附加值,鼠标附加值
	*/

	//返回句柄类型
	HWND hwnd = CreateWindow(wc.lpszClassName, TEXT("WINDOWS"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

	//4.显示和更新

	ShowWindow(hwnd, SW_FORCEMINIMIZE);
	UpdateWindow(hwnd);

	//5.通过循环取消息

	/*
	HWND        hwnd;     主窗口句柄
	UINT        message;   具体消息名称
	WPARAM      wParam;    键盘消息
	LPARAM      lParam;    鼠标消息
	DWORD       time;      消息产生时间
	POINT       pt;    鼠标附加消息  x,y  位置消息
	*/

	//MSG为一个结构体

	MSG msg;

	while (true) {
	GetMessage的参数解释:
		/*
	 _Out_ LPMSG lpMsg,  消息
	_In_opt_ HWND hWnd,    捕获窗口 填NULL,代表捕获所有的窗口
	_In_ UINT wMsgFilterMin,  最小和最大的过滤信息,一般填入0
	_In_ UINT wMsgFilterMax);  填0代表捕获所有信息
		*/
		if (GetMessage(&msg, NULL, 0, 0) == FALSE) {
			break;
		}

		//翻译消息
		TranslateMessage(&msg);

		//不为false
		//分发消息

		DispatchMessage(&msg);
	}

	//6.处理消息 窗口过程,写在了开头
	system("pause");
	return 0;
}


 

发布了37 篇原创文章 · 获赞 12 · 访问量 9273

猜你喜欢

转载自blog.csdn.net/weixin_43265881/article/details/89380557