关于Vspy中CCode编程对文本控件信息的编码格式转换(Vspy系列应用1)

1、目的

        通讯矩阵中有用于发送歌曲信息的报文信号;现需在Vspy的“Graphical Pannels”下制作面板,在文本框中输入歌曲名,通过报文将输入的歌曲名以utf8编码格式进行发送

2、GB2312编码格式及格式转换

2.1、 GB2312编码格式介绍

        在Vspy中,关于中文使用的是GB2312编码格式(英文数字则是使用ASCII码);接下来,我们对涉及到的GB2312编码进行简单的介绍。
        在GB2312编码格式中,每个字符是以两个字节来表示 。其中,第一个字节称为“高位字节”,也称为区码,使用了0xA1-0xF7(把01-87区的区号加上0xA0)。第二个字节称为“低位字节”,也称为位码,使用了0xA1-0xFE(把01-94加上0xA0)。例如 “啊”字“是GB2312之中的第一个汉字,它的区位码就是1601(第16区第一位),则其GB2312编码是0xB0A1(0xB0=0xA0+区码16,0xA1=0xA0+位码01)。

在这里插入图片描述
        GB2312编码中,将所收录的字符分为 94 个区,编号为 01 区至 94 区;每个区收录 94 个字符,编号为 01 位至 94 位。各区的分配类型如下,其中,汉字的分配范围是在16区–87区。
在这里插入图片描述

2.2、 GB2312编码格式转Unicode

        可以通过MultiByteToWideChar()函数进行多字节字符到宽字符转换函数;该函数原型如下,参数设置可参考对应的注释部分:

int
WINAPI
MultiByteToWideChar(
    _In_ UINT CodePage,/*指定要转换成的字符集代码页,常用的参数是CP_ACP(表示当前系统ANSI代码页)、CP_UTF8 */
    _In_ DWORD dwFlags,/*一般设置为0即可 */
    _In_NLS_string_(cbMultiByte) LPCCH lpMultiByteStr,/*要进行转换的字符串*/
    _In_ int cbMultiByte,/*要转换字符串的长度,若为-1则表示转换到字符串结尾,并返回原字符串长度*/
    _Out_writes_to_opt_(cchWideChar, return) LPWSTR lpWideCharStr,/*用于接收转换后输出的宽字符串,如果为NULL, 则表示计算生成的字符串的长度*/
    _In_ int cchWideChar/*输出缓冲区大小,即转化生成的unicode字符串的缓存容量;为0时, 函数  将返回所需缓冲区大小*/
    );

        利用上述函数将GB2312转换为Unicode的代码如下(注意用完之后通过free()函数对malloc分配的内存进行释放):

	int wLen = MultiByteToWideChar(CP_ACP, 0, Name, -1, NULL, 0);	/*获取转换为Unicode所需的缓冲区大小(注意此时的单位是宽字符)*/
	LPWSTR Name_Unicode = NULL;
	Name_Unicode = (LPWSTR)malloc((sizeof(WCHAR))* wLen);          /*分配空间*/
	MultiByteToWideChar(CP_ACP, 0, Name, -1, Name_Unicode, wLen);  /*进行编码转换*/

2.3、 Unicode编码格式转Utf8

        可以通过WideCharToMultiByte()函数将宽字符串转换成指定的字符串,如ANSI,UTF8等,新字符串不必是多字节字符集;该函数原型如下,参数设置与上一小节的MultiByteToWideChar()函数基本一致:

int
WINAPI
WideCharToMultiByte(
    _In_ UINT CodePage,/*指定要转换成的字符集代码页,常用的参数是CP_ACP(表示当前系统ANSI代码页)、CP_UTF8 */
    _In_ DWORD dwFlags,/*一般设置为0即可 */
    _In_NLS_string_(cchWideChar) LPCWCH lpWideCharStr,/*要进行转换的字符串*/
    _In_ int cchWideChar,/*要转换字符串的长度,若为-1则表示转换到字符串结尾,并返回原字符串长度*/
    _Out_writes_bytes_to_opt_(cbMultiByte, return) LPSTR lpMultiByteStr,/*用于接收转换后输出的字符串,如果为NULL, 则表示计算生成的字符串的长度*/
    _In_ int cbMultiByte,/*输出缓冲区大小,即转化生成的字符串的缓存容量;为0时, 函数  将返回所需缓冲区大小*/
    _In_opt_ LPCCH lpDefaultChar,/*一般设置为NULL即可 */
    _Out_opt_ LPBOOL lpUsedDefaultChar/*一般设置为NULL即可 */
    );

        利用上述函数将Unicode转换为Utf8编码的代码如下(注意用完之后通过free()函数对malloc分配的内存进行释放):

	int Len = WideCharToMultiByte(CP_UTF8, 0, Name_Unicode, -1, NULL, 0, NULL, NULL);	 /*获取转换为Utf8所需的缓冲区大小*/
	char * Name_Utf8 = NULL;
	Name_Utf8 = (char *)malloc((sizeof(char))* Len);/*分配空间*/
	WideCharToMultiByte(CP_UTF8, 0, Name_Unicode, -1, Name_Utf8, Len, NULL, NULL);/*进行编码转换*/

2.4、 Utf8编码格式转GB2312

        在前两小节我们介绍了通过MultiByteToWideChar()函数和WideCharToMultiByte()函数将GB2312编码转换为Utf8的步骤。当我们想反过来将Utf8转换为GB2312编码时,其操作如下:先通过MultiByteToWideChar()函数将Utf8转换为Unicode编码(第一个参数设置为CP_UTF8);再通过WideCharToMultiByte()函数将Unicode转换为GB2312编码(第一个参数设置为CP_ACP)即可。对应代码如下:

	int wLen1 = MultiByteToWideChar(CP_UTF8, 0, Name_Utf8, -1, NULL, 0);/*假设要转换的Utf8码存储在Name_Utf8中*/						 
	char * Name_Unicode1 = NULL;
	Name_Unicode1 = (char *)malloc((sizeof(char))* wLen1);
	MultiByteToWideChar(CP_UTF8, 0, Name_Utf8, -1, Name_Unicode1, wLen1);
	
	int Len1 = WideCharToMultiByte(CP_ACP, 0, Name_Unicode1, -1, NULL, 0, NULL, NULL);	 
	char * Name_GB2312 = NULL;
	Name_GB2312 = (char *)malloc((sizeof(char))* Len1);
	WideCharToMultiByte(CP_ACP, 0, Name_Unicode1, -1, Name_GB2312, Len1, NULL, NULL);

        

3、操作步骤

(1)、定义用于发送的报文
        在"Message Editor"界面下,根据通讯矩阵中关于该报文的描述定义该发送报文;或者已经有dbc的情况下从dbc中导入到"Transmit"中;

(2)、定义存储文本信息的App Signal
        定义一个文本类型的App Signal,用于存储我们输入的文本信息;如下:
在这里插入图片描述
(3)、创建Text Entry控件
        在“Graphical Pannels”下放置一个文本输入框(Text Entry)控件;关联上前面一步定义的App Signal。如下:
在这里插入图片描述

在这里插入图片描述
        
        Ps:关于前面三点的操作,可以查看“Vspy常用操作”的相关介绍(第5、第7小节内容);这里不对步骤进行详细操作介绍。

(4)、新建C Code工程
        在C Code Interface中新增C工程;此时,前面定义的App Signal、报文等信息都会在工程中的SpyCCode.c中自动生成对应的接口操作函数。

(5)、在C Code工程代码中进行编码格式转换
        在上一步新建的C工程中;通过自动生成的App Signal接口获取其文本值(如下的AS_NameOfSong_GetText()函数);因为在Vspy中,关于中文使用的是GB2312编码格式(英文数字是使用ASCII码);所以我们需要通过编程对其进行编码格式的转换。代码如下:

int GetNameOfSong(void)
{ 
	unsigned char Name[512];
	AS_NameOfSong_GetText(Name);			/*获取文本控件的输入信息*/

	unsigned short LengthOfSongName = 0u;
	for (int i = 0; i < strlen(Name); i++) /*计算歌曲名字字符长度*/
	{
		if (Name[i] < 0xA1)				   /*是数字英文字符*/
		{
			LengthOfSongName++;
		}
		else
		{
			if ((Name[i + 1] > 0xA0) && (Name[i + 1] < 0xFF))	/*是GB2312编码*/
			{
				LengthOfSongName++;
				i++;
			}
		}
	}

	/*GB2312转Unicode*/
	int wLen = MultiByteToWideChar(CP_ACP, 0, Name, -1, NULL, 0);	
	LPWSTR Name_Unicode = NULL;
	Name_Unicode = (LPWSTR)malloc((sizeof(WCHAR))* wLen);
	MultiByteToWideChar(CP_ACP, 0, Name, -1, Name_Unicode, wLen);

	/*Unicode转Utf8*/
	int Len = WideCharToMultiByte(CP_UTF8, 0, Name_Unicode, -1, NULL, 0, NULL, NULL);	 
	char * Name_Utf8 = NULL;
	Name_Utf8 = (char *)malloc((sizeof(char))* Len);
	WideCharToMultiByte(CP_UTF8, 0, Name_Unicode, -1, Name_Utf8, Len, NULL, NULL);
		
	return 0;

(6)、通过生成的_Tranmit(参数)函数接口进行报文发送,操作可对应查看“Vspy工程之C Code Interface的使用”一文中4.2小节中对其的使用介绍。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值