Day1:手写第一个Win32程序

news2024/10/7 11:30:13

学习重点:

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;
}

运行结果:

手写一个窗口类的思路

  1. 设计一个窗口类
  2. 注册窗口类
  3. 创建窗口
  4. 显示以及更新窗口
  5. 消息循环

关于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++空项目,程序完成之后,需要修改项目的属性,共计有两处。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/573099.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3 集成kindeditor研究

kindeditor虽然老&#xff0c;但是稳定&#xff0c;最大的好外是word贴进去不变形&#xff0c;后端部分有安全隐患&#xff0c;我给去掉了&#xff0c;只保留了前端&#xff0c;集成jquery添加了跨域ajax上传功能。 用iframe引用实属无奈&#xff0c;因为尝试了好多次用ts封装都…

如何在华为OD机试中获得满分?Java实现【快速开租建站】一文详解!

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Java华为OD机试真题(2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述4. Java算法源码5. 测试6.解题思路1. 题目描述 当前IT部门支撑了子公司…

【2023年电工杯竞赛】B题 人工智能对大学生学习影响的评价 数学建模方案和python代码

1 题目 B题 人工智能对大学生学习影响的评价 人工智能简称AI&#xff0c;最初由麦卡锡、明斯基等科学家于1956年在美国达特茅斯学院开会研讨时提出。 2016年&#xff0c;人工智能AlphaGo 4:1战胜韩国围棋高手李世石&#xff0c;期后波士顿动力公司的人形机器人Atlas也展示了…

【PICO G2 4K】 + 【Unity2020.3.40】 :Android 发布设置

一、【设备】设置 设备开始USB调试模式&#xff0c;然后用usb线连接到电脑&#xff0c;识别后下拉框会显示该设备 二、【脚本调试】的Debug设置 如果要在PICO上读取脚本的Debug信息&#xff0c;则需要开启下图中选项&#xff0c;并配置adb工具读取log日志。 参考之前的blog…

学了两个多月软件测试,顺利过了试用期,拿到12K的我很满足了

先介绍一下&#xff0c;我是机械专业的&#xff0c;在一个大厂做售后工程师&#xff08;就是修东西的&#xff09;&#xff0c;做了几年没啥成绩&#xff0c;年龄越大&#xff0c;心里压力也越大&#xff0c;而且这种大型设备维修很容易出事故&#xff0c;就想着搞一门好点的技…

软件测试面试题【内附超详细面试宝典】

一般软件测试的面试分为三轮&#xff1a;笔试&#xff0c;HR面试&#xff0c;技术面试。 前两轮&#xff0c;根据不同企业&#xff0c;或有或无&#xff0c;但最后一个技术面试是企业了解你“行不行”的关键环节&#xff0c;每个企业都会有的。 在平时的学习、工作中一定要善…

《Zookeeper》从零开始学Zookeeper源码(一)之源码环境搭建

目录 源码环境搭建1. 下载源码2. 编译3. Eclipse启动服务端4. 启动客户端 源码环境搭建 1. 下载源码 下载地址&#xff1a; github 2. 编译 进入下载好的源码的根目录&#xff0c;因为下载依赖的时候需要apache的maven元数据&#xff0c;目前最高的版本为3.8.0-SNAPSHOT&am…

【分享】科大讯飞星火认知大模型(初体验)

前言&#xff1a; 哈喽&#xff0c;大家好&#xff0c;我是木易巷~ 随着人工智能技术的迅猛发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;成为了热门话题。在众多NLP模型中&#xff0c;科大讯飞星火认知大模型成为了一个备受瞩目的新秀&#xff0c;今天我们来了解…

C++中string::npos 的使用

string::npos 的作用 string::npos 的意思:The constant is the largest representable value of type size_type. It is assuredly larger than max_size(); hence it serves as either a very large value or as a special code. 大致意思 是一个常量, 是size_type类型,是一…

策略模式-类型统计

文章目录 前言一、策略模式是什么&#xff1f;二、策略模式应用场景三、策略模式优点四、策略模式缺点五、场景案例&#xff1a;类型统计1.项目结构2.UML图解3.代码实现3.1 指标枚举3.2 请求体3.3 响应体3.4.分析统计指标策略3.5.接口3.6.扩展接口3.7.接口实现3.8.控制层 六、P…

2023年本科应届生,金融转行做数据分析有前景吗?

当然有前景的&#xff0c;尤其是数据分析本身的发展前景是无限的&#xff1b;而作为个人而言&#xff0c;只要你专业技能掌握得好&#xff0c;对于业务的理解分析能力过关&#xff0c;也是非常有发展前景的&#xff0c;尤其是在数据分析人才紧缺的阶段&#xff0c;众多行业领域…

直播预告:聚焦盗号 企业邮件安全的威胁分析与应对

根据Coremail邮件安全人工实验室数据监测&#xff0c;2023年Q1全国企业级用户遭受超过17.45亿次暴力破解&#xff0c;虽然无差别的暴力破解攻击从去年Q4开始有相当幅度的下降趋势&#xff0c;但在今年2-3月&#xff0c;全域暴力破解攻击次数又开始回升。 根据Coremail邮件安全专…

Go 存储系列:Hash存储引擎 Bitcask

Hash 存储引擎 在现代软件系统中&#xff0c;存储和检索数据是一个非常重要的任务。随着数据量的不断增长&#xff0c;如何高效地存储和检索数据变得越来越重要。Hash 存储引擎是一种常见的存储引擎&#xff0c;它可以快速地存储和检索数据。 在本文中&#xff0c;我们将介绍…

深入篇【C++】类与对象:友元函数与友元类

深入篇【C】类与对象&#xff1a;友元函数与友元类 ①.提出问题&#xff1a;重载operator<<②.解决问题&#xff1a;友元Ⅰ.友元函数【特点】 Ⅱ.友元类【特点】 ③.总结问题 ①.提出问题&#xff1a;重载operator<< 如果我们尝试去重载运算符operator<<,你…

【JavaSE】Java基础语法(十八):接口

文章目录 1. 接口的概述2. 接口的特点3. 接口的成员特点4. 类和接口的关系5. 抽象类和接口的关系 1. 接口的概述 接口就是一种公共的规范标准&#xff0c;只要符合规范标准&#xff0c;大家都可以通用。Java中接口存在的两个意义 用来定义规范用来做功能的拓展 2. 接口的特点…

SpringBoot3.0升级遇到关于Invalid bound statement (not found)处理方案

前言 今天升级SpringBoot3时尝试兼容Mybatis和MybatisPlus出现多个异常。顺带写写排查方案&#xff0c;springboot2其实也一样用 排查方向&#xff1a;mapper接口中的方法名和mapper.xml中的id标签不一致 仔细核对抛出异常的接口和xml文件名。方法名排查方向&#xff1a;.map…

基于docker容器化的jenkins2.406升级迁移(jdk8升级jdk11)

查看基础配置 查看jenkins的home路径: 查看磁盘占比: 发现占比比较大的是: 主要子目录&#xff1a; jobs&#xff1a;包含Jenkins管理的构建作业的配置细节、构建产物和数据&#xff1b;logs&#xff1a;Jenkins的日志目录&#xff1b;plugins&#xff1a;包含所有已经安装了…

低代码开发平台助力门店管理创新,提升用户体验

随着信息技术的飞速发展&#xff0c;低代码开发成为了近年来热门的开发方式。同时&#xff0c;在零售业中&#xff0c;门店管理也成为了一个重要的议题。本文将结合低代码开发和门店管理两个主题&#xff0c;探讨如何应用低代码技术优化门店管理。 一、门店管理的挑战 门店管…

Ansible从入门到精通【二】

大家好&#xff0c;我是早九晚十二&#xff0c;目前是做运维相关的工作。写博客是为了积累&#xff0c;希望大家一起进步&#xff01; 我的主页&#xff1a;早九晚十二 专栏名称&#xff1a;Ansible从入门到精通 立志成为ansible大佬 文章目录 ansible常用命令ansibleansible-d…

Revit幕墙:用幕墙巧做屋面瓦及如何快速幕墙?

一、Revit中用幕墙巧做屋面瓦 屋面瓦重复性很高&#xff0c;我们如何快速的创建呢?下面我们来学会快速用幕墙来创建屋面瓦的技巧。 1.新建“公制轮廓-竖挺”族&#xff0c;以此来创建瓦的族(以便于载入项目中使用) 2.在轮廓族中绘制瓦的轮廓(轮廓需要闭合)&#xff0c;将族名称…