• 实验六 CeGUI与中文支持的这点破事


    用的是0.7.5版本,问题其实早已不难,自己瞎捣鼓半天,虽然搞定,但终究不得正法,

    还是好好静下来看下前辈们的文章好,顺便进行一些无脑的Ctrl+C/V操纵,纯当烂笔头:

    1,首先是中文显示:

    这个其实都差不多,其实就是一个utf8转换的问题,

    估计是旧时代遗留下来节约内存的习惯吧,问题虽然不大,改天有空我一定要重新编一个Unicode版本的CeGUi(ms也有前辈做过,可惜未找到共享),

    我的具体解决方法:

    首先加载字体(改动schema也行):

    FontManager::getSingleton().createFreeTypeFont("JianTi", 10/*pt*/, true, "jianti.ttf");
    System::getSingleton().setDefaultFont("JianTi");
    然后,转换utf8:(如在FalagardDemo1中:)

        CEGUI::Window *quit = winMgr.createWindow("Vanilla/Button", "CEGUIDemo/QuitButton");
        quit->setText("Quit");
        quit->setSize(CEGUI::UVector2(CEGUI::UDim(0.15, 0), CEGUI::UDim(0.05, 0)));
        background->addChildWindow(quit);

        std::wstring aa = L"我管你123还是abc就算あいうえお也可以!";
        char buff[128] = "";
        WideCharToMultiByte(CP_UTF8, 0, aa.c_str(), aa.size(), buff, sizeof(buff), 0, 0);
        quit->setText((CEGUI::utf8*)buff);

    image

    -----代码标色的插件有挂了,将就下先~

    2,基本原理(抓住本质才能解决根本问题):

    痞子龙3D编程(unicode,ANSI,UTF-8的故事):

    http://blog.csdn.net/pizi0475/archive/2010/03.aspx

    中文编码之间的转换:

    http://blog.csdn.net/s030702614/archive/2010/06/27/5698026.aspx

    3,中文输入:

    CEGUI学习笔记四-- 如何输入中文 - 踏入神的领域 :

    http://blog.csdn.net/kun1234567/archive/2008/04/15/2294125.aspx

    一个总结:CEGUI说明文档_百度文库:

    http://wenku.baidu.com/view/fd635312a216147917112858.html

    CEGUI与其他程序剪切复制粘帖的实现(支持中文)~~~ - 李素颙~Harry的专栏:

    http://blog.csdn.net/harr999y/archive/2010/06/02/5643269.aspx

    研究cegui,写脚本 - lonelyfish的日志 :

    http://songxiaoyu8.blog.163.com/blog/static/2081812820096232432677/

    CEGUI学习笔记:

    http://blog.csdn.net/feiyun1987/archive/2009/05/29/4224488.aspx

    其实问题的关键很简单,就是预留一个字符,

    把CeGUI对字符输入的响应截取下来即可:

    好吧,动手!

    修改common\src\Win32AppHelper.cpp

    #include <imm.h>
    #pragma comment(lib,"imm32.lib")

    加入有输入法时的处理函数:

    namespace CEGUI{
        bool _injectChar(utf32 code_point )
        {
    #ifndef UNICODE
            static char     s_tempChar[3]  = "";
            static wchar_t  s_tempWchar[2] = L"";
            static bool s_flag = false;
            unsigned char  uch  = (unsigned char)code_point;
            if( uch >= 0xA1 )
            {
                if( !s_flag )
                {
                    s_tempChar[0] = (char)uch; //第一个字节
                    s_flag = true;
                    return 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';
                    utf32 code = (utf32)s_tempWchar[0];
                    //Font* fnt = System::getSingleton().getDefaultFont();
                    return CEGUI::System::getSingleton().injectChar( code );
                }
                else
                {
                    return CEGUI::System::getSingleton().injectChar(code_point);
                }
            }
            else
            {
                s_flag = false;
                return CEGUI::System::getSingleton().injectChar(code_point);
            }
    #else
            return CEGUI::System::getSingleton().injectChar(code_point );
    #endif
        }
    }

    再改下:

    case WM_CHAR:
            if (ImmIsIME(GetKeyboardLayout(0)))
            {
                CEGUI::_injectChar(wParam);
            }
            else
            {
                CEGUI::System::getSingleton().injectChar((CEGUI::utf32)wParam);
            }
            break;

    image

    熟悉win32的话这一切就实在是so easy了~~

    4,Bug

    引用一下:“

    还有一个问题就是关于BackSpace的:如果你在输入框里有字,这个时候输入法输入框里输入错了一个字符,当你按backspace的时候,CEGUI里的输入框上的字也被删了一个。这不是我们期望的行为,解决这个问题有很多途径,你可以在中间渲染层进行这些输入事件插入之前进行判断,也可以注册监听事件进行处理,但是我认为最正确的方法是在需要进行输入法输入的地方,比如EditBox的事件处理函数里特别处理backspace,当然,这需要修改CEGUIEditbox的源代码,不过这件事并不困难。。。。”

    好吧,我承认还不了解CEGUIEditbox,但我会尽快KO的!

    (ps:虽然绕了不少弯路,憋气斗气不少,但是多看了许多CeGUi的源代码,就像江湖好汉似的不打不相识,了解其些许的内部,如此亦为甚妙,心得体会真还算不上,就暂且厚颜先贴些网址上来吧,相信,很快会到运用自如的境界的,兔年,好运,奋斗~~O(∩_∩)O哈哈~~)

    5,Bug解决——110204补充:

    网上乱逛,无意中看了一些MyGUI对中文输入处理的代码,

    眉头一皱计上心来,

    问题的关键还是在于在用输入法时截取退格(Code:8)对EditBox的注入,

    首先还是对Win32AppHelper的改造:

    毛早就毛躁点吧,首先标记下:

    bool g_bImming=false;

    再在Win32AppHelper::wndProc

    case WM_IME_STARTCOMPOSITION:
                g_bImming =true;
                break;
        case WM_IME_ENDCOMPOSITION:
                g_bImming =false;
                break;

    本以为接下来会很简单的,可接下来跟踪,很是莫名奇妙,看源代码,原来是退格的消息不仅在WM_CHAR中响应,还直接注入了EditBoxz中,

    case Key::Backspace:
                  handleBackspace();
                break;

    尝试在这里修改,出bug,而且也不合适,

    估摸着自己玩网游时候打字不就是禁用了其他快捷键的响应,于是直接hack:

    在Win32AppHelper::doDirectInputEvents中修改:

    if (itemCount > 0)
            {
                if (LOBYTE(devDat.dwData) & 0x80)
                {
                    // force quit on ESCAPE key
                    if (devDat.dwOfs == CEGUI::Key::Escape)
                    {
                        PostQuitMessage(0);
                    }
                    else
                    {
                        if(!g_bImming)
                            CEGUI::System::getSingleton().injectKeyDown(devDat.dwOfs);
                    }

                }
                else
                {
                    CEGUI::System::getSingleton().injectKeyUp(devDat.dwOfs);
                }

            }

    问题成功解决,

    ps:

    发现窗口最小化后会有时丢失,不知道是不是在Debug的缘故,还待深究,

    另外,被网友说动了,去试试MyGUI,管它俄文看不懂,坚决不涅都~~~呵呵

  • 相关阅读:
    工作10年写不好一封邮件?
    邮件狂人告诉你:如何打造最强邮件处理流
    免费瘫软入院,付费发飙成壮汉,YoMail 想干嘛?
    我们要招5-10人,全要技术!
    如何有效的报告bug?
    黑科技 | 用实力打造邮件沟通新模式
    李叫兽去了百度,我们来聊聊营销
    你好,我想送你一本书
    上了这套密码锁,你就无敌了
    YoMail 邮箱客户端的社会化之路,起于邮箱,不止于邮件
  • 原文地址:https://www.cnblogs.com/Zephyroal/p/1949057.html
Copyright © 2020-2023  润新知