学习重点:
1. 理解这个Win32窗口程序的实现逻辑
2. 学习Windows消息循环机制
3. 了解Windows的数据类型
4. 明白Winmain函数的作用
首先这个Winodws窗口程序在之后的学习并不需要进行手写,这里的重点是学习代码的逻辑,虽然有一些参数的含义尚且不明白,但是可以通过官方文档进行查询,而且这也不是关注的重点,因为一般情况下这些参数的值是不会变的。
代码
//dos main
//
//目的:窗口程序
//1 掌握 C++ 面向对象思想 2 理解消息机制 3 多态性
#include <windows.h>
#include <stdio.h>
LPCTSTR clsName = "My";
LPCTSTR msgName = "欢迎学习";
LRESULT CALLBACK MyWinProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter word
LPARAM lParam // second message parameter long
);
// a 设计一个窗口类 b 注册窗口类 c 创建窗口 d 显示以及更新窗口 e 消息循环
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmdr
)
{
//a 设计一个窗口类
// 1 定义和配置窗口对象 WNDCLASS的本质其实是一个结构体
WNDCLASS wndcls;
wndcls.cbClsExtra = NULL;
wndcls.cbWndExtra = NULL;
wndcls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndcls.hCursor = LoadCursor(NULL, IDC_ARROW);
wndcls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndcls.hInstance = hInstance;
//定义交互响应
wndcls.lpfnWndProc = MyWinProc;//回调
//定义窗口代号
wndcls.lpszClassName = clsName;
wndcls.lpszMenuName = NULL;
wndcls.style = CS_HREDRAW | CS_VREDRAW;
// b 注册窗口类
RegisterClass(&wndcls);
//c 创建窗口
HWND hwnd;
hwnd = CreateWindow(clsName, msgName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance,
NULL);
//d 显示和刷新窗口
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);
//e 消息循环 GetMessage 只有在接收到 WM_QUIT 才会返回 0
//TranslateMessage 翻译消息 WM_KEYDOWN 和 WM_KEYUP 合并为 WM_CAHR
// 这里写成一个死循环
MSG msg;
while (GetMessage(&msg, NULL, NULL, NULL))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK MyWinProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter word
LPARAM lParam // second message parameter long
)
{
//uMsg 消息类型
int ret;
HDC hdc;
switch (uMsg)
{
case WM_CHAR:
char szChar[20];
sprintf_s(szChar, "您刚才按下了: %c", wParam);
MessageBox(hwnd, szChar, "char", NULL);
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd, "检测鼠标左键按下", "msg", NULL);
break;
case WM_PAINT:
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 0, 0, "www.baidu.com", strlen("www.baidu.com"));
EndPaint(hwnd, &ps);
MessageBox(hwnd, "重绘", "msg", NULL);
break;
case WM_CLOSE:
ret = MessageBox(hwnd, "是否真的结束?", "msg", MB_YESNO);
if (ret == IDYES)
{
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
运行结果:
手写一个窗口类的思路
- 设计一个窗口类
- 注册窗口类
- 创建窗口
- 显示以及更新窗口
- 消息循环
关于Winodws的数据类型
Unicode 是世界通用的字符编码标准,使用 16 位数据表示一个字符,一共可以表 示 65535 种字符。
ASNI 字符集,使用 8 位数据或将相邻的两个 8 位的数据组合在一起表示特殊的语 言字符。如果一个字节是负数,则将其后续的一个字节组合在一起表示一个字符。 这种编码方式的字符集也称作“多字节”字符集。
DWORD 32 字节无符号整型数据
DWORD32 32 字节无符号整型数据
DWORD64 64 字节无符号整型数据
HANDLE 对象的句柄,最基本的句柄类型
HICON 图标的句柄
HINSTANCE 程序实例的句柄
HKEY 注册表键的句柄
HMODULE 模块的句柄
HWND 窗口的句柄
INT 32 位符号整型数据类型
INT_PTR 指向 INT 类型数据的指针类型
INT32 32 位符号整型
INT64 64 位符号整型
LONG32 32 位符号整型
LONG64 64 位符号整型
LPARAM 消息的 L 参数
WPARAM 消息的 W 参数
LPCSTR Windows,ANSI,字符串常量
LPCTSTR 根据环境配置,如果定义了 UNICODE 宏,则是 LPCWSTR 类型,否则是 LPCSTR 类型
LPCWSTR UNICODE 字符串常量
LPDWORD 指向 DWORD 类型数据的指针
LPSTR Window,ANSI,字符串变量
LPTSTR 根据环境配置,如果定义了 UNICODE,则是 LPWSTR 类型,否则是 LPSTR 类型
LPWSTR UNICODE 字符串变量
SIZE_T 表示内存大小,以字节为单位,其最大值是 CPU 最大寻址范围
TCHAR 如果定义了 UNICODE,则为 WCHAR,否则为 CHAR
WCHAR 16 位 Unicode 字符
变量里一些常见前缀的含义:
a 数组 array
b 布尔值 bool
by 无符号字符(字节)
c 字符(字节)
cb 字节计数
rgb 保存颜色值的长整
cx,cy 短整型(计算 x,y 的长度)
dw 无符号长整型
fn 函数
h 句柄
i 整形(integer)
m_ 类的数据成员 memb
n 短整型或整型
np 近指针
p 指针(pointer)
l 长整型(long)
lp 长指针
s 字符串 string
sz 以零结尾的字符串
tm 正文大小
w 无符号整型
x,y 无符号整型(表示 x,y 的坐标
备注:这些东西无需特别记忆,随着之后频繁使用会逐渐记忆下来,而且在VS中通过 Alt + G 就可以查看数据类型得定义,其本质还是C++得基本数据结构。
比如:句柄 HANDLE
它得本质实际上就是一个Void型的指针,其它也是同理。
关于API与SDK
API:Application Programming Interface 应用程序编程接口。
SDK:Software Development Kit 软件开发工具包,一般会包括 API 接口文档,示例文 档,帮助文档,使用手册,相关工具等
关于窗口和句柄
窗口就是屏幕上的一片区域,接收用户的输入,显示程序的输出。可以包含 标题栏,菜单栏,工具栏,控件等。
句柄(handle) (资源的编号,二级指针,门把手),窗口句柄,文件句 柄,数据库连接句柄。
窗口和句柄的关系:
C++窗口类对象与窗口并不是一回事,它们之间惟一的关系是 C++窗口类对 象内部定义了一个窗口句柄变量,保存了与这个 C++窗口类对象相关的那个窗口的 句柄。窗口销毁时,与之对应的 C++窗口类对象销毁与否,要看其生命周期是否结束。但 C++窗口类对象销毁时,与之相关的窗口也将销毁。两者的区别简单来说就是:
- 生命周期 窗口类对象周期 》 窗口
- 窗口类内部定义了 m_wnd
补充:当窗口对象在内存中生成后,会返回一个句柄值,作为标识。
Windows消息循环机制
参考我的博客:Day1:Windows消息循环机制_貌美不及玲珑心,贤妻扶我青云志的博客-CSDN博客
关于需要用到的头文件
Windows.h 是一个Windows操作系统的核心头文件,定义了许多与操作系统相关的函数、数据类型和常量。通过包含 windows.h
头文件,您可以使用其中定义的函数和类型来与 Windows 操作系统进行交互,执行各种系统级操作,如窗口管理、文件操作、进程管理、内存管理等。
可以实现一下功能:
- 窗口和消息处理:包括创建和管理窗口、处理窗口消息、窗口过程等。
- 文件和文件系统:包括文件的创建、读取、写入、删除、重命名等操作,以及路径解析和文件属性获取等。
- 进程和线程:包括进程和线程的创建、终止、同步和通信等操作。
- 内存管理:包括内存的分配、释放、读写等操作,以及虚拟内存管理函数。
- 系统信息和配置:包括获取系统信息、注册表操作、环境变量管理等。
- 网络和通信:包括网络套接字操作、网络协议和通信的相关函数。
#include <stdio.h>
是C语言中用于包含标准输入输出函数的头文件。stdio.h 头文件定义了许多用于输入和输出操作的函数和常量。
关于WinMain函数
Winmain函数是程序的入口点
每个 Windows 程序都包含一个名为 WinMain 或 wWinMain 的入口点函数。
根据官方文档,这是参数的意义:
WinMain函数的意义就是C++程序中的Main函数,程序的起点。
补充
因为我在写这程序的时候是创建的C++空项目,程序完成之后,需要修改项目的属性,共计有两处。