开源项目之freepy自由输入法

92 篇文章 1 订阅
19 篇文章 0 订阅

freepy自由输入法是由李振春老师产品,在此对李振春老师表示感谢!~~~

项目如图:



输入法与系统的关系如图:

  系统的键盘事件有windowsuser.exe软件接收后,user.exe在将键盘事件传导输入法管理器(Input Method Manager,简称IMM)中,管理器 再将键盘事件传到输入法中,输入法根据用户编码字典,翻译键盘事件为对应的汉字(或汉字串),然后再反传到user.exe中,user.exe再将翻译后的键盘事件传给当前正运行的应用程序,从而完成汉字的输入。

你是否了解IME?不了解我们就来简略了解一下吧!~

IME是输入法编辑器!~

IME必须提供两个部件:IME转换接口和IME用户接口。

IME用户界面包括IME窗口、用户界面(UI)窗口以及UI窗口的部件。

缺省输入上下文情况下系统给每个线程一个输入上下文,该输入上下文被线程的所有无IME支持窗口共享。

应用程序的一个窗口可以使用窗口句柄与输入上下文交互以维护任何IME状态,包括中间写作字符串。

当应用程序或者系统创建新的输入上下文时,系统准备新的输入上下文,新的输入上下文已经包括IMCC,这个IMC的部件由hCompStr、hCandInfo、hGuideLine、hPrivate和hMsgBuf组成。

IME需要生成IME消息。当IME开始转换时,IME必须生成WM_IME_STARTCOMPOSITION消息,如果IME改变了写作字符串,IME必须生成WM_IME_COMPOSITION消息,IME引发的事件导致生成消息给与输入上下文进行交互的窗口。

IME与设备驱动程序一样是动态链接库(DLL),输入法管理器(IMM)应该处理所有安装的IME。因为IME在运行时是可以改变的,不需要重新启动系统,IMM有一个结构用于维护每一个IME的所有入口点。

IMM(Input Method Manager)只在安装了亚洲语言包之后才能使用,可以通过调用GetSystemMetrics(SM_IMMENABLED)知道IMM是否使能。

下面是可以在UI窗口中调用的IMM消息、常量、函数:

  1. IME消息 
  2.   以下列出IME中用到的消息。 
  3. WM_IME_CHAR(IME得到了转换结果中的一个字符) 
  4. WM_IME_COMPOSITION(IME根据用户击键的情况更改了按键组合状态) 
  5. WM_IME_COMPOSITIONFULL(IME检测到按键组合窗口的区域无法继续扩展) 
  6. WM_IME_CONTROL(由应用程序直接向IME发出控制请求) 
  7. WM_IME_ENDCOMPOSITION(IME完成了对用户击键情况的组合) 
  8. WM_IME_KEYDOWN(检测到“键盘上的某键被按下”的动作,同时在消息队列中保留该消息) 
  9. WM_IME_KEYUP(检测到“键盘上的某键已弹起”的动作,同时在消息队列中保留该消息) 
  10. WM_IME_NOTIFY(IME窗口发生了改变) 
  11. WM_IME_REQUEST(通知:IME需要应用程序提供命令和请求信息) 
  12. WM_IME_SELECT(操作系统将改变当前IME) 
  13. WM_IME_SETCONTEXT(输入焦点转移到了某个窗口上) 
  14. WM_IME_STARTCOMPOSITION(IME准备生成转换结果) 
  15. IME函数 
  16.   本节列出了所有IME函数。 
  17. 函数 
  18. 说明 
  19. EnumInputContext 
  20. 由应用程序定义的,提供给ImmEnumInputContext函数用来处理输入环境的一个回调函数。 
  21. EnumRegisterWordProc 
  22. 由应用程序定义的,结合ImmEnumRegisterWord函数一起使用的一个回调函数。 
  23. ImmAssociateContext 
  24. 建立指定输入环境与窗口之间的关联。 
  25. ImmAssociateContextEx 
  26. 更改指定输入环境与窗口(或其子窗口)之间的关联。 
  27. ImmConfigureIME 
  28. 显示指定的输入现场标识符的配置对话框。 
  29. ImmCreateContext 
  30. 创建一个新的输入环境,并为它分配内存和初始化它。 
  31. ImmDestroyContext 
  32. 销毁输入环境并释放和它关联的内存。 
  33. ImmDisableIME 
  34. 关闭一个线程或一个进程中所有线程的IME功能。 
  35. ImmDisableTextFrameService 
  36. 关闭指定线程的文本服务框架(TSF)功能--虽然这里把它列了出来,但建议程序员最好不要使用这个函数。 
  37. ImmEnumInputContext 
  38. 获取指定线程的输入环境。 
  39. ImmEnumRegisterWord 
  40. 列举跟指定读入串、样式和注册串相匹配的注册串。 
  41. ImmEscape 
  42. 对那些不能通过IME API函数来访问的特殊输入法程序提供兼容性支持的一个函数。 
  43. ImmGetCandidateList 
  44. 获取一个候选列表。 
  45. ImmGetCandidateListCount 
  46. 获取候选列表的大小。 
  47. ImmGetCandidateWindow 
  48. 获取有关候选列表窗口的信息。 
  49. ImmGetCompositionFont 
  50. 获取有关当前用来显示按键组合窗口中的字符的逻辑字体的信息。 
  51. ImmGetCompositionString 
  52. 获取有关组合字符串的信息。 
  53. ImmGetCompositionWindow 
  54. 获取有关按键组合窗口的信息。 
  55. ImmGetContext 
  56. 获取与指定窗口相关联的输入环境。 
  57. ImmGetConversionList 
  58. 在不生成任何跟IME有关的消息的情况下,获取输入按键字符组合或输出文字的转换结果列表。 
  59. ImmGetConversionStatus 
  60. 获取当前转换状态。 
  61. ImmGetDefaultIMEWnd 
  62. 获取缺省IME类窗口的句柄。 
  63. ImmGetDescription 
  64. 复制IME的说明信息到指定的缓冲区中。 
  65. ImmGetGuideLine 
  66. 获取出错信息。 
  67. ImmGetIMEFileName 
  68. 获取跟指定输入现场相关联的IME文件名。 
  69. ImmGetImeMenuItems 
  70. 获取注册在指定输入环境的IME菜单上的菜单项。 
  71. ImmGetOpenStatus 
  72. 检测IME是否打开。 
  73. ImmGetProperty 
  74. 获取跟指定输入现场相关联的IME的属性和功能。 
  75. ImmGetRegisterWordStyle 
  76. 获取跟指定输入现场相关联的IME所支持的样式列表。 
  77. ImmGetStatusWindowPos 
  78. 获取状态窗口的位置。 
  79. ImmGetVirtualKey 
  80. 获取跟IME处理的键盘输入消息相关联的初始虚拟键值。 
  81. ImmInstallIME 
  82. 安装一个IME。 
  83. ImmIsIME 
  84. 检测指定的输入现场是否有和它相关的IME。 
  85. ImmIsUIMessage 
  86. 检查IME窗口消息并发送那些消息到特定的窗口。 
  87. ImmNotifyIME 
  88. 通知IME有关输入环境状态已改变的消息。 
  89. ImmRegisterWord 
  90. 注册一个输出文字到跟指定输入现场相关联的IME的字典中去。 
  91. ImmReleaseContext 
  92. 销毁输入环境并解除对跟它相关联的内存的锁定。 
  93. ImmSetCandidateWindow 
  94. 设置有关候选列表窗口的信息。 
  95. ImmSetCompositionFont 
  96. 设置用来显示按键组合窗口中的字符的逻辑字体。 
  97. ImmSetCompositionString 
  98. 设置按键组合字符串的字符内容、属性和子串信息。 
  99. ImmSetCompositionWindow 
  100. 设置按键组合窗口的位置。 
  101. ImmSetConversionStatus 
  102. 设置当前转换状态。 
  103. ImmSetOpenStatus 
  104. 打开或关闭IME功能。 
  105. ImmSetStatusWindowPos 
  106. 设置状态窗口的位置。 
  107. ImmSimulateHotKey 
  108. 在指定的窗口中模拟一个特定的IME热键动作,以触发该窗口相应的响应动作。 
  109. ImmUnregisterWord 
  110. 从跟指定输入环境相关联的IME的字典中注销一个输出文字。 
  111.   
  112. IME命令 
  113.   以下列出IME中用到的命令(控制消息)。 
  114. IMC_CLOSESTATUSWINDOW(隐藏状态窗口) 
  115. IMC_GETCANDIDATEPOS(获取候选窗口的位置) 
  116. IMC_GETCOMPOSITIONFONT(获取用来显示按键组合窗口中的文本的逻辑字体) 
  117. IMC_GETCOMPOSITIONWINDOW(获取按键组合窗口的位置) 
  118. IMC_GETSTATUSWINDOWPOS(获取状态窗口的位置) 
  119. IMC_OPENSTATUSWINDOW(显示状态窗口) 
  120. IMC_SETCANDIDATEPOS(设置候选窗口的位置) 
  121. IMC_SETCOMPOSITIONFONT(设置用来显示按键组合窗口中的文本的逻辑字体) 
  122. IMC_SETCOMPOSITIONWINDOW(设置按键组合窗口的样式) 
  123. IMC_SETSTATUSWINDOWPOS(设置状态窗口的位置) 
  124. IMN_CHANGECANDIDATE(IME通知应用程序:候选窗口中的内容将改变) 
  125. IMN_CLOSECANDIDATE(IME通知应用程序:候选窗口将关闭) 
  126. IMN_CLOSESTATUSWINDOW(IME通知应用程序:状态窗口将关闭) 
  127. IMN_GUIDELINE(IME通知应用程序:将显示一条出错或其他信息) 
  128. IMN_OPENCANDIDATE(IME通知应用程序:将打开候选窗口) 
  129. IMN_OPENSTATUSWINDOW(IME通知应用程序:将创建状态窗口) 
  130. IMN_SETCANDIDATEPOS(IME通知应用程序:已结束候选处理同时将移动候选窗口) 
  131. IMN_SETCOMPOSITIONFONT(IME通知应用程序:输入内容的字体已更改) 
  132. IMN_SETCOMPOSITIONWINDOW(IME通知应用程序:按键组合窗口的样式或位置已更改) 
  133. IMN_SETCONVERSIONMODE(IME通知应用程序:输入内容的转换模式已更改) 
  134. IMN_SETOPENSTATUS(IME通知应用程序:输入内容的状态已更改) 
  135. IMN_SETSENTENCEMODE(IME通知应用程序:输入内容的语句模式已更改) 
  136. IMN_SETSTATUSWINDOWPOS(IME通知应用程序:输入内容中的状态窗口的位置已更改) 
  137. IMR_CANDIDATEWINDOW(通知:选定的IME需要应用程序提供有关候选窗口的信息) 
  138. IMR_COMPOSITIONFONT(通知:选定的IME需要应用程序提供有关用在按键组合窗口中的字体的信息) 
  139. IMR_COMPOSITIONWINDOW(通知:选定的IME需要应用程序提供有关按键组合窗口的信息) 
  140. IMR_CONFIRMRECONVERTSTRING(通知:IME需要应用程序更改RECONVERTSTRING结构) 
  141. IMR_DOCUMENTFEED(通知:选定的IME需要从应用程序那里取得已转换的字符串) 
  142. IMR_QUERYCHARPOSITION(通知:选定的IME需要应用程序提供有关组合字符串中某个字符的位置信息) 
  143. IMR_RECONVERTSTRING(通知:选定的IME需要应用程序提供一个用于自动更正的字符串) 
  144. IME编程中需要用到的数据结构 
  145.   这里列了所有在使用输入法编辑器函数和消息时需要用到的数据结构。 
  146.   CANDIDATEFORM(描述候选窗口的位置信息) 
  147.   CANDIDATELIST(描述有关候选列表的信息) 
  148.   COMPOSITIONFORM(描述按键组合窗口的样式和位置信息) 
  149.   IMECHARPOSITION(描述按键组合窗口中的字符的位置信息) 
  150.   IMEMENUITEMINFO(描述IME菜单项的信息) 
  151.   RECONVERTSTRING(定义用于IME自动更正功能的字符串) 
  152.   REGISTERWORD(描述一个要注册的读入信息或文字内容) 
  153.   STYLEBUF(描述样式的标识符和名称) 
  154. IME常量 
  155.   这里列出了所有在使用输入法编辑器函数和消息时需要用到的常量。 
  156.   • IME转换模式常量 
  157.   • IME按键组合字符串常量 
  158.   • IME热键标识常量 
  159.   • IME句型模式常量 
  160.   • IMMEscape函数常量 
IME消息
  以下列出IME中用到的消息。
WM_IME_CHAR(IME得到了转换结果中的一个字符)
WM_IME_COMPOSITION(IME根据用户击键的情况更改了按键组合状态)
WM_IME_COMPOSITIONFULL(IME检测到按键组合窗口的区域无法继续扩展)
WM_IME_CONTROL(由应用程序直接向IME发出控制请求)
WM_IME_ENDCOMPOSITION(IME完成了对用户击键情况的组合)
WM_IME_KEYDOWN(检测到“键盘上的某键被按下”的动作,同时在消息队列中保留该消息)
WM_IME_KEYUP(检测到“键盘上的某键已弹起”的动作,同时在消息队列中保留该消息)
WM_IME_NOTIFY(IME窗口发生了改变)
WM_IME_REQUEST(通知:IME需要应用程序提供命令和请求信息)
WM_IME_SELECT(操作系统将改变当前IME)
WM_IME_SETCONTEXT(输入焦点转移到了某个窗口上)
WM_IME_STARTCOMPOSITION(IME准备生成转换结果)
IME函数
  本节列出了所有IME函数。
函数
 说明
EnumInputContext
 由应用程序定义的,提供给ImmEnumInputContext函数用来处理输入环境的一个回调函数。
EnumRegisterWordProc
 由应用程序定义的,结合ImmEnumRegisterWord函数一起使用的一个回调函数。
ImmAssociateContext
 建立指定输入环境与窗口之间的关联。
ImmAssociateContextEx
 更改指定输入环境与窗口(或其子窗口)之间的关联。
ImmConfigureIME
 显示指定的输入现场标识符的配置对话框。
ImmCreateContext
 创建一个新的输入环境,并为它分配内存和初始化它。
ImmDestroyContext
 销毁输入环境并释放和它关联的内存。
ImmDisableIME
 关闭一个线程或一个进程中所有线程的IME功能。
ImmDisableTextFrameService
 关闭指定线程的文本服务框架(TSF)功能--虽然这里把它列了出来,但建议程序员最好不要使用这个函数。
ImmEnumInputContext
 获取指定线程的输入环境。
ImmEnumRegisterWord
 列举跟指定读入串、样式和注册串相匹配的注册串。
ImmEscape
 对那些不能通过IME API函数来访问的特殊输入法程序提供兼容性支持的一个函数。
ImmGetCandidateList
 获取一个候选列表。
ImmGetCandidateListCount
 获取候选列表的大小。
ImmGetCandidateWindow
 获取有关候选列表窗口的信息。
ImmGetCompositionFont
 获取有关当前用来显示按键组合窗口中的字符的逻辑字体的信息。
ImmGetCompositionString
 获取有关组合字符串的信息。
ImmGetCompositionWindow
 获取有关按键组合窗口的信息。
ImmGetContext
 获取与指定窗口相关联的输入环境。
ImmGetConversionList
 在不生成任何跟IME有关的消息的情况下,获取输入按键字符组合或输出文字的转换结果列表。
ImmGetConversionStatus
 获取当前转换状态。
ImmGetDefaultIMEWnd
 获取缺省IME类窗口的句柄。
ImmGetDescription
 复制IME的说明信息到指定的缓冲区中。
ImmGetGuideLine
 获取出错信息。
ImmGetIMEFileName
 获取跟指定输入现场相关联的IME文件名。
ImmGetImeMenuItems
 获取注册在指定输入环境的IME菜单上的菜单项。
ImmGetOpenStatus
 检测IME是否打开。
ImmGetProperty
 获取跟指定输入现场相关联的IME的属性和功能。
ImmGetRegisterWordStyle
 获取跟指定输入现场相关联的IME所支持的样式列表。
ImmGetStatusWindowPos
 获取状态窗口的位置。
ImmGetVirtualKey
 获取跟IME处理的键盘输入消息相关联的初始虚拟键值。
ImmInstallIME
 安装一个IME。
ImmIsIME
 检测指定的输入现场是否有和它相关的IME。
ImmIsUIMessage
 检查IME窗口消息并发送那些消息到特定的窗口。
ImmNotifyIME
 通知IME有关输入环境状态已改变的消息。
ImmRegisterWord
 注册一个输出文字到跟指定输入现场相关联的IME的字典中去。
ImmReleaseContext
 销毁输入环境并解除对跟它相关联的内存的锁定。
ImmSetCandidateWindow
 设置有关候选列表窗口的信息。
ImmSetCompositionFont
 设置用来显示按键组合窗口中的字符的逻辑字体。
ImmSetCompositionString
 设置按键组合字符串的字符内容、属性和子串信息。
ImmSetCompositionWindow
 设置按键组合窗口的位置。
ImmSetConversionStatus
 设置当前转换状态。
ImmSetOpenStatus
 打开或关闭IME功能。
ImmSetStatusWindowPos
 设置状态窗口的位置。
ImmSimulateHotKey
 在指定的窗口中模拟一个特定的IME热键动作,以触发该窗口相应的响应动作。
ImmUnregisterWord
 从跟指定输入环境相关联的IME的字典中注销一个输出文字。
 
IME命令
  以下列出IME中用到的命令(控制消息)。
IMC_CLOSESTATUSWINDOW(隐藏状态窗口)
IMC_GETCANDIDATEPOS(获取候选窗口的位置)
IMC_GETCOMPOSITIONFONT(获取用来显示按键组合窗口中的文本的逻辑字体)
IMC_GETCOMPOSITIONWINDOW(获取按键组合窗口的位置)
IMC_GETSTATUSWINDOWPOS(获取状态窗口的位置)
IMC_OPENSTATUSWINDOW(显示状态窗口)
IMC_SETCANDIDATEPOS(设置候选窗口的位置)
IMC_SETCOMPOSITIONFONT(设置用来显示按键组合窗口中的文本的逻辑字体)
IMC_SETCOMPOSITIONWINDOW(设置按键组合窗口的样式)
IMC_SETSTATUSWINDOWPOS(设置状态窗口的位置)
IMN_CHANGECANDIDATE(IME通知应用程序:候选窗口中的内容将改变)
IMN_CLOSECANDIDATE(IME通知应用程序:候选窗口将关闭)
IMN_CLOSESTATUSWINDOW(IME通知应用程序:状态窗口将关闭)
IMN_GUIDELINE(IME通知应用程序:将显示一条出错或其他信息)
IMN_OPENCANDIDATE(IME通知应用程序:将打开候选窗口)
IMN_OPENSTATUSWINDOW(IME通知应用程序:将创建状态窗口)
IMN_SETCANDIDATEPOS(IME通知应用程序:已结束候选处理同时将移动候选窗口)
IMN_SETCOMPOSITIONFONT(IME通知应用程序:输入内容的字体已更改)
IMN_SETCOMPOSITIONWINDOW(IME通知应用程序:按键组合窗口的样式或位置已更改)
IMN_SETCONVERSIONMODE(IME通知应用程序:输入内容的转换模式已更改)
IMN_SETOPENSTATUS(IME通知应用程序:输入内容的状态已更改)
IMN_SETSENTENCEMODE(IME通知应用程序:输入内容的语句模式已更改)
IMN_SETSTATUSWINDOWPOS(IME通知应用程序:输入内容中的状态窗口的位置已更改)
IMR_CANDIDATEWINDOW(通知:选定的IME需要应用程序提供有关候选窗口的信息)
IMR_COMPOSITIONFONT(通知:选定的IME需要应用程序提供有关用在按键组合窗口中的字体的信息)
IMR_COMPOSITIONWINDOW(通知:选定的IME需要应用程序提供有关按键组合窗口的信息)
IMR_CONFIRMRECONVERTSTRING(通知:IME需要应用程序更改RECONVERTSTRING结构)
IMR_DOCUMENTFEED(通知:选定的IME需要从应用程序那里取得已转换的字符串)
IMR_QUERYCHARPOSITION(通知:选定的IME需要应用程序提供有关组合字符串中某个字符的位置信息)
IMR_RECONVERTSTRING(通知:选定的IME需要应用程序提供一个用于自动更正的字符串)
IME编程中需要用到的数据结构
  这里列了所有在使用输入法编辑器函数和消息时需要用到的数据结构。
  CANDIDATEFORM(描述候选窗口的位置信息)
  CANDIDATELIST(描述有关候选列表的信息)
  COMPOSITIONFORM(描述按键组合窗口的样式和位置信息)
  IMECHARPOSITION(描述按键组合窗口中的字符的位置信息)
  IMEMENUITEMINFO(描述IME菜单项的信息)
  RECONVERTSTRING(定义用于IME自动更正功能的字符串)
  REGISTERWORD(描述一个要注册的读入信息或文字内容)
  STYLEBUF(描述样式的标识符和名称)
IME常量
  这里列出了所有在使用输入法编辑器函数和消息时需要用到的常量。
  • IME转换模式常量
  • IME按键组合字符串常量
  • IME热键标识常量
  • IME句型模式常量
  • IMMEscape函数常量

一般汉字输入法都由三个窗口组成:

状态窗口(Status Windows)-显示当前的输入法状态(中文还是英文等站环信息);

编码输入窗口(Composition Windows)-显示当前击键情况;

汉字选择窗口(Candidates Windows)-列出当前编码的全部汉字(串),供用户选择或查询。

上述三个窗口由基本的用户接口(User Interface )函数管理着。

Dumpbin.exe打开微软提供的拼音输入法(WINDOWS\SYSTEM\WINPY.IME)看看它有什么组成。

  1. 19 number of functions //共有19个函数 
  2. 19 number of names// 对应19个名称  
  3. ordinal hint RVA name 
  4. 1 0 0000A010 CandWndProc//"选择汉字窗口"注册函数 
  5. 2 1 0000E750 CompWndProc//"输入编码窗口"注册函数 
  6. 3 2 0000FB50 ImeConfigure//配置当前ime参数函数  
  7. 4 3 0000FEC0 ImeConversionList//将字符或字符串转换成目标字符 
  8. 5 4 0000FFA0 ImeDestroy//退出当前使用的IME 
  9. 6 5 000030D0 ImeEnumRegisterWord  
  10. 7 6 0000FFB0 ImeEscape //应用软件访问输入法的接口函数. 
  11. 8 7 00003080 ImeGetRegisterWordStyle  
  12. 9 8 0000E9A0 ImeInquire//启动并初始化当前IME输入法 
  13. 10 9 0000A800 ImeProcessKey//IME输入键盘事件管理函数 
  14. 11 A 00002C20 ImeRegisterWord //向输入法字典注册字符串 
  15. 12 B 000109A0 ImeSelect //启动当前IME输入法 
  16. 13 C 000109E0 ImeSetActiveContext //设置当前的输入处于活动状态. 
  17. 14 D 0000C850 ImeSetCompositionString 由应用程序设置输入法编码 
  18. 15 E 0000AEE0 ImeToAsciiEx//将输入的键盘事件转换为汉字编码事件 
  19. 16 F 00002F40 ImeUnregisterWord //删除被注册的字符串. 
  20. 17 10 0000CA90 NotifyIME//IME事件管理函数 
  21. 18 11 00005160 StatusWndProc//状态窗口注册函数 
  22. 19 12 00002350 UIWndProc//用户界面接口函数 
19 number of functions //共有19个函数
19 number of names// 对应19个名称 
ordinal hint RVA name
1 0 0000A010 CandWndProc//"选择汉字窗口"注册函数
2 1 0000E750 CompWndProc//"输入编码窗口"注册函数
3 2 0000FB50 ImeConfigure//配置当前ime参数函数 
4 3 0000FEC0 ImeConversionList//将字符或字符串转换成目标字符
5 4 0000FFA0 ImeDestroy//退出当前使用的IME
6 5 000030D0 ImeEnumRegisterWord 
7 6 0000FFB0 ImeEscape //应用软件访问输入法的接口函数.
8 7 00003080 ImeGetRegisterWordStyle 
9 8 0000E9A0 ImeInquire//启动并初始化当前IME输入法
10 9 0000A800 ImeProcessKey//IME输入键盘事件管理函数
11 A 00002C20 ImeRegisterWord //向输入法字典注册字符串
12 B 000109A0 ImeSelect //启动当前IME输入法
13 C 000109E0 ImeSetActiveContext //设置当前的输入处于活动状态.
14 D 0000C850 ImeSetCompositionString 由应用程序设置输入法编码
15 E 0000AEE0 ImeToAsciiEx//将输入的键盘事件转换为汉字编码事件
16 F 00002F40 ImeUnregisterWord //删除被注册的字符串.
17 10 0000CA90 NotifyIME//IME事件管理函数
18 11 00005160 StatusWndProc//状态窗口注册函数
19 12 00002350 UIWndProc//用户界面接口函数

上述可以看出,IME程序共有19个出口函数组成,每一个函数都有特定的格式,它们担负着与windows 系统传递信息的作用,这些函数是供Windows系统调用的。

下面我们将介绍上述各个函数的功能及接口格式。

  1. 1. BOOL ImeInquire( //初始化IME 
  2. LPIMEINFO lpIMEInfo, //用于初始化该输入法的结构地址 
  3. LPTSTR lpszWndClass, //当前输入法的名称 
  4. LPCTSTR或者dword lpszData //系统信息,9X系列值为0,NT/2000下有实际值 
  5. 如果该函数初始化成功,返回TURE,否则为FALSE 
  6. 用户应该搞清楚IMEINFO结构,特关系着你设计的输入法是否成功.有关该结构请看"结构"一章. 
  7. 2.DWORD IMEConversionList( // 将某字符或字符串转换成目标字符串 
  8. HIMC hIMC, // 与当前输入法相关的应用程序句柄  
  9. LPCTSTRlpSrc, // 要转换的字符串 (也可能是结果串,可由uFlag指定)  
  10. LPCANDIDATELIST lpDst, /// 转换后的字符串(也可能是源串,可由uFlag指定) 
  11. DWORD dwBufLen, //转换后有几个字符 
  12. UINT uFlag //指定结果的存放位置 
  13. 如果成功,返回转换后的字符串长度 
  14. 3.BOOL ImeConfigure( //用户设置输入法接口 
  15. HKL hKL, //当前输入法句柄 
  16. HWND hWnd, //配置窗口的父窗口 
  17. DWORD dwMode, //配置什么 
  18. LPVOID lpData //用户设置的数据 
  19. 该函数的功能是提供给输入法使用者一个可以更改某些隐含设置的能力. 
  20. 如果你用过别人的输入法,其中的"配置输入法..."功能既是也! 
  21. 对于一个初写输入法的人,可以不予理它. 
  22. 4.BOOL ImeDestroy( //关闭当前输入法 
  23. UINT uReserved //无用 (0) 
  24. 成功返回TURE,否则为FALSE 
  25. 5.LRESULT ImeEscape( //用户软件访问输入法内部信息的接口 
  26. HIMC hIMC, //当前的应用程序句柄 
  27. UINT uEscape, //设置函数功能 
  28. //=IME_ESC_QUERY _SUPPORT 
  29. //=IME_ESC_RESERVED_LAST IME_ESC_RESERVED_FIRST 
  30. //=IME_ESC_PRIVATE_FIRST IME_ESC_PRIVATE_LAST 
  31. //=IME_ESC_SEQUENCE_TO_ INTERNAL 
  32. //=IME_ESC_GET_EUDC_ DICTIONARY  
  33. //=IME_ESC_SET_EUDC_ DICTIONARY  
  34. //=IME_ESC_MAX_KEY  
  35. //=IME_ESC_IME_NAME 
  36. //=IME_ESC_SYNC_HOTKEY 
  37. //=IME_ESC_HANJA_MODE 
  38. //=IME_ESC_GETHELPFILENAME(只适应 Windows 98和Windows 2000) 
  39. //=IME_ESC_PRIVATE_HOTKEY(w95下不可用)  
  40. LPVOID lpData //当前功能所需的数据 
  41. 如果失败,返回0,否则有个功能决定 
  42. 有时,人们可以用此函数怀区输入法的名称、帮助文件名称等。当然,我们可以不提供这些功能。 
  43.   
  44. 6、BOOL ImeSetActiveContext( //激活或搁置当前的输入法 
  45. HIMC hIMC, //当前用户程序句柄 
  46. BOOL fFlag //激活或搁置:=TRUE 激活 =FALSE 搁置 
  47. 成功返回TRUE,否则为FALSE 
  48. 7、BOOL ImeProcessKey( //处理应用程序传入的所有击键事件,监测是否是当前输入法所需的 
  49. HIMC hIMC, //应用程序句柄 
  50. UINT uVirKey, //需处理的虚键 
  51. DWORD lParam, //击键消息参数 
  52. CONST LPBYTE lpbKeyState //当前键盘状态(256字节) 
  53. 如果此键是该输入法需要的,则返回TRUE,否则为FALSE 
  54. 只有返回true的击键,IME才去处理 
  55. 8、BOOL NotifyIME( //输入法选择窗口状态管理函数: 
  56. HIMC hIMC, //当前的应用程序句柄 
  57. DWORD dwAction, //状态值 
  58. DWORD dwIndex, //与状态值有关的序号 
  59. DWORD dwValue //与状态值有关的值 
  60. 状态值说明: 
  61. =NI_OPENCANDIDATE 打开编码选择窗口 
  62. =NI_CLOSECANDIDATE 关闭当前的编码选择窗  
  63. =NI_SELECTCANDIDATESTR 选摘编码 
  64. 此时:dwIndex 被选择的编码列表序号.  
  65. dwValue 被选中的编码在当前的编码列表中的序号 
  66. =NI_CHANGECANDIDATELIST 改变当前的编码列表(按pageup等键操作) 
  67. 此时:dwIndex 被选择的编码列表序号.  
  68. dwValue 不用 
  69. =NI_SETCANDIDATE_PAGESTART 设置编码开始页号  
  70. 此时: dwIndex 被改变的编码列表序号 
  71. dwValue 新页的开始序号.  
  72. =NI_SETCANDIDATE_PAGESIZE 改变编码列表页的大小  
  73. 此时:dwIndex 当前编码页序号 
  74. dwValue 新的页大小 
  75. =NI_CONTEXTUPDATED 更新应用程序的信息的输入法的信息:移动位置,设置模式,设置编码窗口,字体。 
  76. 此时:dwIndex 只用于 dwValue=IMC_SETCONVERSIONMODE, IMC_SETSENTENCEMODE  
  77. dwValue 可取由 WM_IME_CONTROL 发送的下列值: 
  78. IMC_SETCANDIDATEPOS 
  79. IMC_SETCOMPOSITIONFONT 
  80. IMC_SETCOMPOSITIONWINDOW  
  81. IMC_SETCONVERSIONMODE  
  82. IMC_SETSENTENCEMODE  
  83. IMC_SETOPENSTATUS  
  84. =NI_COMPOSITIONSTR 改变编码窗口中的编码  
  85. 此时:dwIndex 取下列值:CPS_COMPLETE 完成编码转换 
  86. CPS_CONVERT 转换编码 
  87. CPS_REVERT 取消当前的编码 
  88. CPS_CANCEL 清除编码,并关闭编码窗  
  89. dwValue 不用 
  90. 此函数成功,返回TRUE,否则为FALSE 
  91. 9、BOOL ImeSelect( //初始化输入法 
  92. HIMC hIMC, //当前应用程序句柄 
  93. BOOL fSelect //是否初始化当前输入法,TRUE表示初始化 
  94. 返回:成功返回true,否则为FALSE 
  95. The ImeSetCompositionString function is used by an application to set the IME composition string structure with the data contained in the lpComp or lpRead parameters. The IME then generates a message. 
  96. 10、BOOL WINAPI ImeSetCompositionString( //将编码窗口中输入的编码保存的编码结构中, 
  97. //同志发送编码完成的消息 
  98. //( WM_IME_COMPOSITION)给系统, 
  99. HIMC hIMC, //当前的应用程序句柄 
  100. DWORD dwIndex, //设置此函数功能 
  101. //=SCS_SETSTR  
  102. //=SCS_CHANGEATTR  
  103. //=SCS_CHANGECLAUSE 
  104. //= SCS_QUERYRECONVERTSTRING  
  105. //=SCS_RECONVERTSTRING  
  106. //=SCS_SETRECONVERTSTRING  
  107.  
  108. LPCVOID lpComp, //编码数据区 
  109. DWORD dwCompLen, //编码数据区长度 
  110. LPCVOID lpRead, //读入的编码数据 
  111. DWORD dwReadLen //读入的编码数据长度 
  112. ) 
  113. 11、UINT ImeToAsciiEx( //转换编码称汉字(串) 
  114. UINT uVirKey, //虚键 
  115. UINT uScanCode, //扫描码 
  116. CONST LPBYTE lpbKeyState, //用户定义的键盘状态 
  117. LPDWORD lpdwTransBuf, //转换后的数据存放区 
  118. UINT fuState, //活动菜单标志 
  119. HIMC hIMC //当前的应用程序句柄 
  120. 返回:返回值表示有几个消息,可理解为:本编码对应的汉字串有几个汉字组成(当然,这并不相等)。 
  121. 12、BOOL WINAPI ImeRegisterWord( 
  122. LPCTSTR lpszReading,  
  123. DWORD dwStyle, 
  124. LPCTSTR lpszString 
  125. 13、BOOL WINAPI ImeUnregisterWord( 
  126. LPCTSTR lpszReading, 
  127. DWORD dwStyle, 
  128. LPCTSTR lpszString 
  129. 14、UINT WINAPI 
  130. ImeGetRegisterWordStyle( 
  131. UINT nItem, 
  132. LPSTYLEBUF lpStyleBuf 
  133. 15、UINT WINAPI ImeEnumRegisterWord( 
  134. hKL, 
  135. REGISTERWORDENUMPROC lpfnEnumProc, 
  136. LPCTSTR lpszReading, 
  137. DWORD dwStyle, 
  138. LPCTSTR lpszString, 
  139. LPVOID lpData 
  140. 16、DWORD WINAPI ImeGetImeMenuItems( 
  141. HIMC hIMC, 
  142. DWORD dwFlags, 
  143. DWORD dwType, 
  144. LPIMEMENUITEMINFO lpImeParentMenu, 
  145. LPIMEMENUITEMINFO lpImeMenu, 
  146. DWORD dwSize 
1. BOOL ImeInquire( //初始化IME
LPIMEINFO lpIMEInfo, //用于初始化该输入法的结构地址
LPTSTR lpszWndClass, //当前输入法的名称
LPCTSTR或者dword lpszData //系统信息,9X系列值为0,NT/2000下有实际值
)
如果该函数初始化成功,返回TURE,否则为FALSE
用户应该搞清楚IMEINFO结构,特关系着你设计的输入法是否成功.有关该结构请看"结构"一章.
2.DWORD IMEConversionList( // 将某字符或字符串转换成目标字符串
HIMC hIMC, // 与当前输入法相关的应用程序句柄 
LPCTSTRlpSrc, // 要转换的字符串 (也可能是结果串,可由uFlag指定) 
LPCANDIDATELIST lpDst, /// 转换后的字符串(也可能是源串,可由uFlag指定)
DWORD dwBufLen, //转换后有几个字符
UINT uFlag //指定结果的存放位置
)
如果成功,返回转换后的字符串长度
3.BOOL ImeConfigure( //用户设置输入法接口
HKL hKL, //当前输入法句柄
HWND hWnd, //配置窗口的父窗口
DWORD dwMode, //配置什么
LPVOID lpData //用户设置的数据
)
该函数的功能是提供给输入法使用者一个可以更改某些隐含设置的能力.
如果你用过别人的输入法,其中的"配置输入法..."功能既是也!
对于一个初写输入法的人,可以不予理它.
4.BOOL ImeDestroy( //关闭当前输入法
UINT uReserved //无用 (0)
)
成功返回TURE,否则为FALSE
5.LRESULT ImeEscape( //用户软件访问输入法内部信息的接口
HIMC hIMC, //当前的应用程序句柄
UINT uEscape, //设置函数功能
//=IME_ESC_QUERY _SUPPORT
//=IME_ESC_RESERVED_LAST IME_ESC_RESERVED_FIRST
//=IME_ESC_PRIVATE_FIRST IME_ESC_PRIVATE_LAST
//=IME_ESC_SEQUENCE_TO_ INTERNAL
//=IME_ESC_GET_EUDC_ DICTIONARY 
//=IME_ESC_SET_EUDC_ DICTIONARY 
//=IME_ESC_MAX_KEY 
//=IME_ESC_IME_NAME
//=IME_ESC_SYNC_HOTKEY
//=IME_ESC_HANJA_MODE
//=IME_ESC_GETHELPFILENAME(只适应 Windows 98和Windows 2000)
//=IME_ESC_PRIVATE_HOTKEY(w95下不可用) 
LPVOID lpData //当前功能所需的数据
)
如果失败,返回0,否则有个功能决定
有时,人们可以用此函数怀区输入法的名称、帮助文件名称等。当然,我们可以不提供这些功能。
 
6、BOOL ImeSetActiveContext( //激活或搁置当前的输入法
HIMC hIMC, //当前用户程序句柄
BOOL fFlag //激活或搁置:=TRUE 激活 =FALSE 搁置
)
成功返回TRUE,否则为FALSE
7、BOOL ImeProcessKey( //处理应用程序传入的所有击键事件,监测是否是当前输入法所需的
HIMC hIMC, //应用程序句柄
UINT uVirKey, //需处理的虚键
DWORD lParam, //击键消息参数
CONST LPBYTE lpbKeyState //当前键盘状态(256字节)
)
如果此键是该输入法需要的,则返回TRUE,否则为FALSE
只有返回true的击键,IME才去处理
8、BOOL NotifyIME( //输入法选择窗口状态管理函数:
HIMC hIMC, //当前的应用程序句柄
DWORD dwAction, //状态值
DWORD dwIndex, //与状态值有关的序号
DWORD dwValue //与状态值有关的值
)
状态值说明:
=NI_OPENCANDIDATE 打开编码选择窗口
=NI_CLOSECANDIDATE 关闭当前的编码选择窗 
=NI_SELECTCANDIDATESTR 选摘编码
此时:dwIndex 被选择的编码列表序号. 
dwValue 被选中的编码在当前的编码列表中的序号
=NI_CHANGECANDIDATELIST 改变当前的编码列表(按pageup等键操作)
此时:dwIndex 被选择的编码列表序号. 
dwValue 不用
=NI_SETCANDIDATE_PAGESTART 设置编码开始页号 
此时: dwIndex 被改变的编码列表序号
dwValue 新页的开始序号. 
=NI_SETCANDIDATE_PAGESIZE 改变编码列表页的大小 
此时:dwIndex 当前编码页序号
dwValue 新的页大小
=NI_CONTEXTUPDATED 更新应用程序的信息的输入法的信息:移动位置,设置模式,设置编码窗口,字体。
此时:dwIndex 只用于 dwValue=IMC_SETCONVERSIONMODE, IMC_SETSENTENCEMODE 
dwValue 可取由 WM_IME_CONTROL 发送的下列值:
IMC_SETCANDIDATEPOS
IMC_SETCOMPOSITIONFONT
IMC_SETCOMPOSITIONWINDOW 
IMC_SETCONVERSIONMODE 
IMC_SETSENTENCEMODE 
IMC_SETOPENSTATUS 
=NI_COMPOSITIONSTR 改变编码窗口中的编码 
此时:dwIndex 取下列值:CPS_COMPLETE 完成编码转换
CPS_CONVERT 转换编码
CPS_REVERT 取消当前的编码
CPS_CANCEL 清除编码,并关闭编码窗 
dwValue 不用
此函数成功,返回TRUE,否则为FALSE
9、BOOL ImeSelect( //初始化输入法
HIMC hIMC, //当前应用程序句柄
BOOL fSelect //是否初始化当前输入法,TRUE表示初始化
)
返回:成功返回true,否则为FALSE
The ImeSetCompositionString function is used by an application to set the IME composition string structure with the data contained in the lpComp or lpRead parameters. The IME then generates a message.
10、BOOL WINAPI ImeSetCompositionString( //将编码窗口中输入的编码保存的编码结构中,
//同志发送编码完成的消息
//( WM_IME_COMPOSITION)给系统,
HIMC hIMC, //当前的应用程序句柄
DWORD dwIndex, //设置此函数功能
//=SCS_SETSTR 
//=SCS_CHANGEATTR 
//=SCS_CHANGECLAUSE
//= SCS_QUERYRECONVERTSTRING 
//=SCS_RECONVERTSTRING 
//=SCS_SETRECONVERTSTRING 

LPCVOID lpComp, //编码数据区
DWORD dwCompLen, //编码数据区长度
LPCVOID lpRead, //读入的编码数据
DWORD dwReadLen //读入的编码数据长度
)
11、UINT ImeToAsciiEx( //转换编码称汉字(串)
UINT uVirKey, //虚键
UINT uScanCode, //扫描码
CONST LPBYTE lpbKeyState, //用户定义的键盘状态
LPDWORD lpdwTransBuf, //转换后的数据存放区
UINT fuState, //活动菜单标志
HIMC hIMC //当前的应用程序句柄
)
返回:返回值表示有几个消息,可理解为:本编码对应的汉字串有几个汉字组成(当然,这并不相等)。
12、BOOL WINAPI ImeRegisterWord(
LPCTSTR lpszReading, 
DWORD dwStyle,
LPCTSTR lpszString
)
13、BOOL WINAPI ImeUnregisterWord(
LPCTSTR lpszReading,
DWORD dwStyle,
LPCTSTR lpszString
)
14、UINT WINAPI
ImeGetRegisterWordStyle(
UINT nItem,
LPSTYLEBUF lpStyleBuf
)
15、UINT WINAPI ImeEnumRegisterWord(
hKL,
REGISTERWORDENUMPROC lpfnEnumProc,
LPCTSTR lpszReading,
DWORD dwStyle,
LPCTSTR lpszString,
LPVOID lpData
)
16、DWORD WINAPI ImeGetImeMenuItems(
HIMC hIMC,
DWORD dwFlags,
DWORD dwType,
LPIMEMENUITEMINFO lpImeParentMenu,
LPIMEMENUITEMINFO lpImeMenu,
DWORD dwSize
)

  1. …… 
  2. 下面进入到freepy里 
  3.       Freepy的执行顺序是:  
  4.       1.   注册UI窗口类(DllMain:   DLL_PROCESS_ATTACH)  
  5.       2.   初始化当前输入法(回凋函数ImeInquire)  
  6.       3.   启动当前输入法(回凋函数ImeSelect)  
  7.       4.   UIWndProc  
  8.       5.   CompWndProc  
  9.       6.   StatusWndProc  
  10.       ...  
  11.        
  12.       X.   结束,释放资源(DllMain:   DLL_PROCESS_DETACH)  
……
下面进入到freepy里
      Freepy的执行顺序是: 
      1.   注册UI窗口类(DllMain:   DLL_PROCESS_ATTACH) 
      2.   初始化当前输入法(回凋函数ImeInquire) 
      3.   启动当前输入法(回凋函数ImeSelect) 
      4.   UIWndProc 
      5.   CompWndProc 
      6.   StatusWndProc 
      ... 
      
      X.   结束,释放资源(DllMain:   DLL_PROCESS_DETACH) 

  1. 消息循环 
  2.    注册了四个窗口类 根据wc.lpszClassName注册不同窗口 
  3.    注: 可以参考 res/BMP文件的命名 
  4.     CandWndProc  //"选择汉字窗口"注册函数  撰写窗口, 当你开始输入字母的时候,显示字母 
  5.     CreateCompWindow    "输入编码窗口"注册函数 
  6. void LoadTable() 加载字体库 
  7. 字体显示  查询相关位图,通过LoadBitmap 得到位图加载显示 
消息循环
   注册了四个窗口类 根据wc.lpszClassName注册不同窗口
   注: 可以参考 res/BMP文件的命名
	CandWndProc  //"选择汉字窗口"注册函数  撰写窗口, 当你开始输入字母的时候,显示字母
    CreateCompWindow    "输入编码窗口"注册函数
 void LoadTable() 加载字体库
字体显示  查询相关位图,通过LoadBitmap 得到位图加载显示


注册测试代码:

  1. void main() 
  2.     HKEY hKey,hChildKey; 
  3.     DWORD dwIndex; 
  4.     DWORD dwName,dwMaxName = 0; 
  5.     TCHAR szNameArr[MAX_SUBKEY][MAX_SIZE],szName[MAX_SIZE]; 
  6.     DWORD dwLen; 
  7.     TCHAR szLayoutText[MAX_SIZE]; 
  8.     DWORD dwData; 
  9.     FILETIME ft; 
  10.     LONG lRet; 
  11.     TCHAR szRegName[MAX_SIZE]; 
  12.     DWORD dwDisposition; 
  13.     DWORD dwConversionSet; 
  14.     WORD wCount = 0; 
  15.     int i; 
  16.     OSVERSIONINFO osVerInfo; 
  17.  
  18.     dwIndex = 0; 
  19.     dwLen = MAX_SIZE; 
  20.     dwData = MAX_SIZE * sizeof(TCHAR); 
  21.     dwConversionSet = CONVERSION_SET; 
  22.  
  23.     if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
  24.             _T("Software"), 
  25.             0, 
  26.             KEY_READ, 
  27.             &hKey) != ERROR_SUCCESS ){ 
  28.         _ftprintf(stderr,_T("Software open error\n")); 
  29.         exit(1); 
  30.     } 
  31.  
  32.     if( RegCreateKeyEx( hKey, 
  33.                     _T("freepy"), 
  34.                     0, 
  35.                     NULL, 
  36.                     REG_OPTION_NON_VOLATILE , 
  37.                     KEY_ALL_ACCESS , 
  38.                     NULL, 
  39.                     &hChildKey, 
  40.                     &dwDisposition ) != ERROR_SUCCESS) { 
  41.         RegCloseKey(hKey); 
  42.         _ftprintf(stderr,_T("freepy create error\n")); 
  43.         exit(1); 
  44.     } 
  45.  
  46.     RegSetValueEx(hChildKey, 
  47.                 _T("ConversionSet"), 
  48.                 0, 
  49.                 REG_DWORD, 
  50.                 (LPBYTE)&dwConversionSet, 
  51.                 sizeof(DWORD)); 
  52.  
  53.     RegCloseKey(hChildKey); 
  54.     RegCloseKey(hKey); 
  55.  
  56.     if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
  57.             _T("System\\CurrentControlSet\\Control\\Keyboard Layouts"), 
  58.             0, 
  59.             KEY_READ, 
  60.             &hKey) != ERROR_SUCCESS ){ 
  61.         _ftprintf(stderr,_T("Keyboard Layouts open error\n")); 
  62.         exit(1); 
  63.     } 
  64.  
  65.     RegQueryInfoKey (hKey,NULL, NULL,NULL, 
  66.                     &dwIndex, 
  67.                     NULL,NULL,NULL, NULL,NULL,NULL, NULL); 
  68.  
  69.     while( (int)dwIndex >= 0 ) { 
  70.         dwLen = MAX_SIZE; 
  71.         if((lRet = RegEnumKeyEx(hKey, 
  72.                     dwIndex, 
  73.                     szName, 
  74.                     &dwLen, 
  75.                     NULL, 
  76.                     NULL, 
  77.                     NULL, 
  78.                     &ft)) == ERROR_SUCCESS || lRet == ERROR_MORE_DATA ) { 
  79.             _tcscpy(szNameArr[wCount++],szName); 
  80.         } 
  81.         dwIndex--; 
  82.     } 
  83.  
  84.     for(i=0;i<wCount;i++) { 
  85.         if ( RegOpenKeyEx(hKey, 
  86.             szNameArr[i], 
  87.             0, 
  88.             KEY_ALL_ACCESS , 
  89.             &hChildKey) == ERROR_SUCCESS ){ 
  90.             if( RegQueryValueEx( hChildKey, 
  91.                                 _T("Layout Text"), 
  92.                                 NULL, 
  93.                                 NULL, 
  94.                                 (LPBYTE)szLayoutText, 
  95.                                 &dwData) == ERROR_SUCCESS ){ 
  96.                 if(!_tcsicmp(szLayoutText,LAYOUTTEXT)) { 
  97.                     goto my_next; 
  98.                 } 
  99.                 _stscanf(szNameArr[i],_T("%lx"),&dwName); 
  100.                 if( dwMaxName < dwName ) dwMaxName = dwName; 
  101.             } 
  102.             RegCloseKey(hChildKey); 
  103.         } 
  104.     } 
  105.  
  106.     _stprintf(szRegName,"%lx",dwMaxName + 0x10000); 
  107.     CharUpper(szRegName); 
  108.  
  109.     if( RegCreateKeyEx( hKey, 
  110.                     szRegName, 
  111.                     0, 
  112.                     NULL, 
  113.                     REG_OPTION_NON_VOLATILE , 
  114.                     KEY_ALL_ACCESS , 
  115.                     NULL, 
  116.                     &hChildKey, 
  117.                     &dwDisposition ) != ERROR_SUCCESS) { 
  118.         RegCloseKey(hKey); 
  119.         _ftprintf(stderr,_T("%s create error\n"),szRegName); 
  120.         exit(1); 
  121.     } 
  122.  
  123. my_next: 
  124.     RegSetValueEx(hChildKey, 
  125.                 _T("IME File"), 
  126.                 0, 
  127.                 REG_SZ, 
  128.                 (LPBYTE)IMEFILE, 
  129.                 _tcslen(IMEFILE)*sizeof(TCHAR)); 
  130.  
  131.     osVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 
  132.     if(GetVersionEx(&osVerInfo)) { 
  133.         RegSetValueEx(hChildKey, 
  134.                 _T("Layout File"), 
  135.                 0, 
  136.                 REG_SZ, 
  137.                 (osVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 
  138.                     ((LPBYTE)LAYOUTFILENT):((LPBYTE)LAYOUTFILE), 
  139.                 _tcslen(LAYOUTFILENT)*sizeof(TCHAR)); 
  140.     } 
  141.     else
  142.         _ftprintf(stdout,_T("get version error\n")); 
  143.         RegSetValueEx(hChildKey, 
  144.                 _T("Layout File"), 
  145.                 0, 
  146.                 REG_SZ, 
  147.                 (LPBYTE)LAYOUTFILE, 
  148.                 _tcslen(LAYOUTFILE)*sizeof(TCHAR)); 
  149.     } 
  150.  
  151.     RegSetValueEx(hChildKey, 
  152.                 _T("Layout Text"), 
  153.                 0, 
  154.                 REG_SZ, 
  155.                 (LPBYTE)LAYOUTTEXT, 
  156.                 _tcslen(LAYOUTTEXT)*sizeof(TCHAR)); 
  157.  
  158.     RegCloseKey(hChildKey); 
  159.     RegCloseKey(hKey); 
  160.  
  161.     _ftprintf(stdout,_T("ok\n")); 
  162.     return
void main()
{
	HKEY hKey,hChildKey;
	DWORD dwIndex;
	DWORD dwName,dwMaxName = 0;
	TCHAR szNameArr[MAX_SUBKEY][MAX_SIZE],szName[MAX_SIZE];
	DWORD dwLen;
	TCHAR szLayoutText[MAX_SIZE];
	DWORD dwData;
	FILETIME ft;
	LONG lRet;
	TCHAR szRegName[MAX_SIZE];
	DWORD dwDisposition;
	DWORD dwConversionSet;
	WORD wCount = 0;
	int i;
	OSVERSIONINFO osVerInfo;

	dwIndex = 0;
	dwLen = MAX_SIZE;
	dwData = MAX_SIZE * sizeof(TCHAR);
	dwConversionSet = CONVERSION_SET;

	if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
			_T("Software"),
			0,
			KEY_READ,
			&hKey) != ERROR_SUCCESS ){
		_ftprintf(stderr,_T("Software open error\n"));
		exit(1);
	}

	if( RegCreateKeyEx( hKey,
					_T("freepy"),
					0,
					NULL,
					REG_OPTION_NON_VOLATILE ,
					KEY_ALL_ACCESS ,
					NULL,
					&hChildKey,
					&dwDisposition ) != ERROR_SUCCESS) {
		RegCloseKey(hKey);
		_ftprintf(stderr,_T("freepy create error\n"));
		exit(1);
	}

	RegSetValueEx(hChildKey,
				_T("ConversionSet"),
				0,
				REG_DWORD,
				(LPBYTE)&dwConversionSet,
				sizeof(DWORD));

	RegCloseKey(hChildKey);
	RegCloseKey(hKey);

	if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
			_T("System\\CurrentControlSet\\Control\\Keyboard Layouts"),
			0,
			KEY_READ,
			&hKey) != ERROR_SUCCESS ){
		_ftprintf(stderr,_T("Keyboard Layouts open error\n"));
		exit(1);
	}

	RegQueryInfoKey (hKey,NULL,	NULL,NULL,
					&dwIndex,
					NULL,NULL,NULL,	NULL,NULL,NULL,	NULL);

	while( (int)dwIndex >= 0 ) {
		dwLen = MAX_SIZE;
		if((lRet = RegEnumKeyEx(hKey,
					dwIndex,
					szName,
					&dwLen,
					NULL,
					NULL,
					NULL,
					&ft)) == ERROR_SUCCESS || lRet == ERROR_MORE_DATA ) {
			_tcscpy(szNameArr[wCount++],szName);
		}
		dwIndex--;
	}

	for(i=0;i<wCount;i++) {
		if ( RegOpenKeyEx(hKey,
			szNameArr[i],
			0,
			KEY_ALL_ACCESS ,
			&hChildKey) == ERROR_SUCCESS ){
			if( RegQueryValueEx( hChildKey,
								_T("Layout Text"),
								NULL,
								NULL,
								(LPBYTE)szLayoutText,
								&dwData) == ERROR_SUCCESS ){
				if(!_tcsicmp(szLayoutText,LAYOUTTEXT)) {
					goto my_next;
				}
				_stscanf(szNameArr[i],_T("%lx"),&dwName);
				if( dwMaxName < dwName ) dwMaxName = dwName;
			}
			RegCloseKey(hChildKey);
		}
	}

	_stprintf(szRegName,"%lx",dwMaxName + 0x10000);
	CharUpper(szRegName);

	if( RegCreateKeyEx( hKey,
					szRegName,
					0,
					NULL,
					REG_OPTION_NON_VOLATILE ,
					KEY_ALL_ACCESS ,
					NULL,
					&hChildKey,
					&dwDisposition ) != ERROR_SUCCESS) {
		RegCloseKey(hKey);
		_ftprintf(stderr,_T("%s create error\n"),szRegName);
		exit(1);
	}

my_next:
	RegSetValueEx(hChildKey,
				_T("IME File"),
				0,
				REG_SZ,
				(LPBYTE)IMEFILE,
				_tcslen(IMEFILE)*sizeof(TCHAR));

	osVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	if(GetVersionEx(&osVerInfo)) {
		RegSetValueEx(hChildKey,
				_T("Layout File"),
				0,
				REG_SZ,
				(osVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ?
					((LPBYTE)LAYOUTFILENT):((LPBYTE)LAYOUTFILE),
				_tcslen(LAYOUTFILENT)*sizeof(TCHAR));
	}
	else {
		_ftprintf(stdout,_T("get version error\n"));
		RegSetValueEx(hChildKey,
				_T("Layout File"),
				0,
				REG_SZ,
				(LPBYTE)LAYOUTFILE,
				_tcslen(LAYOUTFILE)*sizeof(TCHAR));
	}

	RegSetValueEx(hChildKey,
				_T("Layout Text"),
				0,
				REG_SZ,
				(LPBYTE)LAYOUTTEXT,
				_tcslen(LAYOUTTEXT)*sizeof(TCHAR));

	RegCloseKey(hChildKey);
	RegCloseKey(hKey);

	_ftprintf(stdout,_T("ok\n"));
	return;
}

最后介绍一下它的调式技巧!~

打开freepy3.1工程,打开vc主菜单的Projectttings的Link属性页下的output file name 下 输入  c:\\winnt\\system32\\freepy.ime, 这是win2000,如果是xp则可能是c:\\windows\\system32\\freepy.ime;还要在Debug属性页下的Executable for debug seesion下输入c:\\windows\\system32\\notepad.exe。设置断点,然后按F5,进行调试,这时候打开任务栏右下脚输入法里的自由拼音输入法就可以了。

文章转载自: http://blog.csdn.net/banketree/article/details/7995866

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Freepy 自由输入法是一款开源的输入法项目,可以在 GitHub 上找到它的代码和项目文档。作为一个开源项目Freepy 自由输入法给用户提供了自由定制的灵活性。 首先,Freepy 自由输入法采用了开放的代码托管平台 GitHub,用户可以方便地获取最新的代码和可运行版本。在这个平台上,用户可以查看和评论项目的源代码、文档、问题和贡献,极大地促进了开发者之间的交流和合作。 作为一款输入法项目,Freepy 自由输入法具备了一些基本功能,如中文拼音输入、英文输入和自动纠错等。而其自由输入法的核心就是灵活的定制性。用户可以根据自己的需求和喜好修改或添加新的功能。通过查阅项目文档和源代码,用户可以了解输入法的整体结构和相关的接口设计,进而进行定制化的开发。这种自由定制的特性使得用户可以打造属于自己的个性化输入法,提高输入效率和舒适度。 除此之外,Freepy 自由输入法还鼓励用户与其它开发者一起贡献代码和提出问题。用户可以通过在 GitHub 上提交请求(Pull Request)来改进输入法,分享自己开发的功能和优化。这种共同协作的方式可以促进项目的快速发展,提供更好的用户体验。 总之,Freepy 自由输入法是一款开源的输入法项目,通过 GitHub 提供了便捷的代码托管和社区贡献平台。用户可以自由地定制输入法,并与其他开发者进行交流和合作,共同推动输入法的发展和提高用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值