当前位置: 首页 > news >正文

win32:第一个窗口程序-应用程序入口点(part.6)

第一个窗口程序的最后一部分:应用程序入口函数wWinMain;这是Windows应用程序的主函数,负责初始化应用程序、注册窗口类、创建主窗口并进入消息循环处理消息。

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPWSTR    lpCmdLine,_In_ int       nCmdShow)
{UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);
​// 初始化全局字符串LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);LoadStringW(hInstance, IDC_WINDOWSPROJECT1, szWindowClass, MAX_LOADSTRING);MyRegisterClass(hInstance);
​// 执行应用程序初始化:if (!InitInstance (hInstance, nCmdShow)){return FALSE;}
​HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT1));
​MSG msg;
​// 主消息循环:while (GetMessage(&msg, nullptr, 0, 0)){if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){TranslateMessage(&msg);DispatchMessage(&msg);}}
​return (int) msg.wParam;
}
​
函数声明部分
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPWSTR    lpCmdLine,_In_ int       nCmdShow)

APIENTRY 是一个宏,定义了函数的调用约定;具体来说,APIENTRY 在 Windows 平台上通常定义为 __stdcall__stdcall 是一种调用约定,规定了函数如何接收参数、返回值,以及函数调用时堆栈的清理方式。(这个部分在汇编部分有涉及到,这边再描述一下__stdcall调用约定的一些关键点)

参数传递顺序: 参数从右向左传递(即最后一个参数最先压入堆栈)。
堆栈清理: 函数自身负责清理堆栈。这与__cdecl不同,在__cdecl中,调用者负责清理堆栈。
名称修饰: 在使用__stdcall时,编译器会对函数名进行修饰。这通常包括在函数名前加上一个下划线,并在后面加上@符号和参数的字节数。例如,void MyFunction(int a) 会被修饰为 _MyFunction@4。
应用场景: __stdcall主要用于Win32 API函数以及一些第三方库的接口函数。

接着来说一下程序入口函数的参数列表:

hInstance:是当前应用程序实例的句柄;它是一个唯一标识应用程序的实例,用于加载资源(如图标、字符串、对话框模板等)和其他操作。
hPrevInstance:这是上一个实例的句柄。在 16 位 Windows 中,它用于判断是否已经有一个实例在运行。对于 32 位和 64 位 Windows 应用程序,这个参数总是 NULL,所以一般不需要用它。
lpCmdLine:是指向包含命令行参数的字符串的指针。
nCmdShow:指定应用程序窗口的初始显示状态。这个参数可以有多种值,比如 SW_SHOW、SW_HIDE 等,用于决定窗口是最小化、最大化还是正常显示,通常在创建窗口时传递给 ShowWindow 函数。

在Windows编程中,应用程序的实例(Instance)通常指的是应用程序在内存中的一个运行副本。每个实例都有一个唯一的句柄(HINSTANCE),这是一个标识符,用于区分和管理不同的实例。当你运行一个可执行文件(如 .exe),操作系统会为这个可执行文件分配内存,并启动一个新进程。这个进程就是应用程序的一个实例。你可以同时运行多个相同的可执行文件,每一个运行的进程都是该应用程序的一个实例。

函数体部分
    UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);

UNREFERENCED_PARAMETER 是一个宏,用于标记在函数中未使用的参数。这在编译时避免了未使用参数的警告。这行代码的作用是告诉编译器,这两个参数 hPrevInstancelpCmdLine 在函数体中没有被使用,但这是有意为之,并且这种情况是可以接受的。

在标记未使用的参数后,模板代码就开始从资源文件加载字符串并注册窗口类。

    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);LoadStringW(hInstance, IDC_WINDOWSPROJECT1, szWindowClass, MAX_LOADSTRING);MyRegisterClass(hInstance);

LoadStringW 是一个Win32 API函数,用于从应用程序的资源文件中加载字符串资源;他的原型是

int LoadStringW(HINSTANCE hInstance,UINT uID,LPWSTR lpBuffer,int cchBufferMax
);

hInstance: 应用程序实例的句柄。在这里,它指定了包含字符串资源的模块。

uID: 字符串资源的标识符。在这里,IDS_APP_TITLEIDC_WINDOWSPROJECT1 是资源ID,通常在资源文件(如 .rc 文件)中定义。

lpBuffer: 指向接收加载的字符串的缓冲区。

cchBufferMax: 缓冲区的最大字符数,包括终止的空字符。

LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);:从资源文件中加载ID为 IDS_APP_TITLE 的字符串,并将其存储在 szTitle 缓冲区中。

LoadStringW(hInstance, IDC_WINDOWSPROJECT1, szWindowClass, MAX_LOADSTRING);:从资源文件中加载ID为 IDC_WINDOWSPROJECT1 的字符串,并将其存储在 szWindowClass 缓冲区中。

通过查看项目中的资源文件(.rc)的内容就可以找到载入的字符串是什么

MyRegisterClass(hInstance);接着就是调用自定义的注册窗口类函数,去指定窗口的样式、窗口过程(处理窗口消息的回调函数)、窗口背景色等信息。(part.2)

接着就是需要进行应用程序实例的初始化:这里调用了自定义函数InitInstance;在这个函数中我们会创建实例的主窗口,并根据nCmdShow参数指定程序窗口的显示方式。

 if (!InitInstance (hInstance, nCmdShow)){return FALSE;}

若实例初始化失败,则返回false,如若成功则显示主窗口。在实例初始化成功后加载加速键表(accelerator table),以便在消息循环中处理快捷键。

HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT1));

LoadAccelerators 是一个Win32 API函数,用于加载加速键表。加速键表定义了一组快捷键及其对应的命令,可以用来快捷地执行菜单命令。其原型如下:

HACCEL LoadAccelerators(HINSTANCE hInstance,LPCWSTR lpTableName
);

hInstance: 应用程序实例的句柄,指定包含加速键表的模块。

lpTableName: 指向包含加速键表的资源名称或标识符(通常使用 MAKEINTRESOURCE 宏转换资源ID)。

当前项目的rc文件中的资源设置如下:

这是菜单资源的标识符和类型。IDC_WINDOWSPROJECT1 是菜单的ID,MENU 表示这是一个菜单资源。BEGINEND:这些关键字用于定义菜单的开始和结束部分。

POPUP:POPUP 定义了一个包含子菜单的顶级菜单项:

"文件(&F)""帮助(&H)" 是两个顶级菜单项,它们分别包含一个或多个子菜单项。(&F)(&H) 是快捷键,按下 Alt+FAlt+H 可以打开相应的菜单。

MENUITEM:MENUITEM 定义了一个具体的菜单项:

"退出(&X)", IDM_EXIT 定义了一个名为 "退出" 的菜单项,(&X) 是快捷键,(&X) 是快捷键,IDM_EXIT 是菜单项的命令ID。

"关于(&A) ...", IDM_ABOUT 定义了一个名为 "关于" 的菜单项,(&A) 是快捷键,IDM_ABOUT 是菜单项的命令ID。

接着进行消息变量声明:

MSG msg;

MSG 结构体用于存储从消息队列中检索的消息,消息循环中会使用这个结构体来接收和处理窗口消息。MSG 结构体在 winuser.h 头文件中定义,用于包含窗口消息信息:

typedef struct tagMSG {HWND   hwnd;UINT   message;WPARAM wParam;LPARAM lParam;DWORD  time;POINT  pt;DWORD  lPrivate;
} MSG, *PMSG;

hwnd: 接收消息的窗口句柄,message: 消息标识符(如 WM_PAINT, WM_KEYDOWN),以及其他参数:

wParam: 消息的附加信息,具体内容取决于消息类型。
lParam: 消息的附加信息,具体内容取决于消息类型。
time: 消息被放入消息队列的时间戳。
pt: POINT 结构体,表示消息发生时的光标位置。
lPrivate: 私有数据,用于内部用途。

声明变量后接着就需要实现消息循环:它在应用程序的整个生命周期中不断运行,处理来自操作系统和用户的各种消息。

while (GetMessage(&msg, nullptr, 0, 0)){if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){TranslateMessage(&msg);DispatchMessage(&msg);}}

GetMessage 函数从调用线程的消息队列中检索消息,并将其存储在 MSG 结构体中。lpMsg: 指向 MSG 结构体的指针,用于接收消息;hWnd: 指定消息的窗口句柄,nullptr 表示检索线程的所有消息;wMsgFilterMinwMsgFilterMax: 指定要检索的消息范围,0, 0 表示检索所有消息。

TranslateAccelerator 函数将加速键消息转换为命令消息,hWnd: 接收消息的窗口句柄;hAccTable: 加速键表句柄;lpMsg: 指向 MSG 结构体的指针。加速键(Accelerator Key)消息是指在 Windows 应用程序中用于快捷键操作的一种消息类型。

TranslateMessage 函数将虚拟键消息(如 WM_KEYDOWN)转换为字符消息(如 WM_CHAR);虚拟键消息(Virtual Key Messages)是 Windows 操作系统中用于处理键盘输入的一种消息类型。它们是由键盘驱动程序生成的消息,通常通过输入设备(如键盘)上的按键触发。

DispatchMessage 函数将消息分派到窗口过程(Window Procedure),窗口过程根据消息类型执行相应的操作。

消息循环的完整流程

检索消息GetMessage 从消息队列中检索消息并存储在 msg 结构体中;如果 GetMessage 返回 0,表示收到 WM_QUIT 消息,退出消息循环。

处理加速键TranslateAccelerator 检查消息是否为加速键,如果是,则翻译并处理它,如果 TranslateAccelerator 返回 TRUE,表示消息已处理,不需要进一步处理。

翻译和分派消息:如果消息不是加速键或未处理,调用 TranslateMessage 将虚拟键消息转换为字符消息;调用 DispatchMessage 将消息分派到窗口过程,窗口过程根据消息类型执行相应的操作。

最后程序的执行结果:

关于窗口

相关文章:

win32:第一个窗口程序-应用程序入口点(part.6)

第一个窗口程序的最后一部分:应用程序入口函数wWinMain;这是Windows应用程序的主函数,负责初始化应用程序、注册窗口类、创建主窗口并进入消息循环处理消息。 int APIENTRY wWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInst…...

c++ 多边形 xyz 数据 获取 中心点方法,线的中心点取中心值搞定 已解决

有需求需要对。多边形 获取中心点方法&#xff0c;绝大多数都是 puthon和java版本。立体几何学中的知识。 封装函数 point ##########::getCenterOfGravity(std::vector<point> polygon) {if (polygon.size() < 2)return point();auto Area [](point p0, point p1, p…...

ext_errno:拓展errno

类似于C库的errno机制&#xff0c;报告错误发生的原因以及所在的位置&#xff0c;通过查询来获取。...

【CUDA】 Trust基本特性介绍及性能分析

Trust简介 Thrust 是一个实现了众多基本并行算法的 C 模板库,类似于 C 的标准模板库(standard template library, STL)。该库自动包含在 CUDA 工具箱中。这是一个模板库,仅仅由一些头文件组成。在使用该库的某个功能时,包含需要的头文件即可。该库中的所有类型与函数都在命名空…...

颈肩肌筋膜炎中医治疗

颈肩肌筋膜炎&#xff0c;又称颈肩肌纤维织炎或肌肉风湿症&#xff0c;是一种涉及筋膜、肌肉、肌腱和韧带等软组织的无菌性炎症。以下将分别从症状和治疗两方面进行详细介绍。 一、颈肩肌筋膜炎的症状 颈肩肌筋膜炎的主要症状包括&#xff1a; 1、肩背部疼痛&#xff1a;患者…...

Java 通配符 在短信发送之中 通配符参数动态获取解决方案

目录 1、通配符应用场景 2、实现方案分析 2.1、可能针对不同模板中核定参数硬编码到程序之中写死 2.2、通配置模板之中动态获得对应的参数 3、通过正则表达式验证与替换参数${}参考示例 4、参考文章 1、通配符应用场景 我们在使用通配符场景&#xff0c;主要是应用于短信…...

Mybatis-Plus中LambdaQueryWrapper

基本用法 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; // 假设有一个 User 实体类 LambdaQueryWrapper<User> queryWrapper new LambdaQueryWrapper<>(); // 添加查询条件 queryWrapper.eq(User::getName, "John&quo…...

C++ 入门05:类和对象

往期回顾&#xff1a; C 入门02&#xff1a;控制结构和循环-CSDN博客C 入门03&#xff1a;函数与作用域-CSDN博客C 入门04&#xff1a;数组与字符串-CSDN博客 一、前言 在前面文章的学习中&#xff0c;我们了解了 C 的基本结构、变量、输入输出、控制结构、循环、函数、作用域…...

4G LTE教程

整体架构 物理层&#xff08;第 1 层&#xff09; 物理层通过空中接口传输来自 MAC 传输信道的所有信息。负责 RRC 层的链路自适应 (AMC)、功率控制、小区搜索&#xff08;用于初始同步和切换目的&#xff09;和其他测量&#xff08;LTE 系统内部和系统之间&#xff09;。 介…...

C++:哈希表

哈希表概念 哈希表可以简单理解为&#xff1a;把数据转化为数组的下标&#xff0c;然后用数组的下标对应的值来表示这个数据。如果我们想要搜索这个数据&#xff0c;直接计算出这个数据的下标&#xff0c;然后就可以直接访问数组对应的位置&#xff0c;所以可以用O(1)的复杂度…...

自己动手写一个滑动验证码组件(后端为Spring Boot项目)

近期参加的项目&#xff0c;主管丢给我一个任务&#xff0c;说要支持滑动验证码。我身为50岁的软件攻城狮&#xff0c;当时正背着双手&#xff0c;好像一个受训的保安似的&#xff0c;中规中矩地参加每日站会&#xff0c;心想滑动验证码在今时今日已经是标配了&#xff0c;司空…...

keepalive脑裂

keepalive脑裂 调度器的高可用 vip地址主备之间的切换&#xff0c;主在工作时&#xff0c;p地址只在主上&#xff0c;主停止工作&#xff0c;ip飘移到备服务器。 在主备的优先级不变的情况下&#xff0c;主恢复工作&#xff0c;vip会飘回到主服务器。 1、配优先级 2、配置…...

STM32Cubemx配置生成 Keil AC6支持代码

文章目录 一、前言二、AC 6配置2.1 ARM ComPiler 选择AC62.2 AC6 UTF-8的编译命令会报错 三、STM32Cubemx 配置3.1 找到stm32cubemx的模板位置3.2 替换文件内核文件3.3 修改 cmsis_os.c文件3.4 修改本地 四、编译对比 一、前言 使用keil ARM compiler V5的时候&#xff0c;编译…...

Perl基础入门指南:从零开始掌握Perl编程

Perl是一种功能强大且灵活的编程语言&#xff0c;广泛应用于系统管理、Web开发、网络编程和文本处理等领域。如果你是编程新手或者想学习一种新的编程语言&#xff0c;Perl是一个不错的选择。本文将带你了解Perl的基础知识&#xff0c;并通过简单的示例代码帮助你快速入门。 什…...

Mybatis SQL注解使用场景

MyBatis 提供了几种常用的注解&#xff0c;主要用于简化 XML 映射文件的编写&#xff0c;使得 SQL 查询和操作可以直接在 Java 接口中定义。下面列出了主要的注解以及它们在被调用时的写法示例&#xff1a; 1. Select Select 注解用于执行查询操作&#xff0c;并将查询结果映…...

Dataset for Stable Diffusion

1.Dataset for Stable Diffusion 笔记来源&#xff1a; 1.Flickr8k数据集处理 2.处理Flickr8k数据集 3.Github&#xff1a;pytorch-stable-diffusion 4.Flickr 8k Dataset 5.dataset_flickr8k.json 1.1 Dataset 采用Flicker8k数据集&#xff0c;该数据集有两个文件&#xff…...

近期matlab学习笔记,学习是一个记录,反复的过程

近期matlab学习笔记&#xff0c;学习是一个记录&#xff0c;反复的过程 matlab的mlx文件在运行的时候&#xff0c;不需要在文件夹路径下&#xff0c;也能运行&#xff0c;但是需要调用子函数时&#xff0c;就需要在文件所在路径下运行 那就先运行子函数&#xff0c;把路径换过来…...

Elasticsearch7.5.2 常用rest api与elasticsearch库

目录 一、rest api 1. 新建索引 2. 删除索引 3. 插入单条数据 4. 更新单条数据 5. 删除单条数据 6. 查询数据 二、python elasticsearch库 1. 新建索引 一、rest api 1. 新建索引 请求方式&#xff1a;PUT 请求URL&#xff1a;http://ip/&#xff08;your_index_nam…...

Autosar Dcm配置-0x28服务ComControl-基于ETAS软件

文章目录 前言DcmDcmDsdDcmDspBswMBswMModeRequestPortBswMModeConditionBswMLogicalExpressionBswMActionBswMActionListBswMRule总结前言 0x28服务主要用来控制非诊断报文的通讯,一般在刷写预编程过程中,用来禁止APP的通信报文,可以减少总线负载率,提高刷写成功率。本文…...

平安养老险厦门分公司:提升金融服务,发挥金融力量

为向社会公众普及金融保险知识&#xff0c;传递消费者权益保护理念&#xff0c;平安养老保险股份有限公司厦门分公司&#xff08;以下简称“分公司”&#xff09;积极开展“78保险公众宣传日”系列教育宣传活动。分公司紧扣“保险&#xff0c;让每一步前行更有底气”主题&#…...

【开源合规】开源许可证风险场景详细解读

文章目录 前言关于BlackDuck许可证风险对比图弱互惠型许可证举个例子具体示例LGPL系列LGPL-2.0-onlyLGPL-2.0-or-laterLGPL-2.1-onlyLGPL-2.1-or-laterLGPL-3.0-onlyLGPL-3.0-or-laterMPL系列MPL-1.0MPL-1.1MPL-2.0EPL系列EPL-1.0EPL-2.0互惠型许可证GPL系列GPL-1.0GPL-2.0GPL-…...

Redis持久化RDB,AOF

目 录 CONFIG动态修改配置 慢查询 持久化 在上一篇主要对redis的了解入门&#xff0c;安装&#xff0c;以及基础配置&#xff0c;多实例的实现&#xff1a;redis的安装看我上一篇&#xff1a; Redis安装部署与使用,多实例 redis是挡在MySQL前面的&#xff0c;运行在内存…...

【持续集成_03课_Linux部署Sonar+Gogs+Jenkins】

一、通过虚拟机搭建Linux环境-CnetOS 1、安装virtualbox&#xff0c;和Vmware是一样的&#xff0c;只是box更轻量级 1&#xff09;需要注意内存选择&#xff0c;4G 2、启动完成后&#xff0c;需要获取服务器IP地址 命令 ip add 服务器IP地址 通过本地的工具&#xff0c;进…...

mvcc 速读

MVCC&#xff08;Multi-Version Concurrency Control&#xff0c;多版本并发控制&#xff09;是MySQL中一种用于实现数据库并发控制的方法&#xff0c;尤其在InnoDB存储引擎中得到了广泛应用。它的主要作用是提高数据库在高并发场景下的性能&#xff0c;并确保数据的一致性。 …...

美容仪维修过程记录

近期维修的家用射频美容仪&#xff0c;发一些维修过程的拆机图片...

STM32入门开发操作记录(一)——新建工程

目录 一、课程准备1. 课程资料2. 配件清单3. 根目录 二、环境搭建三、新建工程1. 载入器件支持包2. 添加模块3. ST配置4. 外观设置5. 主函数文件 一、课程准备 1. 课程资料 本记录操作流程参考自b站视频BV1th411z7snSTM32入门教程-2023版 细致讲解 中文字幕&#xff0c;课程资…...

QT实现自定义带有提示信息的透明环形进度条

1. 概述 做界面开发的童鞋可能都会遇到这样的需求&#xff0c;就是有一些界面点击了之后比较耗时的操作&#xff0c;需要界面给出一个环形进度条的进度反馈信息. 如何来实现这样的需求呢&#xff0c;话不多说&#xff0c;上效果 透明进度条 2. 代码实现 waitfeedbackprogressba…...

金币程序题

昨天&#xff0c;小孩问了我一个python编程竞赛题&#xff0c;我看了一下题目&#xff0c;是一个数列编程的问题&#xff0c;我在想&#xff0c;小学五年级的学生能搞得懂吗&#xff1f;反正我家小孩是没有搞懂&#xff0c;不知道别人家的小孩能不能搞明白。所以我花了一点时间…...

《Windows API每日一练》9.13资源-鼠标位图和字符串

鼠标指针位图&#xff08;Mouse Cursor Bitmap&#xff09;是用于表示鼠标指针外观的图像。在 Windows 窗口编程中&#xff0c;可以使用自定义的鼠标指针位图来改变鼠标的外观&#xff0c;并提供更加个性化的用户体验。 ■以下是一些与鼠标指针位图相关的要点&#xff1a; ●…...

【保姆级教程】CenterNet的目标检测、3D检测、关键点检测使用教程

一、代码下载 仓库地址:https://github.com/xingyizhou/CenterNet?tab=readme-ov-file 二、目标检测 2.1 下载预训练权重 下载预训练权重ctdet_coco_dla_2x.pth放到models文件夹下 下载链接:https://drive.google.com/file/d/18Q3fzzAsha_3Qid6mn4jcIFPeOGUaj1d/edit …...

医院如何做网站策划?/免费人脉推广软件

CPython c语言开发的 使用最广的解释器IPython 基于cpython之上的一个交互式计时器 交互方式增强 功能和cpython一样PyPy 目标是执行效率 采用JIT技术 对python代码进行动态编译&#xff0c;提高执行效率JPython 运行在Java上的解释器 直接把python代码编译成Java字节码执行Iro…...

微商网站/软文推广系统

30行代码实现纯CSS—3种换肤 老规矩&#xff0c;先把代码给大家&#xff0c;拿去粘贴直接用&#xff0c;无需引用&#xff0c;不好用评论底下随便喷&#xff0c;我一条一条看。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UT…...

优质做网站公司/bt磁力搜索引擎

在bitbucket上使用https协议&#xff0c;经常会在提交代码的时候出错&#xff0c;让人很着急上火&#xff0c;但是用ssh就要方便很多。下面介绍一下设置ssh的方法&#xff1a;1.在终端中运行ssh-keygen。2.然后一路enter&#xff0c;直接到结束。不要理会中间的输入。3 打开用户…...

网站建设制作软件/搜索风云榜

对于想要打造爆款朋友圈的朋友来说要么就是想靠朋友圈引流要么就是想直接在微信变现&#xff0c;但不论如何首先你需要有自己专业的知识或者有清晰的目标 一、要专业&#xff0c;可以多发些案例反馈&#xff0c;大咖背书&#xff0c;互动或者认证&#xff0c;增加你的可信度&am…...

贵阳地铁建设网站/seo是什么工作内容

2019独角兽企业重金招聘Python工程师标准>>> [toc] 网络协议&#xff08;networking protocol&#xff09; 网络协议即为计算机网络中进行数据交换而建立的规则、标准或约定的集合。网络协议是由三个要素组成&#xff1a;语义、语法、时序&#xff0c;人们形象地把这…...

企业网站文章后台添加/优化大师免费安装下载

1.阿里巴巴矢量图官网&#xff1a;https://www.iconfont.cn/ 2.把需要用到的图标加入购物车&#xff0c;需要注册登录 3.把选好的图标添加至项目 4.下载到本地 5.解压&#xff0c;打开&#xff0c;选择复制这四个文件&#xff0c;粘贴到项目的css文件里 6.在项目中使用...