CEGUI/OIS的中文输入与显示

来源:互联网 发布:大数据发展前景 编辑:程序博客网 时间:2024/04/29 05:13
 CEGUI是OGRE默认推荐的一个界面库.虽然Ogre官方表示CEGUI不是唯一的选择,但是我想很多人会因为Ogre的关系而选择CEGUI库.

  使用了一段CEGUI库后,感觉还是比较方便.我在CEGUI官网下了那个编辑器,用起来很简单,不过似乎某些地方还是存在一些无伤大雅的BUG.CEGUI最大的问题在于对中文的支持.CEGUI中文的显示网上的解决方案转贴得太多了,而且这个解决方案也的确工作得很好.不过对CEGUI的中文输入我有自己的看法.

  目前网上解决方案大多是不使用Ogre的默认的窗口,而是自己使用windows API创建自己的窗口,处理WM_CHAR消息,实现中文输入.但我觉得这个方案似乎动作太大了点.自己管理窗口意味着自己还要处理一些诸如窗口移动等许多消息.我个人觉得麻烦.一个程序员,尤其是一个业余程序员,要节省自己的时间,唯一的办法就是不要自己发明轮子.

  我花了大概一天的时间在网上查找资料.整个中文输入的流程大概是这样:当客户输入中文的时候,windows系统的ime库拦截到响应的输入信息,做出一系列处理后,将输入转换成中文,把结果用WM_CHAR消息发送给应用程序,然后应用程序处理WM_CHAR消息,在相应的输入窗口显示中文.整个流程看起来是这样:

    输入的按键消息 -> IME转换为中文 -> IME发送WM_CHAR消息 -> 应用程序窗口响应并显示消息

  Ogre之所以存在中文输入的问题在于Ogre的默认窗口是不能处理WM_CHAR消息的.我知道国内解决这个问题除了上面说的办法外,还有个办法是修改Ogre的源代码.但是同样的,这个手术太大了.既然问题在于应用程序的窗口不能响应消息,那我们就想个办法自己处理WM_CHAR消息好了.毕竟IME的工作是很正常的,即便我们使用的是Ogre默认窗口,WM_CHAR仍然在发送.

  解决这个问题也不是新鲜的技术,那就是钩子HOOK.因为整个程序的源代码都是自己写,所以我可以使用一个局部钩子,直接添加个函数进源代码.这个函数看上去是这样:

 

LRESULT CALLBACK ChineseCharHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
     if(nCode < 0)
          return CallNextHookEx(g_hHook,nCode,wParam,lParam);

     if(!ImmIsIME(GetKeyboardLayout(0)))
          return CallNextHookEx(g_hHook,nCode,wParam,lParam);

     MSG* msg = (MSG*)lParam;
     switch(msg->message)
     {
     case WM_CHAR:
         {

        CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::Return);
            break;
           }

            default:
          {
                CEGUI::utf32 utf = (CEGUI::utf32)(msg->wParam);
                CEGUI::System::getSingleton().injectChar(utf);

            break;

        }
         return true;

    }

     return CallNextHookEx(g_hHook,nCode,wParam,lParam);
}

 

ImmIsIME(GetKeyboardLayout(0))这个函数检查输入法状态是否打开.所以这个函数的作用就是检查输入法,当打开输入法的时候把输入转换成CEGUI可以识别的模式.

另外在构造和析构函数要分别添加:

g_hHook =SetWindowsHookEx(WH_GETMESSAGE,ChineseCharHookProc,NULL,GetCurrentThreadId())

UnhookWindowsHookEx(g_hHook)

语句.OIS的capture代码段要加入对输入法状态的判断,否则会造成双重输入.

原创粉丝点击