内核态和用户态的基本概念
创建窗口的七个步骤
(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位的字符串。
效果展示
全部代码
#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
解决办法二
把.c结尾的c文件变为.cpp结尾的C++文件
eg