Window类

Directx3D11入门

Window类,内部类WindowClass单例用于注册,Window创建窗口

myWindow.h
#pragma once
#include<Windows.h>

class Window
{
private:

	class WindowClass//单例设计,用于注册类,
	{
	public:
		static const wchar_t* GetName()noexcept;
		static HINSTANCE GetInstance()noexcept;
	private:
		static WindowClass wndClass;
		HINSTANCE hInst;//当前应用实例句柄

		WindowClass()noexcept;
		~WindowClass();
		WindowClass(const WindowClass&) = delete;
		WindowClass& operator=(const WindowClass&) = delete;
		static constexpr const wchar_t* wndClassName = L"my Window";
	};

public:
	Window(int width, int height, const wchar_t* name)noexcept;
	~Window();
	Window(const Window&) = delete;
	Window& operator=(const Window&) = delete;
private:
    //消息处理的参数列表固定,没有this,所以static,若要该函数中获取该Window实例的指针,使用CreateWindow()的最后的一位参数
	static LRESULT CALLBACK HandleMsgSetup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);//初始化要处理的消息
	static LRESULT CALLBACK HandleMsgThunk(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
	LRESULT HandleMsg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
	int width;
	int height;
	HWND hWnd;
};

myWindow.cpp

#include"MyWindow.h"

Window::WindowClass Window::WindowClass::wndClass;//初始化静态数据成员
Window::WindowClass::WindowClass() noexcept//class "WindowClass" construction,
	:hInst{GetModuleHandle(nullptr)}
{
	WNDCLASSEX wc{ 0 };
	wc.cbSize = sizeof(wc);
	wc.style = CS_OWNDC;
	wc.lpfnWndProc = HandleMsgSetup;//function in class"Window"
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = GetInstance();// member function
	wc.hIcon = nullptr;
	wc.hCursor = nullptr;
	wc.hbrBackground = nullptr;
	wc.lpszMenuName = nullptr;
	wc.lpszClassName = GetName();//member function
	wc.hIconSm = nullptr;
	RegisterClassEx(&wc);
}
Window::WindowClass::~WindowClass()
{
	UnregisterClass(wndClassName, GetInstance());
}

const wchar_t* Window::WindowClass::GetName() noexcept
{
	return wndClassName;
}

HINSTANCE Window::WindowClass::GetInstance() noexcept
{
	return wndClass.hInst;
}

Window::Window(int width, int height, const wchar_t* name) noexcept
	:width{width},height{height}
{
	RECT wr;
	wr.left = 100;
	wr.right = width + wr.left;
	wr.top = 100;
	wr.bottom = height + wr.top;
	AdjustWindowRect(&wr, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, FALSE);//传入客户端矩形区域大小,和窗口风格,计算整个窗口的大小

	hWnd = CreateWindow(
		WindowClass::GetName(), name,
		WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
		CW_USEDEFAULT, CW_USEDEFAULT,
		wr.right - wr.left, wr.bottom - wr.top,
		nullptr, nullptr, WindowClass::GetInstance(), 
		this//this 传入形参lpParam,用于填充结构体“CREATESTRUCT",处理WM_NCCREATE/WM_CREATE消息时,其LParam指向结构体
	);

	ShowWindow(hWnd, SW_SHOWDEFAULT);
}

Window::~Window()
{
	DestroyWindow(hWnd);
}

LRESULT CALLBACK Window::HandleMsgSetup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)//初始化要处理的消息
{
	if (msg == WM_NCCREATE)//在WM_CREATE之前,即在“CreateWindowEx”函数,之前,产生此消息,wParam未使用,LParam是CREATESTRUCT的对象的指针,结构体包含窗口信息(其与创建window时传入的信息相同)
	{
		const CREATESTRUCTW* const pCreate = reinterpret_cast<CREATESTRUCTW*>(lParam);
		//该结构体的lpCreateParams参数,实际为"CreateWindow"的"lpParam"所传入的this,目的是窗口实例与Win消息处理机制关联起来
		Window* const pWnd = static_cast<Window*>(pCreate->lpCreateParams);			
		//该函数允许:修改WINAPI端的数据,这里选用GWLP_USERDATA功能,允许存储自定义用户数据,存入Window类对象
		SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pWnd));	
		//修改了消息处理函数,让消息经由"HandleMsgThunk"处理,停止使用"HandleMsgSetup"处理消息,
		SetWindowLongPtr(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&Window::HandleMsgThunk));
		return pWnd->HandleMsg(hWnd, msg, wParam, lParam);
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}

LRESULT CALLBACK Window::HandleMsgThunk(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	//获取Window类的指针,
	Window* const pWnd = reinterpret_cast<Window*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
	return pWnd->HandleMsg(hWnd, msg, wParam, lParam);
}

LRESULT Window::HandleMsg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_CLOSE:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}



WinMain.cpp

#include "MyWindow.h"

int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
	Window wnd(800, 300, L"Box");
	MSG msg;
	BOOL getResult;
	while ((getResult = GetMessage(&msg, nullptr, 0, 0)) > 0)
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	if (getResult == -1)
	{
		return -1;
	}
	else
	{
		return msg.wParam;
	}
}

WindowClass包含它的一个静态成员,程序运行,就会产生该对象,且只能一次,
在其构造函数,完成窗口类的注册,析构时,取消注册。
需要Window中的 消息处理函数,

Window包含成员width,height,hWnd(该窗口的句柄),
在构造函数,CreateWindow() 和 ShowWindow() 
需要WindowClass: 注册的类名,
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值