当前位置: 首页 > 工具软件 > CEGUI > 使用案例 >

CEGUI学习笔记

耿联
2023-12-01

写3d程序没个像样的GUI界面可不行,最近没啥事也来捣腾一下CEGUI。果然是个不错的东东,用起来很方便,新版本已经支持dx10了,就是对中文的支持还是那么“不主动”。

1,中文显示,这个到处都能找到解决方法。就是装载一个支持中文显示的font,然后保存程序代码的时候选择

正确的utf8编码。有的说保存成“带签名utf8”,可是我的保存成“不带签名utf8”才正确。

2,中文输入,这个似乎不是那么复杂了,只要在响应WM_CHAR消息的时候直接调用“injectChar

((CEGUI::utf32)wParam)”就行了(有的说要对中文的"wParam"进行合并,有的说要转成宽字符,而我是在DXUT

框架的MsgProc中调用injectChar的,直接传入就行)。另外还要注意的一个是injectKeyDown、injectKeyUp的

传参是键盘扫描码,要是字符的话就用MapVirtualKey转化一下。

3,让EditBox响应 Ctrl+C Ctrl+V 的复制粘贴事件。这个捣了好久,终于还是搞定了。主要是CEGUI自带的String和标准的string的中文编码不一致,要相互转换。
首先是提交一个响应“Window::EventCharacterKey”事件的函数,然后在函数里面判断输入的是否是ctrl+c,Ctrl+v 值再做相应的粘贴板处理。相应的处理代码及编码转化代码见下:


CEGUI::String CEGUIRender::encode(const char * c)
{
static CEGUI::String str;
WCHAR e;
str.clear();
int i = 0;
while(c[i])
{
   if(unsigned char(c[i])>=161)
   {
    MultiByteToWideChar(0,0,c+i,2,&e,1);
    str.append(1,e);
    i+=2;
   }
   else
   {
    str.append(1,c[i]);
    i++;
   }
}
return str;
}

std::string CEGUIRender::decode(const CEGUI::String& str)
{
const char* chTemp = str.c_str();
WCHAR*     strA;      

int i= MultiByteToWideChar(CP_UTF8,0 ,(char*)chTemp,-1,NULL,0);
strA = new WCHAR[i];      
MultiByteToWideChar(CP_UTF8,0,(char*)chTemp,-1,strA,i);   

i= WideCharToMultiByte(CP_ACP,0,strA,-1,NULL,0,NULL,NULL);
char *strB = new char[i];
WideCharToMultiByte (CP_ACP,0,strA,-1,strB,i,NULL,NULL);

std::string strReturn = std::string(strB);
delete strA;
delete strB;

return strReturn;
}

bool CEGUIRender::OnEditBoxKeyDown(const CEGUI::EventArgs& e)
{
CEGUI::KeyEventArgs* kEvent = (CEGUI::KeyEventArgs*)&e;
Window* wBox = kEvent->window;

HGLOBAL clipbuffer;
char * buffer;
std::string strTemp;
CEGUI::String guiStr;
CEGUI::String guiStrTemp;
int iStart,iLen;
//WinLog("%d",kEvent->codepoint);

guiStr = wBox->getText();
iStart = ((Editbox*)wBox)->getSelectionStartIndex();
iLen = ((Editbox*)wBox)->getSelectionLength();

switch (kEvent->codepoint)
{
case 3://ctrl+c copy selected text to clipboard

   if(iLen==0)break;
   guiStr = guiStr.substr(iStart,iLen);
   strTemp = decode(guiStr);
   if(OpenClipboard(0))
   {
    EmptyClipboard();
    clipbuffer = GlobalAlloc(GMEM_DDESHARE, strTemp.length()+1);
    buffer = (char*)GlobalLock(clipbuffer);
    strcpy(buffer, strTemp.c_str());
    GlobalUnlock(clipbuffer);
    SetClipboardData(CF_TEXT,clipbuffer);
    CloseClipboard();
   }
   break;

case 24: //ctrl+x cut the selected text to clipboard
   if(iLen==0)break;
   wBox->setText(guiStr.substr(0,iStart)+guiStr.substr(iStart+iLen,guiStr.length()-(iStart+iLen)));
   ((Editbox*)wBox)->setCaratIndex(iStart);
   guiStr = guiStr.substr(iStart,iLen);
   strTemp = decode(guiStr);
  
   if(OpenClipboard(0))
   {
    EmptyClipboard();
    clipbuffer = GlobalAlloc(GMEM_DDESHARE, strTemp.length()+1);
    buffer = (char*)GlobalLock(clipbuffer);
    strcpy(buffer, strTemp.c_str());
    GlobalUnlock(clipbuffer);
    SetClipboardData(CF_TEXT,clipbuffer);
    CloseClipboard();
   }
   break;

case 22://ctrl+v insert the clipboard data

   if (!IsClipboardFormatAvailable(CF_TEXT)) break;
   if (!OpenClipboard(0)) break;
   HGLOBAL hMem = GetClipboardData(CF_TEXT);
   if (hMem != NULL)
   {
    LPTSTR lpStr = (LPTSTR)GlobalLock(hMem);
    if (lpStr != NULL)
    {
     strTemp = std::string((char*)lpStr);
     GlobalUnlock(hMem);
    }
    else strTemp="";
   }
   else strTemp="";
         CloseClipboard();

   if( strTemp.length() == 0)break;
   guiStrTemp = encode(strTemp.c_str());
   wBox->setText(guiStr.substr(0,iStart)+guiStrTemp+guiStr.substr(iStart+iLen,guiStr.length()-(iStart+iLen)));
   ((Editbox*)wBox)->setCaratIndex(iStart+guiStrTemp.length());

   break;
}
return true;
}

 类似资料: