找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 4310|回复: 19

【VB6】把BSTR和ANSI/UNICODE/UNICODE-BE/UTF8字符串互相转换

[复制链接]

55

主题

275

回帖

9352

积分

用户组: 管理员

UID
77
精华
16
威望
237 点
宅币
8217 个
贡献
251 次
宅之契约
0 份
在线时间
254 小时
注册时间
2014-2-22
发表于 2021-9-3 15:28:19 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
首先说明:ANSIUNICODE、UNICODE-BE(UNICODE BIG ENDIAN)的名称可能有歧义,以上名称来自WINDOWS记事本“另存为”对话框的【编码选择】处。

BSTR就是VB的STRING字符串,它本质上是UNICODE字符串。但讽刺的是,VB的自带控件竟然都不支持UNICODE。比如你想在中文系统上用VB自带控件(比如LABEL和TEXTBOX)正确显示德语的变音字母,是不可能的。要做的这点,必须用API自行创建控件。

ANSI字符串是最常见的,等同于C语言里的CHAR[],它的格式可以简单理解为“英文字符1字节+非英文字符2字节”。它的缺点在于非英文字符的编码有N种方法,比如简体中文WINDOWS系统的汉字编码是GBK(兼容GB2312),繁体中文WINDOWS系统的汉字编码是BIG5。如果在繁体中文WINDOWS系统上保存一个ANSI格式文本文件放到简体中文WINDOWS系统上打开就会显示为乱码,反之亦然。如果你的程序用了A版本的API,比如【MessageBoxA(0,"字符串",0,0)】,那么在非简体中文WINDOWS系统上看到的弹框将会是乱码;如果你的程序用的是W版本的API,比如【MessageBoxW(0,L"字符串",0,0)】,那么在非简体中文WINDOWS系统上看到的弹框则是正常的。

UNICODE字符串等同于C语言里的WCHAR[],所有字符就一律2个字节。该编码全球通用,不受地区和系统的影响。但如果字符串主要由英文字符组成时,会造成大量空间浪费。比如ABCD的ANSI编码是\x41\x42\x43\x44,但UNICODE编码则是\x41\x0\x42\x0\x43\x0\x44\x0。

UNICODE-BE字符串就是把UNICODE字符串的2个字节的位置调换了一下。比如某个字符的UNICODE编码是0xAA55,那么UNICODE-BE的编码就是0x55AA。该编码全球通用,不受地区和系统的影响。

综合ANSI和UNICODE的优缺点,于是就有了UTF8。对于纯英文字符,UTF8和ANSI是兼容的;对于非英文字符,UTF8有一套固定编码方法。该编码全球通用,不受地区和系统的影响。UTF8的缺点是一个中文字符的长度可能高达3字节甚至4字节。

使用MultiByteToWideChar和WideCharToMultiByte能让VB字符串(BSTR)和其它字符串相互转换。

以下是测试(把代码复制并保存为FRM文件即可运行):
游客,如果您要查看本帖隐藏内容请回复

本帖被以下淘专辑推荐:

回复

使用道具 举报

1111

主题

1651

回帖

7万

积分

用户组: 管理员

一只技术宅

UID
1
精华
244
威望
743 点
宅币
24239 个
贡献
46222 次
宅之契约
0 份
在线时间
2297 小时
注册时间
2014-1-26
发表于 2021-9-4 19:46:34 | 显示全部楼层
其实你所说的“UNICODE”是Win32编程里的“UNICODE宏”的概念,需要和Unicode编码形式的概念区分开。

Unicode使用32位整数存储每个字符,比如ABCD其实是41 00 00 00 42 00 00 00 43 00 00 00 44 00 00 00,看起来非常占空间,但它能表达的字符种类非常多,其中还包含了相当多的数量的Emoji表情字符等。

Win32编程的“UNICODE”其实使用的是UTF-16编码。其和UTF-8一样,是Unicode的压缩形式。通过判断高位的Bit组合来决定后续字节是否与当前字节共同组合为一个字符。

UTF-8、UTF-16都是Unicode的压缩形式,其压缩解压的算法十分简单,参考这个帖子可以不借助API进行其中的互转:10972

也可以参考这个更加早期的帖子:1676

顺带一提,VB6自带“StrConv”函数,可以进行字符串编码转换,和MultiByteToWideChar、WideCharToMultiByte的功能相同。
回复 赞! 靠!

使用道具 举报

55

主题

275

回帖

9352

积分

用户组: 管理员

UID
77
精华
16
威望
237 点
宅币
8217 个
贡献
251 次
宅之契约
0 份
在线时间
254 小时
注册时间
2014-2-22
 楼主| 发表于 2021-9-6 22:10:47 | 显示全部楼层
0xAA55 发表于 2021-9-4 19:46
其实你所说的“UNICODE”是Win32编程里的“UNICODE宏”的概念,需要和Unicode编码形式的概念区分开。

Unic ...

StrConv不好使,只能和UNICODE互相转换。

但是BSTR和UNICODE互相转换可以直接使用“等号”实现。
回复 赞! 靠!

使用道具 举报

0

主题

2

回帖

32

积分

用户组: 初·技术宅

UID
5597
精华
0
威望
2 点
宅币
26 个
贡献
0 次
宅之契约
0 份
在线时间
3 小时
注册时间
2020-2-9
发表于 2021-9-11 08:50:53 | 显示全部楼层
谢谢分享,学习了
回复 赞! 靠!

使用道具 举报

0

主题

28

回帖

0

积分

用户组: 初·技术宅

UID
5412
精华
0
威望
-2 点
宅币
-24 个
贡献
0 次
宅之契约
0 份
在线时间
10 小时
注册时间
2019-10-31
发表于 2021-11-12 21:19:07 | 显示全部楼层
dfdfdfdfdfdf
回复 赞! 靠!

使用道具 举报

0

主题

16

回帖

45

积分

用户组: 初·技术宅

UID
7607
精华
0
威望
2 点
宅币
25 个
贡献
0 次
宅之契约
0 份
在线时间
8 小时
注册时间
2021-12-6
发表于 2022-4-5 11:23:57 | 显示全部楼层
谢谢分享,学习了
回复 赞! 靠!

使用道具 举报

1

主题

159

回帖

626

积分

用户组: 大·技术宅

UID
7535
精华
0
威望
0 点
宅币
466 个
贡献
0 次
宅之契约
0 份
在线时间
71 小时
注册时间
2021-10-16
发表于 2022-5-13 15:37:14 | 显示全部楼层
此贴必火,占位刘留名~~~~
回复 赞! 靠!

使用道具 举报

9

主题

177

回帖

1万

积分

用户组: 真·技术宅

UID
4293
精华
6
威望
441 点
宅币
8675 个
贡献
850 次
宅之契约
0 份
在线时间
338 小时
注册时间
2018-9-19
发表于 2022-5-20 12:42:46 | 显示全部楼层
其实VB6点TextBox是可以做到显示Unicode字符的,首先需要给exe加入comctl32.dll 6.0清单,让控件获得视觉主题,然后文本不要通过.Text属性赋值,而是用GetClassInfoW去获取原生的W版Edit控件的WndProc,最后用CallWindowProcW来调用它并传人WM_SETTEXT消息。同理我们也可以利用DefWindowProcW函数来实现让VB6的Form窗口标题栏现实Unicode文本。

点评

谢谢,这个方法确实可行。  发表于 2022-5-24 14:24
回复 赞! 靠!

使用道具 举报

55

主题

275

回帖

9352

积分

用户组: 管理员

UID
77
精华
16
威望
237 点
宅币
8217 个
贡献
251 次
宅之契约
0 份
在线时间
254 小时
注册时间
2014-2-22
 楼主| 发表于 2022-5-20 14:53:14 | 显示全部楼层
系统消息 发表于 2022-5-20 12:42
其实VB6点TextBox是可以做到显示Unicode字符的,首先需要给exe加入comctl32.dll 6.0清单,让控件获得视觉主 ...

口说无凭,你也弄个DEMO并放出源码来。

https://www.0xaa55.com/thread-26616-1-1.html

点评

你自己试试吧,这个例子我已经给很多人写过多次了。  发表于 2022-5-21 23:44
回复 赞! 靠!

使用道具 举报

1

主题

44

回帖

987

积分

用户组: 大·技术宅

UID
7437
精华
0
威望
112 点
宅币
608 个
贡献
110 次
宅之契约
0 份
在线时间
133 小时
注册时间
2021-9-11
发表于 2022-5-20 17:20:26 | 显示全部楼层
认真学习
回复

使用道具 举报

1

主题

24

回帖

138

积分

用户组: 小·技术宅

UID
2928
精华
0
威望
1 点
宅币
111 个
贡献
0 次
宅之契约
0 份
在线时间
15 小时
注册时间
2017-10-7
发表于 2022-5-24 13:51:43 | 显示全部楼层
杠起来了?
回复

使用道具 举报

0

主题

11

回帖

44

积分

用户组: 初·技术宅

UID
8289
精华
0
威望
2 点
宅币
29 个
贡献
0 次
宅之契约
0 份
在线时间
2 小时
注册时间
2023-4-7
发表于 2023-5-6 17:23:24 | 显示全部楼层
6
回复

使用道具 举报

0

主题

3

回帖

19

积分

用户组: 初·技术宅

UID
8318
精华
0
威望
2 点
宅币
12 个
贡献
0 次
宅之契约
0 份
在线时间
0 小时
注册时间
2023-5-11
发表于 2023-5-11 22:53:05 | 显示全部楼层
谢谢高手
回复

使用道具 举报

0

主题

7

回帖

29

积分

用户组: 初·技术宅

UID
8349
精华
0
威望
2 点
宅币
18 个
贡献
0 次
宅之契约
0 份
在线时间
1 小时
注册时间
2023-7-5
发表于 2023-7-5 11:44:26 | 显示全部楼层
学习一下
回复

使用道具 举报

0

主题

27

回帖

59

积分

用户组: 小·技术宅

UID
8351
精华
0
威望
2 点
宅币
28 个
贡献
0 次
宅之契约
0 份
在线时间
5 小时
注册时间
2023-7-5
发表于 2023-7-6 10:22:11 | 显示全部楼层
来晚了啊
回复

使用道具 举报

0

主题

5

回帖

27

积分

用户组: 初·技术宅

UID
8405
精华
0
威望
2 点
宅币
18 个
贡献
0 次
宅之契约
0 份
在线时间
2 小时
注册时间
2023-8-14
发表于 2023-8-19 15:12:39 | 显示全部楼层
vb6 編碼就新手而言是個困擾,感謝分享學習。
回复 赞! 靠!

使用道具 举报

0

主题

5

回帖

30

积分

用户组: 初·技术宅

UID
5605
精华
0
威望
2 点
宅币
21 个
贡献
0 次
宅之契约
0 份
在线时间
1 小时
注册时间
2020-2-10
发表于 2023-9-26 18:00:27 | 显示全部楼层
谢谢分享!
回复

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-4-23 20:15 , Processed in 0.042959 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表