windows编程 为什么要用宽字节

简介: windows编程 为什么要用宽字节

1668320809505.jpg

今天这个问题困扰了我好久,其实对于一个初学者来说,不必专研的太深,大致理解如下就可以了:


窄字符就是用一个字节表示一个字符,宽字符就是用≥2个字节表示一个字符。


比如(以Windows下小端存储为例)

char c=’A’;//内存中对应字节41
wchar_t wc=L’A’;//内存中对应字节41 00
char cs[]=”AB”;//内存中对应字节41 42 00
wchar_t ws[]=L”AB”;//内存中对应字节41 00 42 00 00 00


Windows中所有的底层函数都是Unicode编码


GetWindowTextW(
    _In_ HWND hWnd,
    _Out_writes_(nMaxCount) LPWSTR lpString,
    _In_ int nMaxCount);
#ifdef UNICODE
#define GetWindowText  GetWindowTextW


该函数将指定窗口的标题条文本(如果存在)拷贝到一个缓存区内。如果指定的窗口是一个控件,则拷贝控件的文本。但是,GetWindowText不能接收其他应用程序中控件的文本。 函数原型:Int GetWindowText(HWND hWnd,LPTSTR lpString IntnMaxCount);。。。。。。。。。。。。。。。。。。。。。。。。

hWnd:带文本的窗口或控件的句柄。

IpString:指向接收文本的 缓冲区的 指针。

nMaxCount:指定要保存在缓冲区内的字符的最大个数,其中包含NULL字符。如果文本超过界限,它就被截断。

> getwindowtext的DELPHI例子:
>  varp:pchar; begin getmem(p,255); getwindowtext(application.Handle,p,255);
> showmessage(strpas(p)); 
> freemem(p); 
> end; 返回值


如果函数成功,返回值是拷贝的字符串的字符个数,不包括中断的空字符;如果窗口无标题栏或文本,或标题栏为空,或窗口或控制的句柄无效,则返回值为零。若想获得更多 错误信息,请调用GetLastError函数。

函数不能返回在其他 应用程序中的编辑控件的文本。


COM组件必须使用Unicode编码(COM组件可以理解为DLL,主要是用于代码重用);


比如在Windows API中:


FindWindowW和FindWindowA


W的意思为wide(宽)

A的意思为ASCII


在Windows.h中有一个UNICODE宏


底层调用宽字节版本


窄字节版本仅作编码转换


下面是2个字符串转换的函数:


1668320892677.jpg


C++语言中“_T”是什么意思?


Visual C++里边定义字符串的时候,用_T来保证兼容性,VC支持ascii和unicode两种字符类型,用_T可以保证从ascii编码类型转换到unicode编码类型的时候,程序不需要修改。


如果将来你不打算升级到unicode,那么也不需要_T,


一. 多字节字符


基于ASCII的GB2312

标准ASCII表 0 ~ 127


拓展ASCII表 0 ~ 255


GB2312 10000000 ~ 11111111(高位) + 10000000 ~ 11111111(低位)


问题:不同国家的字符集会产生乱码

1

基于UNICODE的UTF-8

UNICODE(同一码 / 万国码):unicode是2个字节。 这一标准的2字节形式通常称作UCS-2(UnicodeCharacterSet)(原ASCII也位双字节)。然而,受制于2字节数量的限制,UCS-2只能表示最多65536个字符。Unicode的4字节形式被称为UCS-4或UTF-32,能够定义Unicode的全部扩展,最多可定义100万个以上唯一字符。


UTF-8:是针对Unicode的一种可变长度字符编码。


二. C语言中的宽字符的使用


1. 在C语言中使用wchar_t表示宽字符,使用L告知编译器使用Unicode表。wchar_t x1 = L’中’;

2. 使用(拓展ASCII码表)GB2312以\0结尾:char x[] = “中国”; 使用UniCode编码表以\0\0结尾:wchar_t x1[] = L"中国";

3. 在控制台打印

char x[] = "中国";                    
wchar_t x1[] = L"中国";                    
printf("%s\n",x);            //使用控制台默认的编码        
wprintf(L"%s\n",x1);            //默认使用英文


在打印x1时默认使用ASCII码表解码所以会出现乱码或无法显示。


此时需要告诉编译器,使用控制台默认的编码格式


(1) 包含头文件 #include <locale.h>                  


(2) setlocale(LC_ALL,""); //使用控制台默认的编码              


三. C语言宽字符操作函数


在使用函数时也是有区别的。


char x[] = "中国";
wchar_t x1[] = L"中国";
cout << strlen(x) << endl; // 4
cout << wcslen(x1) << endl; // 2
char  wchar_t  //多字节字符类型   宽字符类型    
printf  wprintf  //打印到控制台函数   
strlen  wcslen  //获取长度    
strcpy  wcscpy  //字符串复制   
strcat  wcscat  //字符串拼接   
strcmp  wcscmp  //字符串比较   
strstr  wcsstr  //字符串查找


四. 字符串转换


MFC下的常用字符串数据类型表示的含义:

L:Long 长  P:Point 指针  C:Const 常量  W:Wchar_t 宽字符  T:TCHAR   STR:String 字符串


MFC下提供的ATL 转换宏:

T2A T2W T2CA T2CW W2A W2CA W2T W2CT A2W A2CW A2T A2CT
T:TCHAR  2:To  C:CONST  A:CHAR(ANSI)  W:WCHAR

先到atlconv.h头文件下看看这些宏的定义,还需要在转换上方添加宏,并以分号结束:USES_CONVERSION;它定义了转换宏所需的一些局部变量。


使用USES_CONVERSION一定要小心,它们从堆栈上分配内存,直到调用它的函数返回,该内存不会被释放。如果在一个循环中,这个宏被反复调用几万次,将不可避免的产生stackoverflow。


但是考虑到栈空间的尺寸( 默认2M),使用时要注意几点:

1、只适合于进行短字符串的转换;

2、不要试图在一个次数比较多的循环体内进行转换;

3、不要试图对字符型文件内容进行转换,因为文件尺寸一般情况下是比较大的;

4、对情况 2 和 3,要使用 MultiByteToWideChar() 和 WideCharToMultiByte();


https://www.cnblogs.com/wind-net/archive/2012/10/31/2746995.html


五. 打印信息的方式


int a = 10;
  TRACE("a == %d", a);
  CString s;
  s.Format(CString("a == %d"), 20);
  AfxMessageBox(s);
  MessageBox(TEXT("111", NULL, NULL, NULL));
#define log(fmt, ...) \
CString str; \
str.Format(CString(fmt), __VA_ARGS__); \
AfxMessageBox(s);
void CPVZCheartDlg::OnBnClickedButton1()
{
  int a = 10;
  log("a == %d", a);
}
相关文章
|
消息中间件 C++ Windows
02 MFC - Windows 编程模型
02 MFC - Windows 编程模型
86 0
|
5月前
|
网络协议 API Windows
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
|
5月前
|
Windows
[原创]用MASM32编程获取windows类型
[原创]用MASM32编程获取windows类型
|
5月前
|
JavaScript 前端开发 API
MASM32编程通过WMI获取Windows计划任务
MASM32编程通过WMI获取Windows计划任务
|
5月前
|
API Windows
MASM32编程获取Windows当前桌面主题名
MASM32编程获取Windows当前桌面主题名
|
6月前
|
编译器 开发工具 C语言
解锁QtCreator跨界神技!Windows下轻松驾驭OpenCV动态库,让你的跨平台开发如虎添翼,秒变视觉编程大师!
【8月更文挑战第4天】QtCreator是一款强大的跨平台IDE,便于创建多平台应用。本教程教你如何在Windows环境下集成OpenCV库至Qt项目。首先,下载匹配MinGW的OpenCV预编译版并解压。接着,在QtCreator中新建或打开项目,并在.pro文件中添加OpenCV的头文件和库文件路径。确保编译器设置正确。随后编写测试代码,例如加载和显示图片,并进行编译运行。完成这些步骤后,你就能在QtCreator中利用OpenCV进行图像处理开发了。
323 6
|
6月前
|
数据库 Windows
超详细步骤解析:从零开始,手把手教你使用 Visual Studio 打造你的第一个 Windows Forms 应用程序,菜鸟也能轻松上手的编程入门指南来了!
【8月更文挑战第31天】创建你的第一个Windows Forms (WinForms) 应用程序是一个激动人心的过程,尤其适合编程新手。本指南将带你逐步完成一个简单WinForms 应用的开发。首先,在Visual Studio 中创建一个“Windows Forms App (.NET)”项目,命名为“我的第一个WinForms 应用”。接着,在空白窗体中添加一个按钮和一个标签控件,并设置按钮文本为“点击我”。然后,为按钮添加点击事件处理程序`button1_Click`,实现点击按钮后更新标签文本为“你好,你刚刚点击了按钮!”。
524 0
|
8月前
|
Java C++
jni编程(windows+JDK11+clion)
jni编程(windows+JDK11+clion)
129 1
|
C++ Windows
[笔记]Windows核心编程《番外篇》几种常见的执行命令行方法
[笔记]Windows核心编程《番外篇》几种常见的执行命令行方法
135 0
|
9月前
|
API C++ Windows
windows编程入门_链接错误的配置
windows编程入门_链接错误的配置
72 0