寫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; } |