【Direct3D11】(一)创建windows窗口
【Direct3D11】(一)创建windows窗口
大鲸鱼锅锅 发表于10个月前
【Direct3D11】(一)创建windows窗口
  • 发表于 10个月前
  • 阅读 11
  • 收藏 0
  • 点赞 0
  • 评论 0

新睿云服务器60天免费使用,快来体验!>>>   

摘要: 在学习Direct3d11之前,我们要创建一个windows窗口用来显示我们的Direct3d程序。这里讲了windows窗口创建的过程,以及一个封装类。

Windows窗口的创建过程#

  • 填充窗口类
    WNDCLASS wc;                                            //窗口类
	wc.style = CS_HREDRAW | CS_VREDRAW;              //CS_HREDRAW:当水平长度改变或移动窗口时,重画整个窗口  
                                                     //CS_VREDRAW: 当垂直长度改变或移动窗口时,重画整个窗口
                                                     //其他选项查阅文档
	wc.cbClsExtra = 0;                               //窗口类无扩展
	wc.cbWndExtra = 0;                               //窗口实例无扩展
	wc.lpszClassName = L"D3DAppWindow";             //窗口类名称为D3DAppWindow
	wc.lpszMenuName = nullptr;                            //窗口菜单名称
	wc.hbrBackground = static_cast<HBRUSH>(GetStockObject(NULL_BRUSH));    //窗口背景色
	wc.hCursor = LoadCursor(0, IDC_ARROW);        //窗口鼠标为箭头光标
	wc.hIcon = LoadIcon(0, IDI_APPLICATION);        //窗口最小化图标为缺省图标
	wc.hInstance = m_hAppInstance;                    //这个为应用程序的实例句柄
	wc.lpfnWndProc = MainWndProc;                    //回调函数指针
  • 注册窗口类
    if (FAILED(RegisterClass(&wc)))                    //将填充好的窗口类注册
	{
		MessageBox(nullptr, L"Failed Register Window!", 0, 0);
		return FALSE;
	}
  • 创建窗口实例
    HWND hWnd = CreateWindow(
		L"D3DAppWindow",                    //之前注册的窗口类名称
		L"D3DApp",                          //窗口标题名称,会显示在窗口左上角
		WS_OVERLAPPEDWINDOW,                //窗口的风格
		CW_USEDEFAULT, CW_USEDEFAULT,       //默认窗口左上角坐标
		m_width, m_height,                  //窗口大小
		nullptr,                              //窗口无父窗口
		nullptr,                              //窗口无子菜单
		m_hAppInstance,                     //应用程序的实例句柄
		nullptr                               
	);
  • 显示和更新窗口
    ShowWindow(hWnd, SW_SHOW);                //指定窗口的显示状态(最小化最大化等),SW_SHOW在原位置以原尺寸显示
	UpdateWindow(hWnd);                        //UpdateWindow函数发送一个WM_PAINT消息来更新指定窗口的客户区
                                               //函数绕过应用程序的消息队列,直接发送WM_PAINT消息给指定窗口的窗口过程
  • 游戏主循环
	MSG msg;                                    //消息对象
	ZeroMemory(&msg, sizeof(MSG));                //零初始化消息对象

	while (msg.message != WM_QUIT)                //主循环,没有收到退出消息时循环执行
	{
		if (PeekMessage(&msg, m_hAppWnd, 0, 0, PM_REMOVE))      //以查看的方式从系统中获取消息,处理后,消息从队列里除掉
		{
			TranslateMessage(&msg);                            //该函数将虚拟键消息转换为字符消息,发送至消息队列
			DispatchMessage(&msg);                             //该函数分发一个消息给窗口程序,消息被分发到回调函数
		}
		else
		{
			UpdateScene(0.1f);                        //没有消息时执行游戏场景逻辑
			DrawScene();                             //由D3D绘制场景
		}
	}
  • 一个简单的回调函数
LRESULT WindowBase::MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{ 
    //收到窗口销毁消息时,发送退出信息
	case WM_DESTROY:                       
		PostQuitMessage(0);
		return 0;
	default:
		break;
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);                //调用默认消息处理函数处理大多数消息
}
  • 封装一个游戏的基类
class WindowBase 
{
public:
    WindowBase(HINSTANCE hInstance):m_hAppInstance(hInstance) {}
	~WindowBase() {}
	//获取App的Instance句柄
	HINSTANCE AppInst() const;
	//获取窗口句柄
	HWND AppWindow() const;
	//设置窗口的大小,应在调用Init()初始化窗口之前设置
	void SetHeightAndWidth(int width, int height);

	//主循环
	int Run();

	//回掉函数
	LRESULT MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
	//初始化,在这里调用 InitGameWindow() 和 InitDirect3D()
	virtual bool Init();
	//游戏逻辑更新 必须重写
	virtual void UpdateScene(float dt) = 0;
	//游戏绘制 可以不重写 即不绘制任何东西 只处理游戏逻辑
	virtual void DrawScene();
protected:
    HRESULT InitGameWindow();        //所有注册、创建窗口实例的过程在这里写
	HRESULT InitDirect3D();            //所有初始化Direct3D的过程在这里写
protected:
	HINSTANCE m_hAppInstance = nullptr;
	HWND m_hAppWnd = nullptr;
	int m_height = 800;
	int m_width = 600;
};
  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 5
博文 13
码字总数 15885
×
大鲸鱼锅锅
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: