第一次学博客,好刺激。刚学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。志同道合者加!