OGre(1.65)+CEGUI的中文显示和中文输入,新人必看

第一次学博客,好刺激。刚学Ogre一个星期,遇到了一些难点,但经过网海的打捞终于慢慢的前行。今天遇到的中文显示和输入的问题!中文显示还好弄的,但中文输入我历经九九八十一个网页,却终究没能解决,正值吃饭之际,也不知是怎么打开的一个充满神奇的网页,里面居然又源代码,而且还是1.60版本的Ogre(我用的1.65,虽然出了1.70但是我的机子运行出了点问题。反正初学能用就好了)。内容十分相近,下载一下,稍稍阅读,震惊不已。Application的cpp里面就两行就“解决”了!感慨万分之余,怕以后和我一样的新人在受此折磨,决定于今晚11点告诉大家我捞得的解决方案,另外附带源代码!好了,就铺垫这么多,下来让我们看看如何实现中文显示和中文输入吧!惊心动魄哦!

一:中文显示

     1:首先拷贝C:/WINDOWS/Fonts目录下面的一个字体文件(例如simhei.ttf)到你OgreSDK/medias/fonts目录下(例如D:/Orge/OgreSDK/media/fonts),随便打开一个.font文件(记事本或写字板打开方式),复制里面的格式,自己创建一个.font文件,拷贝进去(例如:<?xml version="1.0" ?>
<Font Name="Chinese" Filename="simhei.ttf" Type="FreeType" Size="12" NativeHorzRes="800" NativeVertRes="600" AutoScaled="true"/>)保存起来,名字最好和FontName里面一样(其实没太大需要,如果你理解的话)。

    2:修改OgreSDK/media/gui下面的文件TaharezLookSkin.scheme的内容,方法,记事本打开。看到四五六行的那写字体文件的列举了吗?对,你只需要将自己的字体文件列举上就可以了。在这三行之间任意插入一行,按照那些列举的方法,例如(<Font Name="Chinese" Filename="chinese.font" />),再保存就好。

   3:再修改你程序里面的CEGUI::System*指针对象设置的默认字体。方法:在createScene里面有一条语句:mGUISystem->setDefaultFont((CEGUI::utf8*)"Chinese");(这里默认你用OgreApplicationWizard创建的带有CEGUI附带选项的工程,如果你是自己一点一点加的话,那就自己照吧。不过建议用OgreApplicationWizard工具,新手省事。),然后你可以在你程序中使用中文了。不过setText等里面的参数要稍加加工。参数为:(CEGUI::utf8*)Ogre::UTFString(L"中文退出").asUTF8_c_str(),不过网上还有好几种方法。我用的是另一种,不过都一样了。

 

二:中文显示(网上有很多方法,有消息钩,还有修改头文件的。消息钩我原本不知道什么意思,但后来看得多了,也大体明白了一点。但我的程序还是不行。而且新手都不太懂怎么安排代码。所以我给新手一个绝佳的方法。我觉得只要你编过程序就可以实现中文输入。)

    1:把CEGUICHSSupport.hpp和CEGUICHSSupport.cpp(你可以根据我后面发的代码自己创建)加到你的工程里面(别说你不会,例如右击源文件点添加现有项),让后再你程序的cpp里面加上#include "CEGUICHSSupport.hpp",而且要在项目属性/c/c++里面的附加目录项,新建选择CEGUICHSSupport.hpp和CEGUICHSSupport.cpp所在目录。

    2:然后你在TutorialApplication1FrameListener类里面的bool keyPressed( const OIS::KeyEvent &arg )函数里面把它原来自带的CEGUI::System::getSingleton().injectKeyDown( arg.key );以及CEGUI::System::getSingleton().injectChar( arg.text );删除或者注释,替换成

if( !CEGUICHSSupport::IsLocked() )
  {
   CEGUI::System::getSingleton().injectKeyDown( arg.key );
  }  

  //下面这句,处理中文
  CEGUICHSSupport::injectChar(  mWindow ,  (CEGUI::utf32)arg.text );

并确定你的程序使用多字节编码。Unicode会出现乱码!

Ok!大功告成。随便找个编辑框试一试吧!

博客没提供附件功能吗?那我上传资源吧!设为需要0资源分数。居然不能上传资源了。那直接把源码内容发给大家。大家自己创建相应的头文件和cpp文件吧。

CEGUICHSSupport.hpp:

#pragma once #include <OgreRenderWindow.h> #include <CEGUI.h> class CEGUICHSSupport { public: static bool injectChar( Ogre::RenderWindow* pWin, CEGUI::utf32 code_point ); public: inline static bool IsLocked() { return m_bIsLock; } protected: static bool MakeWChar( unsigned char code_point ); static LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); protected: static bool m_bIsOk; static bool m_bIsLock; static WNDPROC m_funcOldWndProc; };

CEGUICHSSupport.cpp:

#include "CEGUICHSSupport.hpp" #include <Imm.h> #pragma comment( lib, "Imm32.lib" ) #include <cassert> #ifndef AssertEx #define AssertEx( exp, msg ) assert( exp && msg ) #endif bool CEGUICHSSupport::m_bIsOk = false; bool CEGUICHSSupport::m_bIsLock = false; WNDPROC CEGUICHSSupport::m_funcOldWndProc = NULL; LRESULT CEGUICHSSupport::WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch( uMsg ) { case WM_IME_COMPOSITION: { if( lParam & GCS_COMPSTR ) { HIMC hIMC = ImmGetContext( hWnd ); TCHAR szBuf[1280] = {0}; DWORD dwSize = ImmGetCompositionString( hIMC, GCS_COMPSTR, (void*)szBuf, 1280 ); if( dwSize != 0 ) { m_bIsLock = true; } else { m_bIsLock = false; } } } break; case WM_CHAR : { MakeWChar( (CEGUI::utf32)wParam ); } break; } AssertEx( m_funcOldWndProc != NULL, "不可为空" ); return CallWindowProc( m_funcOldWndProc , hWnd , uMsg , wParam , lParam ); } bool CEGUICHSSupport::MakeWChar( unsigned char code_point ) { using namespace CEGUI; static char s_tempChar[3] = ""; static wchar_t s_tempWchar[2] = L""; static bool s_flag = false; unsigned char uch = code_point; if( uch >= 0x81 || s_flag ) { if( !s_flag ) { s_tempChar[0] = (char)uch; s_flag = true; return true; } else if( uch >= 0x40 ) { s_tempChar[1] = (char)uch; s_flag = false; MultiByteToWideChar( 0, 0, s_tempChar, 2, s_tempWchar, 1); s_tempWchar[1] = L'/0'; utf32 code = (utf32)s_tempWchar[0]; return CEGUI::System::getSingleton().injectChar( code ); } else { if ( !ImmIsIME(GetKeyboardLayout(0))) { return CEGUI::System::getSingleton().injectChar(code_point); } } } else { s_flag = false; return CEGUI::System::getSingleton().injectChar(code_point); } return false; } bool CEGUICHSSupport::injectChar( Ogre::RenderWindow* pWin, CEGUI::utf32 code_point ) { AssertEx( pWin != NULL, "RenderWindow不能为空..." ); if( !m_bIsOk ) { HWND hWnd = NULL; pWin->getCustomAttribute( "WINDOW", &hWnd ); if( NULL == hWnd ) { throw std::runtime_error( "获取系统句柄失败..." ); } m_funcOldWndProc = (WNDPROC)::GetWindowLong( hWnd, GWL_WNDPROC ); ::SetWindowLong( hWnd, GWL_WNDPROC, (LONG)WndProc ); m_bIsOk = true; return false; } return true; }

最后希望中国软件能有自己的一片天地!一起努力吧!让中国的操作系统走向世界!我:QQ103406727。志同道合者加!

上一篇:Maven下载与配置


下一篇:typedef的用法小总结