现场记录:
游戏的帮助界面,使用了IHtmlViewer接口,通过读UTF8编码的html格式文件help.html载入帮助信息,载入IHtmlViewer控件进行显示,程序运行时发现在显示内容的第一行总会有一行的空白,且在LG KV500手机上第一行空白的开头还会带一个方框状的乱码。
原因分析:
Unicode编码方式的文件会有标志位,具体如下:
unicode文件头的标识
Byte-order mark Description
EF BB BF UTF-8
FF FE UTF-16 aka UCS-2, little endian
FE FF UTF-16 aka UCS-2, big endian
00 00 FF FE UTF-32 aka UCS-4, little endian.
00 00 FE FF UTF-32 aka UCS-4, big-endian.
为了显示中文帮助信息,help.html文档使用了UTF8方式保存,因此用读文件的方式读出的数据流头3个字节是EF BB BF,在调试时就可以清楚的看到这一点,乱码的原因就在于此。
比如新建一个文本文件,内容只有一个字母a,保存后查看文件大小是1字节,另存为unicode编码文件,查看大小,会发现文件大小是4字节。
2种解决方法:
- 将指向文件内容的指针后移3个字节 - (需要额外注意的是,如果移动了指针,利用该指针释放内存时记得先还原,再释放)。具体实现:pBuf += 3;释放时:pBuf -= 3; FREEIF( pBuf );
- 检索出头一个html标签的位置,如<HTML>的位置,具体实现:pStart = STRSTR( pBuf,"<") ;
最终代码:
if ( NULL != pf )
{
char *pBuf = NULL;
char *pStart = NULL;
IMemAStream* m_pPopAStream;
if( ISHELL_CreateInstance( GetShell(pMe), AEECLSID_MEMASTREAM, (void**)(&m_pPopAStream)) != SUCCESS )
{
return;
}
ReadFileEx( GetShell(pMe), GAME_HELP_HTML, &pBuf, NULL );
pStart = STRSTR( pBuf,"<") ;
if( NULL == pStart )
{
pStart = pBuf;
}
IMEMASTREAM_SetEx( m_pPopAStream, (void*)pStart,STRLEN(pStart)*sizeof(char), 0, NULL, NULL);
IHTMLVIEWER_LoadStream( pMe->m_pHTMLViewer, (IAStream*)m_pPopAStream);
if( NULL != pf )
{
IFILE_Release(pf);
pf = NULL;
}
if( NULL != m_pPopAStream )
{
IMEMASTREAM_Release( m_pPopAStream);
m_pPopAStream = NULL;
}
FREEIF(pBuf);
}
else
{
IHTMLVIEWER_SetData( pMe->m_pHTMLViewer, "<h1>Error</h1>File Not Found", -1);
}