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

第2章,[标签 Win32] :兼容 ASCII 字符与宽字符的 Windows 函数调用

专栏导航

上一篇:第2章,[标签 Win32] :Windows 字符数据类型

回到目录

下一篇:无

本节前言

在上一节,我们讲解了 WIndows 程序设计中的字符与字符指针类型,包括 ASCII 字符与字符指针,也包括 Unicode 字符与字符指针。

本节,我们来讲解,使用字符串作参数的 Windows 函数。这样的一些个 Windows 函数,所使用的字符串参数,可能是 ASCII 字符串,也可能是 Unicode 字符串。

如何编写程序,使得我们的程序,在调用这些个,使用字符串参数的 Windows 函数的时候,能够兼容 ASCII 字符串与 Unicode 字符串两种字符串参数,是我们本节要去解决的问题。

我们开始。

一.    MessageBox 宏函数

在之前的课节里,我们介绍过 MessageBox 函数。严格来讲,它并不是一个函数,而是一个宏函数。实际调用它的时候,会调用两个函数版本中的一个。这两个函数版本,一个是 ASCII 版的 MessageBoxA,另一个是 Unicode 版的 MessageBoxW 。

MessageBoxA 和 MessageBoxW,它俩不是宏,而是地地道道的函数。

那么,当我们使用 MessageBox 宏的时候,我们究竟是在调用着 MessageBoxA,还是在使用着 MessageBoxW 呢?

请看下面的代码块。

#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif

也就是说,当我们定义了 UNICODE 标识符的时候,MessageBox 宏函数,实际上就等同于 MessageBoxW 函数。当没有定义 UNICODE 标识符的时候,MessageBox 宏函数,实际上就等同于 MessageBoxA 函数。

在这里,UNICODE 标识符,与 _UNICODE 标识符,我们可以将其看作是同义语,对其不作区分。

我们在下面的文章链接里,讲解了如何定义 _UNICODE 标识符,也就是相当于讲解了如何定义 UNICODE 标识符。

第2章 :编写兼容多字节字符集和 Unicode 字符集的 Windows 程序

在上述文章链接的【四.(二)】里面,我们讲解了设置方法。

我们来看一看 MessageBoxA 与 MessageBoxW 的函数声明。

MessageBoxA 的声明如下。

WINUSERAPI int WINAPI MessageBoxA (HWND hWnd, LPCSTR lpText,
                                                                LPCSTR lpCaption, UINT uType);

在上面的函数声明里面,首先出现的东西是 WINUSERAPI,这个东西我们不用管,忽略它就可以了。我们可以将这个东西当作是不存在。这不会影响我们的理解。

接下来的 int,就是返回值类型,为 int 型。

接下来的 WINAPI,它表示的是调用约定。在计算机编程里面,存在着很多种函数调用约定。其中有两种,一个是标准调用,Windows 将其标记为 __stdcall 。另一个是 CDECL 调用约定,Windows 将其标记为 __cdecl 。大多数的 Windows SDK 函数使用的调用约定是标准调用,而大多数的 C 运行库函数,以及我们自定义的函数,都用的是 CDECL 调用约定。

接下来的 MessageBoxA,它是函数名。

再往后,就是形参列表了。

在形参列表里,第一个形参的类型为 HWND,它的含义是窗口句柄。啥是窗口句柄,此处你可以暂时不去深究,有个印象就可以。在将来的 Windows 编程知识的学习中,窗口句柄的概念,我们时不时地都会用到。用得多了,即使不理解,也可以熟练地使用它。此处,我们只要求大家对【窗口句柄】这个数据类型有一个概念。

第二个形参的类型为 LPCSTR,这个 LPCSTR,与【const char *】含义相同。也就是说,第二个参数,需要的是一个常量字符指针。这个字符指针,指向的是一个 ASCII 字符串,字符串中的每一个字符,都是 char 型的。

第三个形参的类型也是 LPCSTR,与第二个参数的类型相同。

第四个形参的类型为 UINT,这个,我们之前没有讲,以后,我们会有专门的章节来列举 Windows 中的各种数据类型。之前,我们讲解过关于字符与字符串的数据类型。在这里,这个 UINT,它其实就是 unsigned int 的意思。

讲完了 MessageBoxA 的函数声明,我们再来看 MessageBoxW 的函数声明。

WINUSERAPI int WINAPI MessageBoxW (HWND hWnd, LPCWSTR lpText,
                                                                LPCWSTR lpCaption, UINT uType);

MessageBoxW 的函数声明与 MessageBoxA 大致相同,只是涉及字符串参数的部分有所不同而已。

MessageBoxA 的参数列表里面,使用的字符串参数类型,为 LPCSTR,也就是【const char *】类型。也就是说,MessageBoxA 使用的字符串参数,为 ASCII 字符串,字符串中的每一个字符,为 char 型字符。

MessageBoxW 与 MessageBoxA 不同,它使用的字符串参数类型,为 LPCWSTR,也就是【const WCHAR *】类型,是【const wchar_t *】类型,是【const unsigned short *】类型。也就是说,MessageBoxW 使用的字符串参数,为 Unicode 字符串,字符串中的每一个字符,为 Unicode 字符。

小结一下,MessageBoxA 函数与 MessageBoxW 函数的函数声明大致相同,区别只在于使用的字符串参数的类型。MessageBoxA 函数使用的字符串参数,为 ASCII 字符串,而 MessageBoxW 函数使用的是 Unicode 字符串。

你可以在程序中,直接使用 MessageBox,而不显式地指定使用 MessageBoxA 或 MessageBoxW 。此时,根据你是否设置了 UNICODE 标识符,编译器会自动选择使用 MessageBoxA 或 MessageBoxW 。此时,如果你定义了 UNICODE 标识符,则 MessageBox 宏会被视为 MessageBoxW 函数。如果没有定义 UNICODE 标识符,则 MessageBox 宏会被视为 MessageBoxA 函数。

你也可以显式地指定,是使用 MessageBoxA 还是 MessageBoxW 。这样一来,在同一个程序代码里面,我们可以混合使用 ASCII 版的 Windows 函数与 Unicode 版的 Windows 函数。

不过,一般来讲,我们还是推荐大家直接使用通用的宏,也就是使用 MessageBox,而不是显式地指定 ASCII 版的 MessageBoxA 或者 Unicode 版的 MessageBoxW 。

二.    使用字符串参数的其它 Windows 宏函数

许多的 Windows 宏函数都与 MessageBox 类似,它们均包含 ASCII 版本与 Unicode 版本两种。

比如 Textout 函数,也包含了 TextOutA 和 TextOutW 两个版本。

所有的这些个使用字符串参数的 Windows 函数,它们均分为 ASCII 版与 Unicode 版两种。ASCII 版的 Windows 函数,在宏名的后面,加上一个 A 后缀。Unicode 版的 Windows 函数,在宏名的后面,加上一个 W 后缀。

结束语

本节的内容,不知道,你看懂了没。

如果没看懂,多看几遍吧。某些内容,可以暂时不去深究,了解一下,有个印象就可以。

本节结束。

专栏导航

上一篇:第2章,[标签 Win32] :Windows 字符数据类型

回到目录

下一篇:无

http://www.dtcms.com/a/263692.html

相关文章:

  • React:利用React.memo和useCallback缓存弹窗组件
  • 欢乐熊大话蓝牙知识24:LE Secure Connections 是 BLE 的安全升级术
  • HarmonyOS应用开发高级认证知识点梳理 (一) 布局与样式
  • 微信小程序使用秋云ucharts echarts
  • 利用springEvent,进行服务内部领域事件处理
  • 安卓接入百度定位和地图SDK
  • Go并发模式精要:掌握Goroutine与Channel的实战艺术
  • 开篇:GORM入门——Go语言的ORM王者
  • 物联网数据洪流下,TDengine 如何助 ThingLinks 实现 SaaS 平台毫秒级响应?
  • LabVIEW调用Excel宏实现数据可视化
  • 4D 毫米波雷达
  • 21、鸿蒙学习——使用App Linking实现应用间跳转
  • SQL Server 进阶:递归 CTE+CASE WHEN 实现复杂树形统计(第二课)
  • 【Python基础】12 闲谈分享:Python用于无人驾驶的未来
  • 借助飞算AI新手小白快速入门Java实操记录
  • 嵌入式编程-使用AI查找BUG的启发
  • AG32调试bug集合
  • [论文阅读] 人工智能 + 软件工程 | 从软件工程视角看大语言模型:挑战与未来之路
  • 基于 Vue + RuoYi 架构设计的商城Web/小程序实训课程
  • 企业级应用技术-ELK日志分析系统
  • java生成word文档
  • 11年考研作文真题大数据
  • 边缘人工智能与医疗AI融合发展路径:技术融合与应用前景(下)
  • SpringBoot计时一次请求耗时
  • mac python3.13 selenium安装使用
  • [特殊字符] 分享裂变新姿势:用 UniApp + Vue3 玩转小程序页面分享跳转!
  • IntelliJ IDEA 2025- 下载安装教程图文版详细教程(附激活码)
  • Python 库 包 nltk (Natural Language Toolkit)
  • 类加载生命周期与内存区域详解
  • 【FR801xH】富芮坤FR801xH之UART