内核态和用户态的基本概念

从0开发游戏引擎---从0创建一个窗口_c语言

创建窗口的七个步骤

(1)定义WinMain函数
(2)定义窗口消息处理函数(窗口过程)
(3)注册窗口类
(4)创建窗口
(5)显示窗口
(6)消息循环
(7)消息处理

为什么使用TEXT?

当然,使用Unicode肯定也有某些缺点,首先同时也是最重要的是,程序中的每一一个字符串会占用两倍的空间。此外,你会看到,宽字符运行库函数比正常的函数要大。为此,你可能希望创建两个版本的程序,一个用ASCII码字符串而另一个使用Unicode字符串。
而最好的办法是维护一个单一的源代码文件,但是可以编译ASCII或Unicode.但这是有问题的,因为运行库函数具有不同名称,字符变量不同,还有那个讨厌的在字符换字面之前必须要加的L。

一个答案是使用包含在Microsoft Visual C++中的TCHAR.H头文件。这个头文件并不是ANSIC标准的一部分,所以其中定义的每一个函数和宏都有一个下换线前缀。TCHAR.H为哪些需要字符串参数的普通运行库函数(例如,tprintf和 tcslen) 提供了一系列的替代名称。这些函数有时被称为“通用”的函数名字,因为他们可以指Unicode或非Unicode版本的函数。

如果一个命名为_ UNICODE 的标识符被定义了并且TCHAR.H头文件被包含在你的程序中,tcslen 就被定义为wcslen:#define tcslen wcslen
如果UNICODE并没有被定义,那么_ tcslen 就被定义为strlen:#define_ tcslen strlen
否则的话,TCHAR 就是一个简单的char:typedef char TCHAR;
现在是时候来解决字符串文字中L这一棘手的问题。

如果UNICODE标识符被定义

一个叫_ T的宏是如下定义的:#define _T(x) L##x
这是相当模糊的语法,但它在ANSIC标准的C预处理中。那一对数字符号被称为“令牌粘贴”,它使得字母L和宏参数拼接在一起。因此,如果宏参数是“Hello!" ,那么L##x就是L“Hello!"

如果UNICODE标识符没有被定义

T 宏就简单的如下定义:#define T(x) x
无论如何,其它两个宏是定义成和
T一样的:
#define _T(x) _T(x)
#define _TEXT(x) _T(x)

Win32控制台程序使用哪一种取决于你所需要的简明或详细程序,基本上,必须用下列方式将字符串字面定义在_T 或TEXT 宏内:
_TEXT(“Hello!”)
这样做的结果是,如果UNICODE 标识符被定义了,字符串就被解释
为是由宽字符组成的,如果没有被定义,它则被解释为8位的字符串。

效果展示

从0开发游戏引擎---从0创建一个窗口_c++_02

全部代码

#include <Windows.h>

//第二步定义消息处理函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgId,WPARAM wParam,LPARAM lParam)
{
	//第七步  处理消息
	//switch (msgId)
	//{
	//}
	

	return DefWindowProc(hWnd,msgId,wParam,lParam);
}


//第一步   定义WinMain函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{ 
	//第三步  注册窗口类  两步   第一步设计窗口类   第二步是注册
	//									设计药方         报备
	WNDCLASS wndclass={0};
	//窗口类的附加内存相当于缓冲区  一般为0
	wndclass.cbClsExtra=0;
	//窗口的附加内存相当于缓冲区  一般为0
	wndclass.cbWndExtra=0;
	//获取一个笔刷   作用:填充背景色   选择什么画刷,那么你的窗口背景就是什么颜色
	wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
	//鼠标指针
	wndclass.hCursor=NULL;
	//系统默认的图标
	wndclass.hIcon=NULL;
	wndclass.hInstance= hInstance;
	//消息处理函数(系统调用)
	wndclass.lpfnWndProc=WndProc;
	//给类起一个名字 C++11 c14
	wndclass.lpszClassName=TEXT("Main");
	//菜单  NULL为不要菜单
	wndclass.lpszMenuName=NULL;
	//窗口类的样式   大样式
	wndclass.style=CS_HREDRAW|CS_VREDRAW;

	//注册到系统中   把上面填好的数据写入到系统内核中
	//一般都可以注册成功 
	RegisterClass(&wndclass);


	//第四步  创建窗口    我们通过窗口句柄可以找到我们刚才创建的窗口
	HWND hWnd=CreateWindow(TEXT("Main"),TEXT("MainWindows"),WS_OVERLAPPEDWINDOW,0,0,1024,768,NULL,NULL,hInstance,NULL);

	//第五步  显示窗口
	ShowWindow(hWnd,SW_SHOW);
	UpdateWindow(hWnd);

	//第六步  消息循环  分为三步 第一步:抓取消息  第二步翻译消息  第三步:派发消息
	MSG msg={0};
	//如果给它指定了固定的窗口句柄则只会抓取该窗口的消息
	//写了NULL就是抓本进程的消息
	while(GetMessage(&msg,NULL,0,0))
	{

		TranslateMessage(&msg);

		DispatchMessage(&msg);
	}


	return 0;
}

error C2275:###:将此类型用作表达式非法

错误原因

c的编译器要求将变量的声明放在一个函数块的头部,而c++没有这样的要求造成的

解决办法一

把变量的声明全部放在变量的生存块的开始。

eg

从0开发游戏引擎---从0创建一个窗口_字符串_03

解决办法二

把.c结尾的c文件变为.cpp结尾的C++文件

eg

从0开发游戏引擎---从0创建一个窗口_字符串_04