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吧!

posted @ 2011-04-13 10:49  Zephyroal  阅读(7085)  评论(7编辑  收藏  举报