1 手写第一个Win32窗口程序

1 基础概念

  1. 什么是窗口?
    答:窗口就是屏幕上的一片区域,接受用户的输入,显示程序的输出。可以包含标题栏、菜单栏、工具栏以及控件等。
  2. 什么是句柄?
    答: 作为一种管理和操作系统资源的机制,提供了对各种对象和资源的访问能力。通过使用句柄,程序可以与特定的资源进行交互和操作。(资源的编号、二级指针)
  3. 窗口类对象是啥?
    C++窗口类对象与窗口并不是一回事,它们之间惟一的关系是 C++窗口类对象内部定义了一个窗口句柄变量,保存了与这个 C++窗口类对象相关的那个窗口的句柄。窗口销毁时,与之对应的 C++窗口类对象销毁与否,要看其生命周期是否结束。但 C++窗口类对象销毁时,与之相关的窗口也将销毁
  4. 常用的结构体以及函数等
//1.用户提供的基于 Windows 的图形应用程序的入口点
int __clrcall WinMain(// __clrcall是一种调用约定,主要涉及函数参数传递方式、函数参数的压栈顺序等[in]           HINSTANCE hInstance,// 应用程序的当前实例的句柄[in, optional] HINSTANCE hPrevInstance,// 应用程序上一个实例的句柄。 此参数始终为NULL。[in]           LPSTR     lpCmdLine,// 应用程序的命令行,不包括程序名称。[in]           int       nShowCmd// 控制窗口的显示方式。
);//2.窗口结构体
typedef struct tagWNDCLASSA {UINT      style;// 类样式WNDPROC   lpfnWndProc;// 指向窗口过程的指针int       cbClsExtra;// 要根据窗口类结构分配的额外字节数。 系统将字节初始化为零int       cbWndExtra;// 在窗口实例之后分配的额外字节数。 系统将字节初始化为零。HINSTANCE hInstance;// 实例的句柄,该实例包含类的窗口过程。HICON     hIcon;// 类图标的句柄。此成员必须是图标资源的句柄。如果此成员为NULL,则系统会提供默认图标。HCURSOR   hCursor;// 类游标的句柄。 此成员必须是游标资源的句柄。 HBRUSH    hbrBackground;// 类背景画笔的句柄。LPCSTR    lpszMenuName;// 类菜单的资源名称,该名称显示在资源文件中。LPCSTR    lpszClassName;// 指向以 null 结尾的字符串的指针或是原子。
} WNDCLASSA, *PWNDCLASSA, *NPWNDCLASSA, *LPWNDCLASSA;//3.从与应用程序实例关联的可执行文件 (.EXE) 文件中加载指定的游标资源
// 如果函数成功,则返回值是新加载的游标的句柄。如果函数失败,则返回值为 NULL。
HCURSOR LoadCursorA(// DLL或可执行文件(.exe 模块的句柄)包含要加载的游标的文件。// 若要加载预定义的系统游标,请将此参数设置为 NULL。[in, optional] HINSTANCE hInstance,// 如果 hInstance 为非 NULL, 则 lpCursorName 按名称或序号指定游标资源//如果 hInstance 为 NULL, 则 lpCursorName 将指定标识符 (从要加载的预定义系统游标的 IDC_前缀) 开始 [in]           LPCSTR    lpCursorName
);
//4.从与应用程序实例关联的可执行 (.exe) 文件中加载指定的图标资源。
HICON LoadIconA(
// DLL 或可执行文件 (.exe 模块的句柄,) 包含要加载的图标的文件
// 若要加载预定义的系统图标,请将此参数设置为 NULL[in, optional] HINSTANCE hInstance,// 如果hInstance为非NULL,则 lpIconName 按名称或序号指定图标资源。// 如果hInstance为NULL,则 lpIconName 将指定标识符(从要加载的预定义系统图标的IDI_前缀)开始 [in]           LPCSTR    lpIconName
);
//5.检索其中一支股票笔、画笔、字体或调色板的句柄
HGDIOBJ GetStockObject([in] int i
);
//6.注册一个窗口类
ATOM RegisterClassA([in] const WNDCLASSA *lpWndClass// 指向 WNDCLASS 结构的指针
);// 7. 该函数创建一个重叠式窗口、弹出式窗口或子窗口。
// 它指定窗口类,窗口标题,窗口风格,以及窗口的初始位置及大小(可选的)。
// 函数也指该窗口的父窗口或所属窗口(如果存在的话),及窗口的菜单。
HWND WINAPI CreateWindow(_In_opt_  LPCTSTR lpClassName,   // 窗口类名称_In_opt_  LPCTSTR lpWindowName,  // 窗口标题_In_      DWORD dwStyle,         // 窗口风格,或称窗口格式_In_      int x,                 // 初始 x 坐标_In_      int y,                 // 初始 y 坐标_In_      int nWidth,            // 初始 x 方向尺寸_In_      int nHeight,           // 初始 y 方向尺寸_In_opt_  HWND hWndParent,       // 父窗口句柄_In_opt_  HMENU hMenu,           // 窗口菜单句柄_In_opt_  HINSTANCE hInstance,   // 程序实例句柄_In_opt_  LPVOID lpParam         // 创建参数
);//8.设置指定窗口的显示状态
BOOL ShowWindow(// 如果窗口以前可见,则返回值为非零值,若隐藏则为0[in] HWND hWnd,// 窗口的句柄[in] int  nCmdShow// 控制窗口的显示方式
);
// 9。如果窗口的更新区域不为空, UpdateWindow 函数通过向窗口发送 WM_PAINT 消息来更新指定窗口的工作区。 函数绕过应用程序队列,将 WM_PAINT 消息直接发送到指定窗口的窗口过程。 如果更新区域为空,则不发送任何消息。
BOOL UpdateWindow([in] HWND hWnd
);//10.从调用线程的消息队列中检索消息。 函数调度传入的已发送消息,直到已发布的消息可供检索。
BOOL GetMessage([out]          LPMSG lpMsg,// 指向 MSG 结构的指针,该结构从线程的消息队列接收消息信息。[in, optional] HWND  hWnd,// 要检索其消息的窗口的句柄。 窗口必须属于当前线程[in]           UINT  wMsgFilterMin,// 要检索的最低消息值的整数值。[in]           UINT  wMsgFilterMax// 要检索的最高消息值的整数值。
);//11.将虚拟密钥消息转换为字符消息。
BOOL TranslateMessage([in] const MSG *lpMsg// 指向 MSG 结构的指针
);
//12.将消息调度到窗口过程
LRESULT DispatchMessage([in] const MSG *lpMsg// 指向包含消息的结构的指针
);//12.包含来自线程的消息队列的消息信息
typedef struct tagMSG {HWND   hwnd;// 其窗口过程接收消息的窗口的句柄UINT   message;// 消息的标识符WPARAM wParam;// 关于消息的附加信息LPARAM lParam;// 关于消息的附加信息DWORD  time;// 消息的发布时间POINT  pt;// 发布消息时的光标位置DWORD  lPrivate;
} MSG, *PMSG, *NPMSG, *LPMSG;
  1. 消息循环
    a.消息是由事件产生的。
    b.事件:由输入设备触发比如鼠标、键盘等;由窗体控件触发比如button,file菜单;由Windows内部的事件。
    c.消息是事件翻译过来的
    d.消息队列:系统消息队列以及应用程序消息队列。产生的消息首先由Windows系统捕获,放在系统消息队列里,再拷贝到对应的应用程序消息队列。
    e.消息循环:系统为每个应用程序维护一个消息循环,消息循环会不断检索自身的消息队列。来一个消息,就用GetMessage()取出消息。
    在这里插入图片描述

2 基本流程

  1. 设计一个窗口类
// 1 定义和配置窗口信息
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;
// 2 定义交互响应
wndcls.lpfnWndProc = MyWinProc;//回调
// 3 定义窗口代号
wndcls.lpszClassName = (LPCTSTR)"My"; 
wndcls.lpszMenuName = NULL; 
wndcls.style = CS_HREDRAW | CS_VREDRAW;// 每当窗口更改大小时,让应用程序重新绘制工作区的整个内容
  1. 注册窗口类
	// 注册窗口类RegisterClass(&wndcls);
  1. 创建窗口
HWND hwnd; // HWND是唯一标识和操作窗口对象
hwnd = CreateWindow(clsName, msgName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
  1. 显示以及更新窗口
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);
  1. 消息循环
MSG msg; 
while (GetMessage(&msg, NULL, NULL, NULL)) 
{ TranslateMessage(&msg); DispatchMessage(&msg); 
}
  1. 回调函数
LRESULT CALLBACK MyWinProc(HWND hwnd, // 窗口的句柄UINT uMsg, // 消息的标识符 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;
}

3 整体代码以及效果

// 创建第一个win32窗口程序
#include<Windows.h>
#include<stdio.h>LPCTSTR clsName = (LPCTSTR)"My";
LPCTSTR msgName = (LPCTSTR)"欢迎学习";// 声明回调函数
LRESULT CALLBACK MyWinProc(HWND hwnd, // 窗口的句柄UINT uMsg, // 消息的标识符 WPARAM wParam, // first message parameter word LPARAM lParam // second message parameter long 
);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {// a 设计一个窗口类// 1 定义和配置窗口信息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;// 2 定义交互响应wndcls.lpfnWndProc = MyWinProc;//回调// 3 定义窗口代号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, // 窗口的句柄UINT uMsg, // 消息的标识符 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);}
}

效果如下:
在这里插入图片描述

4 Windows数据类型

WORD: 16位无符号整形数据

DWORD: 32位无符号整型数据(DWORD32)

DWORD64: 64位无符号整型数据

INT: 32位有符号整型数据类型

INT_PTR: 指向INT数据类型的指针类型

INT32: 32位符号整型

INT64: 64位符号整型

UINT: 无符号INT

LONG: 32位符号整型(LONG32)

ULONG: 无符号LONG

LONGLONG: 64位符号整型(LONG64)

SHORT: 无符号短整型(16位)

LPARAM: 消息的L参数

WPARAM: 消息的W参数

HANDLE: 对象的句柄,最基本的句柄类型

HICON: 图标的句柄

HINSTANCE: 程序实例的句柄

HKEY: 注册表键的句柄

HMODULE: 模块的句柄

HWND: 窗口的句柄

LPSTR: 字符指针,也就是字符串变量

LPCSTR: 字符串常量

LPCTSTR: 根据环境配置,如果定义了UNICODE宏,则是LPCWSTR类型,否则则为LPCSTR类型

LPCWSTR: UNICODE字符串常量

LPDWORD: 指向DWORD类型数据的指针

CHAR: 8比特字节

TCHAR: 如果定义了UNICODE,则为WCHAR,否则为CHAR

UCHAR: 无符号CHAR

WCHAR: 16位Unicode字符

BOOL: 布尔型变量

BYTE: 字节类型(8位)

CONST: 常量

FLOAT: 浮点数据类型

SIZE_T: 表示内存大小,以字节为单位,其最大值是CPU最大寻址范围

VOID: 无类型,相当于标准C语言中的void

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

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

相关文章

解析云原生与云计算本质区别,别再傻傻分不清楚了!

来源| comparethecloud翻译 | 天道酬勤&#xff0c;责编 | Carol出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;云应用程序是热门话题。很多时候&#xff0c;我们会遇到像云原生应用程序和云计算应用程序这样的术语。首先&#xff0c;很少有人同时使用这两…

阿里开发者招聘节 | 面试题02-04:给定一个二叉搜索树(BST),找到树中第K小的节点

为帮助开发者们提升面试技能、有机会入职阿里&#xff0c;云栖社区特别制作了这个专辑——阿里巴巴资深技术专家们结合多年的工作、面试经验总结提炼而成的面试真题这一次将陆续放出&#xff08;面试题官方参考答案将在专辑结束后统一汇总分享&#xff0c;点此进入答题并围观他…

确认!别再相信Python了! 程序员:就你敢说...

程序员你有没有感觉到&#xff0c;Python最近已经刷屏到爆炸了&#xff1f;细分析Python之所以刷屏&#xff0c;主要是因为人红是非多&#xff0c;在编程界它是一种特殊的存在&#xff0c;有人认为&#xff0c;只有用Python才能优雅写代码&#xff0c;提高代码效率&#xff1b;…

云原生的新思考,为什么容器已经无处不在了

4月24日&#xff0c;中国信息通信研究院主办的首届云原生产业大会在北京举行&#xff0c;在《云原生数字引领未来》的主题演讲中&#xff0c;阿里云容器服务总监易立表示&#xff1a;“云原生不但可以很好的支持互联网应用&#xff0c;也在深刻影响着新的计算架构、新的智能数据…

走近科学,探究阿里闲鱼团队通过数据提升Flutter体验的真相

背景 闲鱼客户端的flutter页面已经服务上亿级用户&#xff0c;这个时候Flutter页面的用户体验尤其重要&#xff0c;完善Flutter性能稳定性监控体系&#xff0c;可以及早发现线上性能问题&#xff0c;也可以作为用户体验提升的衡量标准。那么Flutter的性能到底如何&#xff1f;…

阿里3篇技术论文入选国际顶级会议FAST2020,全球第一!

2月26日&#xff0c;存储行业顶级国际会议FAST2020&#xff08;18th USENIX Conference on File and Storage Technologies&#xff09;在美国圣克拉拉举行&#xff0c;大会公开论文名单显示&#xff0c;阿里巴巴3篇第一作者论文入选&#xff0c;是全球入选数最多的企业。 FAS…

oracle11g linux 日期格式设置

下面的过程把oracle 的日期格式设置成 yyyy-mm-dd hh24:mi:ss(1) 使用 oracle 用户登录(2) 在.bash_profile里增加以下两条环境变量export NLS_LANGamerican_america.ZHS16GBK export NLS_DATE_FORMAT"YYYY-MM-DD HH24:MI:SS" (3) 执行一下"source .bash_profil…

一份还热乎的蚂蚁金服面经(已拿Offer)!附答案!!

本文来自我的知识星球的球友投稿&#xff0c;他在最近的校招中拿到了蚂蚁金服的实习生Offer&#xff0c;整体思路和面试题目由作者——泽林提供&#xff0c;部分答案由Hollis整理自知识星球《Hollis和他的朋友们》中「直面Java」板块。 经历了漫长一个月的等待&#xff0c;终于…

linux RssFile什么含义,什么是RSS

导读RSS 指 Really Simple Syndication(真正简易联合),RSS 的 元素可描述 RSS feed。RSS 元素RSS 的 元素可描述 RSS feed。请看下面这个 RSS 文档&#xff1a;<?xml version"1.0"encoding"UTF-8"?>菜鸟教程首页http://www.runoob.com免费编程教程…

linux CPU、内存、I/O、磁盘等监控统一解决方案

文章目录一、效果图二、软件安装配置2.1. nmon安装2.2. 权限赋予2.3. 脚本制作2.4. 脚本运行三、解析监控文件3.1. 监控文件下载3.2. 解析监控文件3.3. 监控指标总览补充内存计算方式需求背景: 性能测试过程中监控服务器健康(CPU、内存、I/O、磁盘)指标的状态 一、效果图 二、软…

数据科学家常见的5个SQL面试问题

作者 | Alexei Ledenev翻译 | 天道酬勤&#xff0c;责编 | Carol出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;在任何以数据为中心的工作中&#xff0c;对SQL有深刻的理解都是成功的关键&#xff0c;尽管这不是工作中最有趣的部分。事实上&#xff0c;除了…

c语言程序滞留,c语言有个可以使程序延时的语句是什么?

满意答案hsgfzdg99推荐于 2017.09.11采纳率&#xff1a;57% 等级&#xff1a;9已帮助&#xff1a;1169人Sleep函数:功 能: 执行挂起一段时间  用 法: unsigned sleep(unsigned seconds);  注意:  在VC中使用带上头文件#include  在VC中,Sleep中的第一个英文字符为大写的…

从濒临解散到浴火重生,OceanBase 这十年经历了什么?

阿里妹导读&#xff1a;谈及国产自研数据库&#xff0c;就不得不提 OceanBase。与很多人想象不同的是&#xff0c;OceanBase 并非衔着金钥匙出生的宠儿。相反&#xff0c;它曾无人看好、困难重重&#xff0c;整个团队甚至数度濒临解散。 从危在旦夕到浴火重生&#xff0c;Ocean…

两成开发者月薪超 1.7 万、算法工程师最紧缺! | 中国开发者年度报告

整理 | 郭芮 责编 | 唐小引 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; “求知若饥&#xff0c;虚心若愚”——这个原本出自《全球概览》的俳句&#xff0c;因为乔布斯在斯坦福大学毕业演讲中的引用而备受推崇&#xff0c;流传成为 IT 界的至理名言之一。在…

拒绝版权流氓!阿里巴巴重磅发布免费商用字体

UCAN 2019 设计大会在杭州国际博览中心开幕&#xff0c;超过 4000 位来自世界各地的设计师参与了这场阿里巴巴设计举办的盛会。 继去年品牌升级为阿里巴巴设计&#xff08;Alibaba Design&#xff09;后&#xff0c;阿里巴巴经济体设计委员会委员长杨光&#xff08;青云&#…

全站CSRF漏洞

文章目录二、解决方案2.1. 创建CSRF防御统一管理2.2. 创建csrfToken校验2.3. 加密工具类2.4. 查询实战2.5. 添加和更新实战默认guns不支持添加headers的需要添加ax2二、解决方案 2.1. 创建CSRF防御统一管理 package com.gblfy.sys.config.web.csrf;import com.gblfy.base.uti…

AutoML数据增广

DeepAugment是一个专注于数据扩充的自动化工具。 它利用贝叶斯优化来发现针对您的图像数据集定制的数据增强策略。 DeepAugment的主要优点和特点是&#xff1a; 降低CNN模型的错误率(WRN-28-10显示CIFAR10的错误率降低了60%)通过自动化流程可以节省时间比谷歌之前的解决方案—…

基于TensorFlow.js的JavaScript机器学习

Credits: aijs.rocks 虽然python或r编程语言有一个相对容易的学习曲线&#xff0c;但是Web开发人员更喜欢在他们舒适的javascript区域内做事情。目前来看&#xff0c;node.js已经开始向每个领域应用javascript&#xff0c;在这一大趋势下我们需要理解并使用JS进行机器学习。由…

阿里巴巴、支付宝员工都在用的知识管理工具,究竟有何特别?

公司内各部门工作文档难以共享&#xff1f;缺乏高效便捷的团队协作工具&#xff1f;文档放到在线云平台担心安全&#xff1f;…… 2019年4月22日&#xff0c;蚂蚁金服旗下知识创作与分享工具语雀发布“空间功能”。语雀在支持在线文档编写、多人协作、灵活的团队管理和金融级安…

探索处理数据的新方法,8 个重点带你搞懂云数据库——DBaaS(数据库即服务)到底是什么!...

作者| Rohan Wadiwala、Mangesh More翻译 | 天道酬勤&#xff0c;编辑 | Carol出品| CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;在分析的世界中&#xff0c;网站的每次点击都是数据分析的候选对象&#xff0c;显然&#xff0c;这会涉及大量的数据生成。对于海…