`
freesoftman
  • 浏览: 319850 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

输入法(IME)实现原理

阅读更多

这篇是我看了, 还不错的技术文档。

不错还是不能很好的理解。  只是为了做参考, 等我吃透了, 我就专门写一篇这样的文档。

 

本文来自于:http://blog.sina.com.cn/s/blog_56a388c20100004u.html

 

=============================================================

 

 

一、实现原理
1.中文输入法的组成
      微软 Windows 系统中输入法由程序(DLL)名称为:*.ime文件和码表文件(字典)
名称为*.mb文件组成。
2.中文输入法的界面
[img]http://wjy.hanwenhua.com/images/Projec6.gif[/img]          
 
3.在 Windows 任务栏“EN图标”中增加输入法名称
    这也就是 Setup 程序的关键,实际上,可以利用 Win32Api 函数 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 ,则调用成功。
4.“.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("file://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);
5.头文件及链接文件
    记得要定义 IMM32.h 及链接文件 IMM32.lib。至于有关“ .ime”程序中必须用到的结构,大家可参考 MSDN 中的有关文档。
二、常用函数
BOOL WINAPI ImmGenerateMessage( //将汉字串法发送到与当前输入法相关联的应用软件中
HIMC hIMC
);//成功为TRUE,否则为FALSE
LRESULT WINAPI ImmRequestMessage( //向应用程序发送WM_IME_REQUEST消息
HIMC hIMC, //与当前输入法相关联的应用软件的句柄
WPARAM wParam, //与WM_IME_REQUEST相关的wP
LPARAM lParam //与WM_IME_REQUEST相关的LP
);
LPINPUTCONTEXT WINAPI ImmLockIMC( //获取当前IMC的INPUTCONTEXT结构信息,增加IMC 计数器
HIMC hIMC
);//成功返回INPUTCONTEXT 结构指针,否则为NULL
BOOL WINAPI ImmUnlockIMC( //释放IMC计数器
HIMC hIMC );//返回:如果IMC计数器被减少到0了,返回FALSE,否则为TRUE.
注意:ImmLockIMC与ImmUnlockIMC必须成对出现,必须是相同的HIMC
HIMCC WINAPI ImmGetIMCLockCount( //取计数器值
HIMC hIMC );//如果成功返回HIMC的计数器值,否则为NULL.
HIMCC WINAPI ImmCreateIMCC( //创建INPUTCONTEXT结构的一个成员
DWORD dwSize //成员的缓冲区长度
);//如果成功返回IMC的成员句柄,否则为NULL
HIMCC WINAPI ImmDestroyIMCC( //删除IMC成员缓冲区
HIMCC hIMCC
);//如果成功返回NULL,否则等于该HIMCC.
LPVOID WINAPI ImmLockIMCC( //取IMCC缓冲地址,同时使IMCC的计数器值增加
HIMCC hIMCC );
BOOL WINAPI ImmUnlockIMCC( //递减IMCC计数器
HIMCC hIMCC );//如果IMCC的计数器值为零,则返回 FALSE,否则为TRUE.
10、HIMCC WINAPI ImmReSizeIMCC( //重新设置IMC的成员的缓冲区大小
HIMCC hIMCC, //IMC的成员句柄
DWORD dwSize //新缓冲区大小
);//如果成功,返回新的HIMCC,否则为 NULL.
DWORD WINAPI ImmGetIMCCSize( //取IMC成员的缓冲区大小
HIMCC hIMCC );//返回IMC成员的缓冲区大小
12、DWORD WINAPI ImmGetIMCCLockCount( //返回IMC计数器值
HIMCC hIMCC
);//成功返回该IMCC的计数器值,否则为0
BOOL WINAPI ImmGetHotKey( //取输入法状态键,该函数供控制面板使用
DWORD dwHotKeyID,
LPUINT lpuModifiers,
LPUINT lpuVKey,
LPHKL lphKL
)
BOOL WINAPI ImmSetHotKey( //设置输入法的热键
DWORD dwHotKeyID,
UINT uModifiers,
UINT uVKey,
hKL hKL
)
HWND WINAPI ImmCreateSoftKeyboard( //产生一个软键盘
UINT uType, //软件盘上的键码含义的定义方式
UINT hOwner, //该输入法的UI窗口
int x, //x坐标
int y //y坐标
);//成功返回软键盘的窗口句柄
BOOL WINAPI ImmDestroySoftKeyboard( //销毁软键盘
HWND hSoftKbdWnd //软键盘窗口句柄
);//成功为TRUE,法哦则为FALSE.
17、BOOL WINAPI ImmShowSoftKeyboard( //显示或隐藏软键盘
HWND hSoftKbdWnd, //软键盘窗口句柄
int nCmdShow //SW_HIDE=隐藏,SW_SHOWNOACTIVATE=显示
);//如构成功返回 TRUE. 否则为 FALSE.
            二、 IME  文件中的常用结构
1、IMEINFOstruct tagIMEInfo { //输入法的接口信息
DWORD dwPrivateDataSize;//用户设计的数据结构的字节数
DWORD fdwProperty; //输入法对键盘事件的相应特性
DWORD fdwConversionCaps;//当前输入法具有的功能特性,如有软键盘、标点、中西文切换等功能
DWORD fdwSentenceCaps;
DWORD fdwUICaps; // 用户界面能力:支持软键盘等
DWORD fdwSCSCaps; // 用户设置编码串的能力
DWORD fdwSelectCaps; // 输入法切换时是否使用以前输入法的模式
} IIMEINFO;
2、COMPOSITIONSTR 用于编码管理
typedef struct tagCOMPOSITIONSTR {
DWORD dwSize; //当前编码信息需要的存储空间
DWORD dwCompReadAttrLen;   //读入的编码属性长度
DWORD dwCompReadAttrOffset; //读入的编码的位置
DWORD dwCompReadClsLen;     //读入的子串长度
DWORD dwCompReadClsOffset; //读入的子串的位置
DWORD dwCompReadStrLen;    //读入的编码长度
DWORD dwCompReadStrOffset; //读入的编码的位置
DWORD dwCompAttrLen; //编码属性长度
DWORD dwCompAttrOffset; //编码属性在内存的位置
DWORD dwCompClsLen; //编码子串长度
DWORD dwCompClsOffset; //编码子串在内存的位置
DWORD dwCompStrLen; //编码串长度
DWORD dwCompStrOffset; //编码串在内存的位置
DWORD dwCursorPos; //当前光标位置
DWORD dwDeltaStart; //被修改编码的位置
DWORD dwResultReadClsLen; //读入结果子串长度
DWORD dwResultReadClsOffset; //读入结果子串在内存的位置
DWORD dwResultReadStrLen; //读入的编码长度
DWORD dwResultReadStrOffset;  //读入的编码在内存的位置
DWORD dwResultClsLen; //结果子串长度
DWORD dwResultClsOffset; //结果子串在内存的位置
DWORD dwResultStrLen; //结果串长度
DWORD dwResultStrOffset; //结果串在内存的位置
DWORD dwPrivateSize; //用户自定义数据长度
DWORD dwPrivateOffset; //用户自定义数据在内存的位置
} COMPOSITIONSTR;
3、CANDIDATEINFO 用于编码选择管理
typedef struct tagCANDIDATEINFO {
DWORD dwSize; //数据所占内存大小
DWORD dwCount; //数据个数
DWORD dwOffset[32]; //各个编码列表的内存位置
DWORD dwPrivateSize; //自定义数据尺寸
DWORD dwPrivateOffset; //缓冲区位置
} CANDIDATEINFO;
4、GUIDELINE
typedef struct tagGUIDELINE {
DWORD dwSize;
DWORD dwLevel;
DWORD dwIndex;
DWORD dwStrLen;
DWORD dwStrOffset;
DWORD dwPrivateSize;
DWORD dwPrivateOffset;
} GUIDELINE;
5、CANDIDATELIST 编码选择列表信息
typedef struct tagCANDIDATELIST {
DWORD dwSize; // 用字节表示的内存大小
DWORD dwStyle; // 列表串的取值方式
DWORD dwCount; // 当前列表个数
DWORD dwSelection; // 当前选择的列表序号
DWORD dwPageStart; // 在列表窗口中所显示的列表的起始序号
DWORD dwPageSize; // 一页显示的列表个数
DWORD dwOffset[]; // 列表数据存放区地址
} CANDIDATELIST;
6、COMPOSITIONFORM 窗口位置、大小信息:
typedef tagCOMPOSITIONFORM {
DWORD dwStyle; //管理窗口方式
POINT ptCurrentPos; //给定坐标
RECT rcArea;
}COMPOSITIONFORM;
7、CANDIDATEFORM 列表窗口信息
typedef tagCANDIDATEFORM {
DWORD dwIndex; //列表窗口序号
DWORD dwStyle; //属性:
POINT ptCurrentPos; //坐标位置
REC rcArea;
} CANDIDATEFORM;
12、INPUTCONTEXT IMC 数据存放区
typedef struct tagINPUTCONTEXT {
HWND hWnd; //使用该IMC的窗口
BOOL fOpen; //IME的打开与关闭状态
POINT ptStatusWndPos; //状态窗口的位置
POINT ptSoftKbdPos; //软键盘的位置
DWORD fdwConversion; //IME状态(活动、不活动,全角等)
DWORD fdwSentence; //编码方式
union {
 LOGFONTA A;
 LOGFONTW W;
} lfFont; //字体
COMPOSITIONFORM cfCompForm; //编码格式结构
CANDIDATEFORM cfCandForm[4]; //列表选择结构
HIMCC hCompStr;HIMCC hCandInfo;
HIMCC hGuideLine
HIMCC hPrivate;
DWORD dwNumMsgBuf; //存放在hMsgBuf中的消息数
HIMCC hMsgBuf; //存放的消息
DWORD fdwInit //系统根据此值来初始本结构相应的信息
DWORD dwReserve[3]; //未定义
} INPUTCONTEXT;     
分享到:
评论

相关推荐

    输入法安装制作原理 输入法安装制作原理 输入法安装制作原理

    2. 编写输入法引擎:开发算法实现拼音处理、候选词生成等功能。这通常涉及自然语言处理、人工智能等领域。 3. 开发用户界面:创建UI界面,确保用户友好且高效。 4. 集成与测试:将所有组件整合成一个输入法程序,...

    输入法安装制作原理教你

    在IT领域,输入法安装制作原理是软件开发过程中的一个重要环节,它涉及到用户与计算机交互的基础,即如何让操作系统识别并使用我们自定义的输入工具。这篇文章将深入探讨输入法安装制作的基本步骤、涉及的技术以及...

    android输入法原理分析

    Android 输入法的实现原理主要基于Input Method Framework (IMF)框架,该框架将输入法的实现分为三个核心模块:客户端控件、输入法服务(IMMS)和输入法应用(IME)。理解这些模块及其交互对于在Android系统下开发...

    易语言源码易语言IME输入法源码.rar

    通过深入研究这个源码,不仅可以掌握易语言的编程技巧,还能了解到IME输入法的设计原理,对于想要在易语言环境下开发自定义输入法或者对输入法技术感兴趣的开发者来说,这是一个宝贵的参考资料。同时,这个项目也...

    基于IMM-IME输入法接口的实现方法

    本篇文章不仅阐述了IMM-IME的基本概念和工作原理,还详细介绍了如何在中文Windows操作系统平台下实现输入法的具体步骤。 #### IMM-IME架构简介 IMM-IME架构是Windows操作系统为支持多语言输入而设计的一套接口和...

    DDK IME输入法源码

    对于学习和理解输入法的工作原理,以及进行输入法开发的程序员来说,这是一个宝贵的资源。下面将详细讲解这个项目中的关键知识点。 1. **输入法引擎**:输入法引擎是输入法的核心部分,它负责解析用户的输入,预测...

    IME输入法.rar

    通过深入学习和分析"IME输入法.rar"中的源码,开发者不仅可以掌握IME的基本原理,还能了解到易语言的编程实践,这对于开发自己的输入法或者其他基于文本输入的应用程序都是非常有益的。同时,源码学习也是提升编程...

    IME输入法编程指南

    本文档旨在介绍在IME(Input Method Editor,输入法编辑器)框架下开发输入法的基本原理与思路,并以微软拼音输入法为例进行详细介绍。通过本指南,开发者可以了解到如何利用各种API函数来实现输入法的核心功能,...

    ime.zip_ime_微软输入法_输入法

    IMEEdit.cpp和IMEDlg.cpp可能涉及到输入法编辑器和对话框的实现,IME.cpp可能包含输入法的主要逻辑,而StdAfx.cpp通常包含了预编译的头文件和项目常量。 3. IMEEdit.h、IMEDlg.h、IME.h、StdAfx.h:这些是头文件,...

    输入法的生成原理.pdf

    本文旨在探讨Windows操作系统下的汉字输入法生成原理及其具体应用,并通过实例展示如何实现汉字输入法的安装。 #### 二、输入法工作原理 在Windows系统中,汉字输入法的核心任务是将用户输入的ASCII字符串按照特定...

    IMM_IME/汉字输入法

    本文将围绕“IMM_IME/汉字输入法”这一主题,详细探讨汉字输入法的基本原理、常见类型以及编程实现技术。 首先,我们需要了解IMM_IME(Input Method Manager/Input Method Editor)的概念。IMM_IME是Windows操作...

    Utf7Ime输入法

    Utf7Ime输入法是一种基于Unicode的UTF-7编码方式实现的中文输入法。...它的源码可以为其他Android开发者提供学习和参考,帮助他们了解IME的实现原理,以及如何在Android系统中创建和调试输入法服务。

    IME输入法VC编程的详细解说

    本篇文章将深入探讨如何使用VC进行IME输入法的编程,以帮助开发者理解IME的工作原理,并掌握在VC环境下创建自定义输入法的方法。 首先,我们需要了解IME的基本工作流程。IME输入法通常包含三个主要组件:候选窗口、...

    易语言IME输入法源码.zip

    易语言IME输入法源码提供了一个实际的实现案例,帮助开发者深入理解输入法的工作原理和易语言的编程机制。以下是一些主要的知识点: 1. **易语言基础**:易语言的核心特点是其直观的中文语法,如“取整”代表数学中...

    Windows9x系统下汉字输入法的基本原理

    ### Windows9x系统下汉字输入法的基本原理 #### 一、输入法与系统的关系 在Windows9x系统中,汉字输入法与系统之间的交互过程是非常关键的。这一过程可以简化为以下几个步骤: 1. **键盘事件接收**:当用户通过...

    Windows系统下汉字输入法的基本原理.doc

    ### Windows系统下汉字输入法的基本原理 #### 一、输入法与系统的关系 在Windows系统中,汉字输入法的工作机制是通过一系列复杂的过程实现的。首先,需要理解的是,输入法(Input Method Editor, IME)是Windows...

Global site tag (gtag.js) - Google Analytics