松鼠的博客

导航

统计

Windows中文输入法的实现

正文

                             windows 中文输入法的实现   

      本人设计了一个“3++输入法”,可运行操作系统 windows95/98/nt/2000,“3++输入法”为纯形码,无需识别码,易学,易用,录入速度快,含“简体、繁体、专业”三种版本,字根量小,词组数大于26000个,全部重码数仅为73个,您可以在 http://www.csdn.net/cnshare/ 下搜索“3++输入法”下载软件,或在:http://www.anycities.com/user1/3jj/  下载。欢迎各位试用并提出宝贵意见。如有问题可发email:w3jj@yahoo.com.cn 给我。
       限于篇幅,windows系统下汉字输入法的基本原理,大家可参考 msdn 中的有关文档。本人仅对程序设计的实现方法说明如下:
      一、在 windows 任务栏中增加输入法名称
       这也就是 setup 程序的关键,实际上,可以利用 imminstallime 函数。该函数的原形是:hkl imminstallime( lpctstr lpszimefilename, lpctstr lpszlayouttext);前一个参数 lpszimefilename 是“.ime”文件的路径,win9x 为“\system”下,winnt/2000为“\system32”下。后一个参数 lpszlayouttext  是输入法的明称。如 hkl myime=imminstallime("windows\\system\\3jaja.ime","3++输入法"); 如果 myime 不返回 null ,则调用成功。
      当然你必须先设计好 dll 程序“.ime”文件和码表原文件“.mb”文件。

二、“.ime”文件的实现
     程序中的输出函数(必须)即文件“.def”中的函数,以下为函数的名称和原形,部分函数给出了原函数,希望对你能有所帮助。

//初始化输入法函数
bool winapi imeinquire(lpimeinfo lpimeinfo,lptstr lpszwndcls,dword lpszoptions)
{
   if (!lpimeinfo)
      return (false);
   lpimeinfo->dwprivatedatasize = sizeof(privcontext);
   lpimeinfo->fdwproperty = ime_prop_kbd_char_first|
                             ime_prop_candlist_start_from_1|
                             ime_prop_ignore_upkeys;
   lpimeinfo->fdwconversioncaps =      ime_cmode_native|ime_cmode_native|ime_cmode_fullshape|ime_cmode_charcode|ime_cmode_softkbd|ime_cmode_noconversion;
  lpimeinfo->fdwsentencecaps = 0;
  lpimeinfo->fdwuicaps = ui_cap_rot90|ui_cap_softkbd;
  lpimeinfo->fdwscscaps = scs_cap_compstr|scs_cap_makeread;
  lpimeinfo->fdwselectcaps = (dword)0;
  lstrcpy(lpszwndcls, (lptstr)szuiclassname);
  return (true);
}      
               
//自定义汉字编码格式,未作处理。
dword winapi imeconversionlist(himc himc,lpctstr lpszsrc,dword ubuflen,uint uflag)
{
     return (0);
}

//设置输入法状态函数,如光标跟随等
bool winapi imeconfigure(hkl hkl,hwnd happwnd,dword dwmode,lpvoid  lpdata)
{
    switch (dwmode)
   {
       case ime_config_general:
             dialogbox(hinst, makeintresource(setime), (hwnd)happwnd, (dlgproc)imesetdlgproc);
            break;
       default:
           return (false);
          break;
      }
     return (true);
}

//退出
bool winapi imedestroy(uint ureserved)
{
     if (ureserved)
        return (false);
     return (true);

             
//应用接口函数
lresult winapi imeescape(himc himc,uint usubfunc,lpvoid lpdata)
{
     lresult lret;

     switch (usubfunc)
   {
       case ime_esc_query_support:
          if ( lpdata == null )
   return false;

    switch (*(lpuint)lpdata)
  {
    case ime_esc_query_support:
    case ime_esc_max_key:
    case ime_esc_ime_name:
    case ime_esc_gethelpfilename:
           return (true);
    case ime_esc_sequence_to_internal:
    case ime_esc_get_eudc_dictionary:
    case ime_esc_set_eudc_dictionary:
    case ime_inputkeytosequence:
         return (false);         
    default:
        return (false);
    }
   break;
   case ime_esc_sequence_to_internal:
   case ime_esc_get_eudc_dictionary:
   case ime_esc_set_eudc_dictionary:
   case ime_inputkeytosequence:
        return (false);
   case ime_esc_max_key:
        return ((word) 4);
  case ime_esc_gethelpfilename:
  {
      tchar szimegudhlpname[maxstrlen];
      if (lpdata == null )
            return false;

      szimegudhlpname[0] = 0;
      getwindowsdirectory((lptstr)szimegudhlpname, maxstrlen);
      lstrcat((lptstr)szimegudhlpname, text("\\help\\3jaja.hlp"));
      lstrcpy((char*)lpdata, (char*)szimegudhlpname);
      return true;
    }

    default:
        return (false);
    }

    return (lret);

  
//启动输入法设置功能
bool winapi imeselect(himc himc,bool fselect)
{
     lpinputcontext lpimc;
     bool           fret;

    if (!himc)
       return (false);

    lpimc = (lpinputcontext)immlockimc(himc);
    if (!lpimc)
      return (false);

    fret = select(himc, lpimc, fselect);
    immunlockimc(himc);
    return (fret);

//设置输入活动状态
bool winapi imesetactivecontext(himc himc,bool fon)
{
     if (fon&&himc)
    {
          lpinputcontext lpimc;

         lpimc = (lpinputcontext)immlockimc(himc);
         if (!lpimc)
             return (false);

        initcontext(lpimc);
        immunlockimc(himc);
     }
     return (true);
 }

//用户按键处理函数,例如中英文状态,返回 false 为英文状态,按键不作处理。
bool winapi imeprocesskey(himc himc,uint uvirtkey,lparam lparam,const lpbyte lpbkeystate);
               
//输入法编码字符处理。
bool winapi imesetcompositionstring(himc himc,dword dwindex,lpvoid lpcomp,
    dword  dwcomplen,lpvoid lpread,dword  dwreadlen);

//将用户按键转换为汉字编码
uint winapi imetoasciiex(uint uvirtkey,uint uscancode,const lpbyte lpbkeystate,lptransmsglist lptransbuf,uint fustate,himc himc)           
               
//处理ime消息函数
bool winapi notifyime(himc himc,dword dwaction,dword dwindex,dword dwvalue);     

//自定义汉字编码格式,未作处理。
bool winapi imeregisterword(lpctstr lpszreading,dword dwstyle,lpctstr lpszstring)
{
    return (false);
}

//自定义汉字编码格式,未作处理。
bool winapi imeunregisterword(lpctstr lpszreading,dword dwstyle,lpctstr lpszstring)
{
    return (false);
}

//自定义汉字编码格式,未作处理。
uint winapi imegetregisterwordstyle(uint nitem,lpstylebuf lpstylebuf)
{
    return (false);
}

//自定义汉字编码格式,未作处理。
uint winapi imeenumregisterword(registerwordenumproc lpfnregisterwordenumproc,
    lpctstr lpszreading,dword dwstyle,lpctstr lpszstring,lpvoid lpdata)
{
    return (false);
}

//ui窗口过程
lresult callback uiwndproc(hwnd   huiwnd,uint   umsg,wparam wparam,lparam lparam)
{
 switch (umsg)
 {
  case wm_create:
      createuiwindow(huiwnd);
       break;
  case wm_destroy:
      destroyuiwindow(huiwnd);
      break;
  case wm_ime_startcomposition:
  ……
}

//状态窗口过程
lresult callback statuswndproc(hwnd hstatuswnd,uint umsg,wparam wparam,lparam lparam);

//编码窗口过程
lresult callback compwndproc(hwnd hcompwnd,uint umsg,wparam wparam,lparam lparam);

//侯选汉字窗口过程
lresult callback candwndproc(hwnd hcandwnd,uint umsg,wparam wparam,lparam lparam);

三、头文件及链接文件
    记得要定义 imm32.h 及链接文件 imm32.lib。至于有关“ .ime”程序中必须用到的结构,大家可参考 msdn 中的有关文档。

posted on   Xproer-松鼠  阅读(786)  评论(0编辑  收藏  举报

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示