Posted on 2008-05-05 15:31
RichardHe 阅读(1869)
评论(5) 编辑 收藏 引用
CEGUI的中文输入:目前为止为我解决的也是参考别人的方法改的代码,不知道哪位兄台有更好的解决方案?源码如下:
filename: Win32AppHelper.h
在后面加一个
private:
static bool d_mouseInWindow;
static bool d_backSpace;//添加的成员变量
filename: Win32AppHelper.cpp
bool Win32AppHelper::d_backSpace = false;
/*************************************************************************
Win32 'Window Procedure' function
*************************************************************************/
LRESULT CALLBACK Win32AppHelper::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CHAR:
{
if (ImmIsIME(GetKeyboardLayout(0)))
{
CEGUI::injectChar((CEGUI::utf32)wParam); //方法在下面的全局函数
}
else
{
CEGUI::System::getSingleton().injectChar((CEGUI::utf32)wParam);
}
}
break;
case WM_IME_ENDCOMPOSITION:
d_backSpace = true;
break;
case WM_IME_STARTCOMPOSITION:
d_backSpace = false;
break;
case WM_MOUSELEAVE:
mouseLeaves();
break;
case WM_NCMOUSEMOVE:
mouseLeaves();
break;
case WM_MOUSEMOVE:
mouseEnters();
CEGUI::System::getSingleton().injectMousePosition((float)(LOWORD(lParam)), (float)(HIWORD(lParam)));
break;
case WM_LBUTTONDOWN:
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);
break;
case WM_LBUTTONUP:
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton);
break;
case WM_RBUTTONDOWN:
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::RightButton);
break;
case WM_RBUTTONUP:
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::RightButton);
break;
case WM_MBUTTONDOWN:
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::MiddleButton);
break;
case WM_MBUTTONUP:
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::MiddleButton);
break;
case 0x020A: // WM_MOUSEWHEEL:
CEGUI::System::getSingleton().injectMouseWheelChange(static_cast<float>((short)HIWORD(wParam)) / static_cast<float>(120));
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SIZE:
// TODO: Notify about new size
break;
case WM_PAINT:
{
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
}
default:
return(DefWindowProc(hWnd, message, wParam, lParam));
break;
}
return 0;
}
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
}
}
至于退格键的解决方法如下,开始一直是在输入法状态下,如果按退格,不但删除字母,同时也删除了开始打好的了字.
1 void Win32AppHelper::doDirectInputEvents(const Win32AppHelper::DirectInputState& dis)
2 {
3 // handle direct input based inputs
4 DIDEVICEOBJECTDATA devDat;
5 DWORD itemCount = 1;
6
7 HRESULT res = dis.keyboardDevice->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &devDat, &itemCount, 0);
8
9 if (SUCCEEDED(res))
10 {
11 if (itemCount > 0)
12 {
13 if (LOBYTE(devDat.dwData) & 0x80)
14 {
15 // force quit on ESCAPE key
16 if (devDat.dwOfs == CEGUI::Key::Escape)
17 {
18 PostQuitMessage(0);
19 }
20 else
21 {
22 if(!ImmIsIME( GetKeyboardLayout(0))) //输入法没关闭的时候才识别键盘事件可以防止backspace的bug
23 {
24 CEGUI::System::getSingleton().injectKeyDown(devDat.dwOfs);
25 }
26 if (d_backSpace) //解决退格时要到英文状态下才可以删除的问题.
27 {
28 CEGUI::System::getSingleton().injectKeyDown(devDat.dwOfs);
29 }
30 }
31
32 }
33 else
34 {
35 CEGUI::System::getSingleton().injectKeyUp(devDat.dwOfs);
36 }
37
38 }
39 }
40 else
41 {
42 // try to re-acquire device if that was the cause of the error.
43 if ((res == DIERR_NOTACQUIRED) || (res == DIERR_INPUTLOST))
44 {
45 dis.keyboardDevice->Acquire();
46 }
47
48 }
49
50 }
上面的winpro方法里面我添加了两个消息处理.
WM_IME_ENDCOMPOSITION
WM_IME_STARTCOMPOSITION
具体说明请查找MSDN!
中文显示问题请看前面一天的随笔!