天龙源码分析 - cegui 中文输入

本文详细介绍了Windows环境下输入框和编辑框如何处理英文、中文和其他特殊字符输入,包括字符转换、复制粘贴操作、键盘快捷键应用以及中文输入法的集成与操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 普遍字符输入

case WM_CHAR:
     WCHAR szCharW;
     CHAR szChar 
= (CHAR)LOWORD(wParam);
     
if(szChar >= 32 && szChar <= 128 )
     {
      ::MultiByteToWideChar(CP_ACP, 
0, (LPCSTR)&szChar, 1&szCharW, 1);

      
//AxTrace(0, 1, "Char:%02X", szCharW);
      CEGUI::System::getSingleton().injectChar((CEGUI::utf32)szCharW);
     }

 

二 中文输入

        case WM_IME_COMPOSITION:
            OutputDebugStringW( L
"WM_IME_COMPOSITION\n" );
            {
                LONG lRet;  
// Returned count in CHARACTERS
                WCHAR wszCompStr[MAX_COMPSTRING_SIZE];
                
bool bRet = false;

                
//*trapped = true;
                if( NULL == ( hImc = _ImmGetContext( GetHWND() ) ) )
                {
                    
break;
                }

                
if ( lParam & GCS_RESULTSTR )
                {
                    OutputDebugStringW( L
"  GCS_RESULTSTR\n" );
                    lRet 
= _ImmGetCompositionStringW( hImc, GCS_RESULTSTR, wszCompStr, sizeof( wszCompStr ) );
                    
if( lRet > 0 )
                    {
                        lRet 
/= sizeof(WCHAR);
                        wszCompStr[lRet] 
= 0;  // Force terminate
                        for(int i = 0; i <lRet; ++i )
                        {
                            
//AxTrace(0, 0, "Result:%02X", (WCHAR)wszCompStr[i]);
                            CEGUI::System::getSingleton().injectChar((WCHAR)wszCompStr[i]);
                        }
                    }
                    bRet 
= true;
                }

                _ImmReleaseContext( GetHWND(), hImc );

                
// Adjust Ime Window Pos. [4/21/2006]
                
//SetImeWindowPos();
                return bRet;
            }

 

 

三 特殊字符输入

        case WM_KEYDOWN:
            {
                
switch ( wParam )
                {
                
case VK_SHIFT:
                    CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::LeftShift);
                    
break;

                
case VK_CONTROL:
                    CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::LeftControl);
                    
break;

                
case VK_DELETE:
                    CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::Delete);
                    
break;

                
case VK_LEFT:
                    CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::ArrowLeft);
                    
break;

                
case VK_RIGHT:
                    CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::ArrowRight);
                    
break;

                
case VK_UP:
                    CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::ArrowUp);
                    
break;

                
case VK_DOWN:
                    CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::ArrowDown);
                    
break;

                
case VK_HOME:
                    CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::Home);
                    
break;

                
case VK_END:
                    CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::End);
                    
break;
                }
            }
            
break;

 

 

四 复制/粘贴

            case VK_CANCEL: // Ctrl-C Copy
            case 24:        // Ctrl-X Cut
                {
                    CEGUI::EditboxInterface
* pEdit = GetActiveIMEEditBox_Interface();
                    
if(pEdit)
                    {
                        
if(0 != pEdit->getSelectionLength() && !(pEdit->isTextMasked()))
                        {
                            
//utf32 selection string
                            CEGUI::String32 szSel = (GetActiveIMEEditBox())->getText().substr(pEdit->getSelectionStartIndex(), pEdit->getSelectionLength());

                            size_t length 
= szSel.length();
                            
if(length > 0)
                            {
                                size_t pos 
= 0;
                                wchar_t
* pWtxt = new wchar_t[length+1];
                                pWtxt[length] 
= 0;
                                
//utf32 -> utf16
                                while(length--)
                                {
                                    pWtxt[pos] 
= szSel.at(pos) & 0xFFFF;
                                    pos
++;
                                }

                                
//paste to clipboard
                                if(::OpenClipboard(::GetTopWindow(NULL)))
                                {
                                    ::EmptyClipboard();
                                    
                                    
int size = ::WideCharToMultiByte(CP_ACP,0,pWtxt,wcslen(pWtxt),NULL,0,NULL,FALSE);
                                    
//alloc mem
                                    HGLOBAL hglb = ::GlobalAlloc(GMEM_MOVEABLE,(size_t)size+1);
                                    
char* ptxt = (char*)::GlobalLock(hglb);
                                    ptxt[size] 
= 0;
                                    
//utf16 -> ansi char
                                    ::WideCharToMultiByte(CP_ACP,0,pWtxt,wcslen(pWtxt),ptxt,size,NULL,FALSE);
                                    ::GlobalUnlock(hglb);
                                    
//copy to clipboard
                                    ::SetClipboardData(CF_TEXT, hglb);
                                    ::CloseClipboard();
                                    
//free mem
                                    ::GlobalFree(hglb);
                                }

                                delete [] pWtxt;

                                
if((WCHAR)wParam == 24/*Ctrl-X need clear selection*/
                                {
                                    CEGUI::System::getSingleton().injectKeyDown(CEGUI::Key::Delete);
                                }
                            }
//end of if(length > 0)
                        }
                    }
// end of if(pWin)
                }
                
break;

            
// Ctrl-V Paste
            case 22:
                {
                    CEGUI::EditboxInterface
* pWin = GetActiveIMEEditBox_Interface();
                    
if(pWin)
                    {
                        
if(::IsClipboardFormatAvailable(CF_TEXT) && ::OpenClipboard(::GetTopWindow(NULL)))
                        {
                            HGLOBAL hglb 
= ::GetClipboardData(CF_TEXT);
                            
if(NULL != hglb)
                            {
                                
char* ptxt = (char*)::GlobalLock(hglb);

                                
int size = ::MultiByteToWideChar(CP_ACP,0,ptxt,(int)strlen(ptxt),NULL,0);
                                wchar_t
* pWtxt = new wchar_t[size+1];
                                pWtxt[size] 
= 0;

                                ::MultiByteToWideChar(CP_ACP,
0,ptxt,(int)strlen(ptxt),pWtxt,size);

                                ::GlobalUnlock(hglb);
                                ::CloseClipboard();

                                
int pos = 0;
                                
while(size--)
                                {
                                    CEGUI::System::getSingleton().injectChar((CEGUI::utf32)pWtxt[pos]);
                                    pos
++;
                                }
                            }
// end of if(NULL != hglb)
                        }
                    }
// end of if(pWin)
                }
                
break;

 

 

五 输入框定位

void SetImeWindowPos(void)
{
    
//Set Ime Wnd Position.
    CEGUI::EditboxInterface* pEdit = GetActiveIMEEditBox_Interface();
    
if(NULL == pEdit) return;

    CEGUI::Window
* pWnd = GetActiveIMEEditBox();
    
if(NULL == pWnd) return;

    CEGUI::Rect ceguiRect 
= pEdit->getCaratTextExtent();
    
if(ceguiRect.getWidth() < 0.01f && ceguiRect.getHeight() < 0.01freturn;

    POINT pt;
    pt.x 
= (long)ceguiRect.d_left;
    
//pt.y = (long)ceguiRect.d_bottom;
    pt.y = (long)ceguiRect.d_top;

    HIMC hImc 
= _ImmGetContext(GetHWND());
    
if(NULL == hImc) return;

    COMPOSITIONFORM imeForm;
    imeForm.dwStyle 
= CFS_POINT;
    imeForm.ptCurrentPos 
= pt;

    _ImmSetCompositionWindow(hImc,
&imeForm);
    _ImmReleaseContext(GetHWND(),hImc);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值