MyGUI中文完美解决方案
首先,得感谢,
“鸣·铭”的介绍 http://www.mobilegamebase.com/
这位兄台的截图和介绍让俺流口水,直接背离CeGUI,
MyGUI真的很不错,编辑器,Delegate,当然还有个功能齐全的EditBox,不多说了,用Ogre的同志们,what’re you waiting for?!
现在越来越觉得,要了解一套代码,最好的方法便是以bug为切入点,拨开撕裂所有的疑云!
(LiveWriter的代码插件不知道扔到哪去了,办公室又不给插u盘,看官暂且将就将就)
一,首先是中文显示:
core_font.xml添加,easy。
<Resource type="ResourceTrueTypeFont" name="JiantiFont">
<Property key="Source" value="jianti.ttf"/>
<Property key="Size" value="19"/>
<Property key="Resolution" value="50"/>
<Property key="Antialias" value="false"/>
<Property key="SpaceWidth" value="4"/>
<Property key="TabWidth" value="8"/>
<Property key="CursorWidth" value="2"/>
<Property key="Distance" value="6"/>
<Property key="OffsetHeight" value="0"/>
<Codes>
<!--一般unicode码是十六进制的,这里使用的是转换为十进制的-->
<!--键盘上所有的英文字母、标点、数字-->
<Code range="33 126"/>
<!--通用标点-->
<!--单引号-->
<Code range="8216 8217"/>
<!--双引号-->
<Code range="8220 8221"/>
<!--连接号,破折号-->
<Code range="8211 8212"/>
<!--省略号-->
<Code range="8230"/>
<!--CJK标点符号-->
<!--顿号,句号-->
<Code range="12289 12290"/>
<!--单书名号,双书名号,竖版单引号,大扩号-->
<Code range="12296 12303"/>
<!--小括号-->
<Code range="12308 12309"/>
<!--中括号-->
<Code range="12304 12305"/>
<!--ASCII全角,全角中英文标点-->
<Code range="65281 65374"/>
<!--unicode汉字范围-->
<Code range="19968 40869"/>
<Code hide="128"/>
<Code hide="1026 1039"/>
<Code hide="1104"/>
</Codes>
</Resource>
但有个问题需要注意,Layout中字体会覆盖默认字体,所以一不小心,出现问题你的注意力很可能会被带到utf-8等等问题,编码的潘多拉魔盒会让你做噩梦的,所以,一定要坚持字体,老毛子写的的代码虽然注释看不懂,可是非en支持的问题可是同病相怜的,MyGUI做得还是不错的。
二,中文输入:
网上很快找到了解决方案,“拿来主义”,你懂的。http://www.cnblogs.com/tuzhiye/archive/2010/09/12/1824456.html
可是渐渐的你会发现问题,
再回头看看帖子,三楼的回复:“你写的很多情况没有考虑,比如按一下shift切换为英文输入,比如直接输入空格,而且会有多余空格,dwSize是字节数,应该除以二的,这样就没有多余空格了,WCHAR lpWideStr[20]还会溢出,大小知道了,应该new出来,有很多情况要处理”
OMG,不给力啊,
怎么办,
还是自己动手,丰衣足食,
根据MyGUi,做了调整,
在InputManager::windowProc做了如下添加:
else if( WM_IME_ENDCOMPOSITION ==uMsg)
{
InputManager::m_bCompleted =true;
//msInputManager->injectKeyPress(MyGUI::KeyCode::None," ");
if (ImmIsIME(GetKeyboardLayout(0))&&InputManager::m_bImming)
{
HIMC hIMC;
DWORD dwSize;
hIMC = ImmGetContext(hWnd);
dwSize = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0);
dwSize += sizeof(WCHAR);
DWORD dwCount=dwSize/2;
WCHAR *lpWideStr=new WCHAR[dwCount];
memset(lpWideStr, 0,dwSize);
ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, lpWideStr, dwSize);
for (INT i = 0; i <dwCount ;i++)
{
msInputManager->injectKeyPress(MyGUI::KeyCode::None, lpWideStr[i]);
}
ImmReleaseContext(hWnd, hIMC);
//缓冲一完,肯定就进入普通状态了
InputManager::m_bImming =false;
}
}
中文支持很棒,前边提到的种种问题也都得到了解决,
但是,标点,标点哪去了?!
三,完美方案:
还是回到一开是我自己上一篇CeGUI中的解决办法:http://www.cnblogs.com/hmxp8/archive/2011/02/03/1949057.html,
但上篇也有好多问题,如一些特殊的+-,还有中文输入法下shift打英文等等问题,
一一KO,感觉尚可,在此就黄婆卖瓜自卖自夸下,还是在InputManager::windowProc,上代码:
else if(WM_CHAR == uMsg)
{
//关于中文,就交给我吧,O(∩_∩)O
if(ImmIsIME(GetKeyboardLayout(0)))
{
#ifndef UNICODE
static char s_tempChar[3] = "";
static wchar_t s_tempWchar[2] = L"";
static bool s_flag = false;
unsigned char uch = (unsigned char)wParam;
int scan_code = VirtualKeyToScanCode(wParam);
if( uch >= 0xA1 )
{
if( !s_flag )
{
s_tempChar[0] = (char)uch; //第一个字节
s_flag = true;
}
else if( uch >= 0xA1 )
{
s_tempChar[1] = (char)uch; //第二个字节
s_flag = false;
MultiByteToWideChar( 0, 0, s_tempChar, 2, s_tempWchar, 1); //转成宽字节
s_tempWchar[1] = L'\0';
wchar_t code = (wchar_t)s_tempWchar[0]; //注意,标点,也是在这里输入的
msInputManager->injectKeyPress(MyGUI::KeyCode::Enum(scan_code), (MyGUI::Char)code);
}
else
{
msInputManager->injectKeyPress(MyGUI::KeyCode::Enum(scan_code), (MyGUI::Char)wParam);
}
}
else
{
s_flag = false;
//MyGUI对这些已经做了处理,按下退格键之类时GetKeyboardLayout(0)!=0 所以在这里只要处理非scankey的字符,如+=
if(MyGUI::KeyCode::Enum(scan_code)==MyGUI::KeyCode::None)//防止消息重复处理
msInputManager->injectKeyPress(MyGUI::KeyCode::Enum(0),uch);
//msInputManager->injectKeyPress(MyGUI::KeyCode::Enum(scan_code), (MyGUI::Char)wParam);
}
#else
msInputManager->injectKeyPress(MyGUI::KeyCode::Enum(scan_code), (MyGUI::Char)text);
#endif
//return 0;//VirtualKeyToText 已经对打开IME的情况已经做了处理,不用担心
}
}
怎么样,享受MyGUi自由自在的EditBox吧!