win32创建自定义窗口类

在创建窗口时不能每一次都对各种参数进行设定,这样的话会使代码复杂而且降低开发效率,创建自定义窗口类可以在使用时直接进行实例化,只需要一行代码便可以实现。
以下代码学习此项目https://github.com/planetchili/hw3d
创建自定义窗口类windowst.h

#pragma once
#include <string>
#include <sstream>
#include <windows.h>
#include "ChiliExceptrion.h"
#include "keyboard.h"

#define CHWND_EXCEPT( hr ) window::HrException( __LINE__,__FILE__,(hr) )
#define CHWND_LAST_EXCEPT() window::HrException( __LINE__,__FILE__,GetLastError() )
class window
{
private:
	//单例模式创建实例得实例
	class windowst
	{
	public:
		static const char* getname() noexcept;
		static HINSTANCE getinstance() noexcept;
		static void setname();
	private:
		windowst() noexcept;
		~windowst();
		//delete禁止函数类外调用
		windowst(const windowst&) = delete;
		windowst operator=(const windowst&) = delete;
		static constexpr const char* wndClassname="gfdgfd";
		static windowst sinwindows;
		HINSTANCE hinst;
	};
public:
	window(int width, int height, const char* name) noexcept;
	~window();
	window(const window&) = delete;
	window& operator=(const window&) = delete;
private:
//
	static LRESULT WINAPI HandleMsgSetup(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) noexcept;
	static LRESULT CALLBACK HandleMsgThunk(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) noexcept;
	LRESULT HandleMsg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) noexcept;
private:
	int height;
	int width;
	HWND hwnd;	
	keyboard kbd;
};

windowst.cpp如下所示

#include "windowst.h"
#include "windows.h"
#include "resource.h"

window::windowst window::windowst::sinwindows;
//GetModuleHandle(nullptr)获取当前进程的窗口句柄
window::windowst::windowst() noexcept:hinst(GetModuleHandle(nullptr))
{
	//wndClassname = window::classname;
	WNDCLASSEX wc = { 0 };
	wc.cbSize = sizeof(wc);
	wc.style = CS_OWNDC;
	wc.lpfnWndProc = HandleMsgSetup;//消息处理函数
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = getinstance();
	wc.hIcon = LoadIcon(getinstance(), MAKEINTRESOURCE(IDI_ICON1)); //设置图标
	wc.hCursor = LoadIcon(getinstance(), MAKEINTRESOURCE(IDI_ICON1));
	wc.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
	wc.lpszMenuName = nullptr;
	wc.lpszClassName = getname();
	wc.hIconSm = nullptr;
	RegisterClassEx(&wc);
}
window::windowst::~windowst()
{
	UnregisterClass(wndClassname, getinstance());
}
void window::windowst::setname()
{
	//wndClassname=window::transmsg();
}
const char* window::windowst::getname() noexcept
{
	return wndClassname;
}
HINSTANCE window::windowst::getinstance() noexcept
{
	return sinwindows.hinst;
}
window::window(int width, int height, const char* name)  noexcept
{
	RECT rect;
	rect.left = 100;
	rect.right = width + rect.left;
	rect.top = 100;
	rect.bottom = height + rect.top;
	AdjustWindowRect(&rect, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU, FALSE);
	hwnd = CreateWindow(windowst::getname(), name, WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,CW_USEDEFAULT, CW_USEDEFAULT,
		width,height, nullptr, nullptr, windowst::getinstance(), this);
	ShowWindow(hwnd, SW_SHOWDEFAULT);
}
window::~window()
{
		DestroyWindow(hwnd);
}

LRESULT CALLBACK window::HandleMsgSetup(HWND hwnd, UINT msg, WPARAM wparem, LPARAM lparam) noexcept
{
	//判断是否在非消息区域创建,否则返回默认处理方式
	if (msg == WM_NCCREATE)
	{
		const CREATESTRUCT* const pcreat = reinterpret_cast<CREATESTRUCT*>(lparam);
		//lpCreateParams就是之前创建的this,将窗口实例与winapi关联起来
		window* const pWnd = static_cast<window*>(pcreat->lpCreateParams);
		//把窗口实例数据在winapi方面进行存储
		SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pWnd));
		SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&window::HandleMsgThunk));
		return pWnd->HandleMsg(hwnd, msg, wparem, lparam);
	}
	return DefWindowProc(hwnd, msg, wparem, lparam);
}
LRESULT CALLBACK window::HandleMsgThunk(HWND hwnd, UINT msg, WPARAM wparem, LPARAM lparam) noexcept
{
	window* const pWnd = reinterpret_cast<window*>(GetWindowLongPtr(hwnd,GWLP_USERDATA));
	return pWnd->HandleMsg(hwnd, msg, wparem, lparam);
}
//不能通过winapi函数调用成员函数,因此创建了静态函数,数据是winapi端的userdata中取得的
LRESULT window::HandleMsg(HWND hwnd, UINT msg, WPARAM wparem, LPARAM lparam) noexcept
{
	switch (msg)
	{
	case WM_CLOSE:
		PostQuitMessage(0);
		return 0;
	case WM_KEYDOWN:
		kbd.OnKeyPressed(static_cast<unsigned char> (wparem));
		MessageBox(nullptr, "WM_KEYDOWN", "OnKeyPressed", MB_OK | MB_ICONEXCLAMATION);
		break;
	case WM_KEYUP:
		kbd.OnKeyReleased(static_cast<unsigned char> (wparem));
		MessageBox(nullptr, "WM_KEYUP", "OnKeyReleased", MB_OK | MB_ICONEXCLAMATION);
		break;
	case WM_CHAR:
		kbd.OnChar(static_cast<unsigned char> (wparem));
		MessageBox(nullptr, "WM_KEYUP", "OnChar", MB_OK | MB_ICONEXCLAMATION);
		break;
	}
	return DefWindowProc(hwnd, msg, wparem, lparam);
}

主函数如下所示

int CALLBACK WinMain( HINSTANCE hinstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
	window mywin1(720, 640, "yang1");//创建一个窗口
	window mywin2(720, 640, "yang2");//创建另一个
	MSG msg;
	while (GetMessage(&msg, nullptr, 0, 0) > 0)
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return 0;
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值