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

一 普遍字符输入

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.01f return ;

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

 

你可能感兴趣的:(源码分析)