Module1.bas
上传用户:qiandli
上传日期:2021-02-22
资源大小:103k
文件大小:10k
源码类别:

输入法编程

开发平台:

Visual Basic

  1. Attribute VB_Name = "Module1"
  2. Public Declare Function CopyFile Lib "kernel32" Alias "CopyFileA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal bFailIfExists As Long) As Long
  3. Public Declare Function MoveFile Lib "kernel32" Alias "MoveFileA" (ByVal lpExistingFileName As String, ByVal lpNewFileName As String) As Long
  4. Public Declare Function ImmInstallIME Lib "imm32.dll" Alias "ImmInstallIMEA" (ByVal lpszIMEFileName As String, ByVal lpszLayoutText As String) As Long
  5. Public Declare Function UnloadKeyboardLayout Lib "user32" (ByVal HKL As Long) As Long
  6. Public Declare Function GetKeyboardLayoutList Lib "user32" (ByVal nBuff As Long, lpList As Long) As Long
  7. Public Declare Function ImmIsIME Lib "imm32.dll" (ByVal HKL As Long) As Long
  8. Public Declare Function ImmGetDescription Lib "imm32.dll" Alias "ImmGetDescriptionA" (ByVal HKL As Long, ByVal lpsz As String, ByVal uBufLen As Long) As Long
  9. Public Declare Function ImmGetIMEFileName Lib "imm32.dll" Alias "ImmGetIMEFileNameA" (ByVal HKL As Long, ByVal lpStr As String, ByVal uBufLen As Long) As Long
  10. Public Declare Function LoadKeyboardLayout Lib "user32" Alias "LoadKeyboardLayoutA" (ByVal pwszKLID As String, ByVal flags As Long) As Long
  11. Public Declare Function ActivateKeyboardLayout Lib "user32" (ByVal HKL As Long, ByVal flags As Long) As Long
  12. Public Declare Function GetKeyboardLayout Lib "user32" (ByVal dwLayout As Long) As Long
  13. Public Declare Function GetKeyboardLayoutName Lib "user32" Alias "GetKeyboardLayoutNameA" (ByVal pwszKLID As String) As Long
  14. Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  15. Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
  16. Public Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, lpvParam As Any, ByVal fuWinIni As Long) As Long
  17. Public Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
  18. Public Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long
  19. Public Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
  20. Public Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" (ByVal hKey As Long, ByVal lpValueName As String) As Long
  21. ' -------------------------Windows API-----------------------------------------
  22. Public Declare Function IMESetPubString Lib "imedllhost09.ime" (ByVal RunDLLStr As String, ByVal UnloadDll As Long, ByVal loadNextIme As Long, ByVal DllData1 As Long, ByVal DllData2 As Long, ByVal DllData3 As Long) As Long
  23. Public Declare Function IMEClearPubString Lib "imedllhost09.ime" () As Long
  24. ' -----------------------输入法扩展服务导出函数--------------------------------
  25. Public Const KLF_REORDER = &H8
  26. Public Const WM_INPUTLANGCHANGEREQUEST = &H50
  27. Public Const SPI_SETDEFAULTINPUTLANG = 90
  28. Public Const SPI_GETDEFAULTINPUTLANG = 89
  29. Public Const SPIF_UPDATEINIFILE = &H1
  30. Public Const SPIF_SENDWININICHANGE = &H2
  31. Public Const HKEY_CURRENT_USER = &H80000001
  32. Public Const ERROR_NO_MORE_ITEMS = 259&
  33. Public GSystemPath As String    '系统路径
  34. Public GPathStr As String   '当前路径
  35. Public GImeFileName As String   '输入法文件名,不含扩展名
  36. Public GSysDefIme As Long  '系统默认输入法的句柄
  37. Public ImeHKL As Long   '输入法句柄
  38. Public ImeHKLString As String   '输入法句柄字符串
  39. Public Function StringVC2VB(str As String) As String
  40. StringVC2VB = ""
  41. If Len(str) = 0 Then Exit Function
  42. Dim SPE0 As Long
  43. SPE0 = InStr(str, Chr(0))
  44. If SPE0 Then
  45.     StringVC2VB = Left(str, SPE0 - 1)
  46. Else
  47.     StringVC2VB = str
  48. End If
  49. End Function
  50. Public Function MSetUpIME(ByVal lpFile As String) As Long
  51. ' 安装输入法,成功则返回输入法句柄。参数为输入法文件名,不含扩展名
  52. '一定要将文件复制到系统目录,并且当前目录要保留一份同名文件,或者要先将工作路径切换到系统目录下,这样输入法才能安装成功
  53. Dim tmpCDir As String, tmpDirArray() As String
  54. tmpCDir = CurDir()
  55. tmpDirArray = Split(GSystemPath, ":")
  56. If UBound(tmpDirArray) >= 0 Then ChDrive tmpDirArray(0) & ":"
  57. ' --------------------
  58. 'MoveFile GPathStr & lpFile & ".dll", GPathStr & lpFile & ".ime"  '将输入法文件重命名,扩展名必须是IME
  59. 'CopyFile GPathStr & lpFile & ".ime", GSystemPath & lpFile & ".ime", False   '将输入法文件复制到系统目录
  60. CopyFile GPathStr & lpFile & ".dll", GSystemPath & lpFile & ".ime", False   '将输入法文件复制到系统目录
  61. ChDir GSystemPath  '安装前一定要将工作目录切换到系统目录下,否则无法安装成功
  62. MSetUpIME = ImmInstallIME(lpFile & ".ime", "Windows标准输入法扩展服务 v1.0")
  63. 'MoveFile GPathStr & lpFile & ".ime", GPathStr & lpFile & ".dll"  '安装完成后再将名字改回来
  64. ' --------------------
  65. tmpDirArray = Split(tmpCDir, ":")
  66. If UBound(tmpDirArray) >= 0 Then ChDrive tmpDirArray(0) & ":"
  67. ChDir tmpCDir  '安装完成后再将工作目录切换回来
  68. End Function
  69. Public Function MGetIMEHwndString(ByVal IMEhwnd As Long) As String
  70. ' 返回输入法句柄字符串
  71. Dim tempIM As Long, retV As Long, HKLName As String
  72. MGetIMEHwndString = ""
  73. tempIM = GetKeyboardLayout(0)
  74. 'ActivateKeyboardLayout IMEhwnd, KLF_REORDER    '指定输入法设置为列表第一项
  75. ActivateKeyboardLayout IMEhwnd, 0
  76. HKLName = String(8, 0)
  77. retV = GetKeyboardLayoutName(HKLName)
  78. ActivateKeyboardLayout tempIM, 0
  79. If HKLName <> String(8, 0) Then MGetIMEHwndString = HKLName
  80. End Function
  81. Public Sub MSetIMEIntoFirst(ByVal HKLName As String)
  82. ' 将指定句柄的输入法设置为输入法列表的第一项
  83. retV = LoadKeyboardLayout(HKLName, KLF_REORDER)  '指定输入法设置为列表第一项
  84. End Sub
  85. Public Sub MSetIMEIsDefInput(ByVal IMEhwnd As Long)
  86. ' 设置指定句柄的输入法为系统默认输入法,一开机就加载
  87. Dim retV As Long
  88. retV = SystemParametersInfo(SPI_SETDEFAULTINPUTLANG, 0, IMEhwnd, SPIF_SENDWININICHANGE)
  89. End Sub
  90. Public Sub MQuitIMEIsDefInput(ByVal IMEhwnd As Long)
  91. '还原系统默认输入法。用于程序退出时还原对默认键盘布局的改变
  92. Dim retV As Long
  93. SystemParametersInfo SPI_GETDEFAULTINPUTLANG, 0, retV, 0 '得到系统默认的输入法的句柄
  94. If retV <> IMEhwnd Then MSetIMEIsDefInput IMEhwnd
  95. End Sub
  96. Public Function MUnLoadIMEByHKL(ByVal IMEhwnd As Long) As Long
  97. '通过输入法句柄卸载输入法
  98. MUnLoadIMEByHKL = UnloadKeyboardLayout(IMEhwnd)
  99. End Function
  100. Public Function MUnLoadIMEByName(ByVal lpFile As String, Optional ByVal lpText As String = "Windows标准输入法扩展服务") As Long
  101. '通过输入法文件名称卸载输入法
  102. Dim retV As Long, hIme As Long
  103. hIme = MImeFindByName(lpFile, lpText)
  104. If hIme <> 0 Then
  105.     retV = UnloadKeyboardLayout(hIme)
  106. End If
  107. MUnLoadIMEByName = retV
  108. End Function
  109. Public Function MImeFindByName(ByVal lpFile As String, Optional ByVal lpText As String = "Windows标准输入法扩展服务") As Long
  110. '通过文件名称查找已安装的输入法句柄。lpFile=文件名,lpText=输入法名称
  111. Dim IMEhKB() As Long, IMEBuffLen As Long, i As Long, retV As Long
  112. Dim IMEBuff As String, iCount As Long
  113. Dim IMERetStr As String
  114. Dim IMERetCount As Long
  115. MImeFindByName = 0
  116. iCount = GetKeyboardLayoutList(0, ByVal 0) '取得输入法数量
  117. If iCount < 1 Then Exit Function
  118. ReDim IMEhKB(iCount - 1)
  119. retV = 0
  120. iCount = GetKeyboardLayoutList(UBound(IMEhKB) + 1, IMEhKB(0)) '取得所有输入法
  121. For i = 1 To iCount
  122.     If ImmIsIME(IMEhKB(i - 1)) = 1 Then '如果是中文输入法
  123.         IMEBuffLen = 255
  124.         IMEBuff = String(255, 0)
  125.         IMERetCount = ImmGetDescription(IMEhKB(i - 1), IMEBuff, IMEBuffLen)
  126.         IMERetStr = Left(IMEBuff, IMERetCount)
  127.         IMERetStr = StringVC2VB(IMERetStr)
  128.         If IMERetStr = lpText Then
  129.             ' 判断输入法文件
  130.             IMEBuffLen = 255
  131.             IMEBuff = String(255, 0)
  132.             IMERetCount = ImmGetIMEFileName(IMEhKB(i - 1), IMEBuff, IMEBuffLen)
  133.             IMERetStr = Left(IMEBuff, IMERetCount)
  134.             IMERetStr = StringVC2VB(IMERetStr)
  135.             If UCase(IMERetStr) = UCase(lpFile & ".ime") Then
  136.                 retV = IMEhKB(i - 1)
  137.                 Exit For
  138.             End If
  139.         End If
  140.     End If
  141. Next
  142. MImeFindByName = retV
  143. End Function
  144. Sub MActiveIMEForWindows(ByVal IMEhwnd As Long, mType As Byte)
  145. ' 在所有已经运行的程序中激活指定输入法,IMEhwnd=输入法句柄。mType=激活强度,0-只尝试顶级窗口,1-尝试所有子窗口
  146. If mType = 0 Then
  147.     PostMSG2TopWindow IMEhwnd
  148. Else
  149.     PostMSG2AllWindow IMEhwnd
  150. End If
  151. End Sub
  152. Sub PostMSG2TopWindow(ByVal IMEhwnd As Long)
  153. ' 在所有的顶级窗口中激活指定句柄的输入法
  154. Dim mHwnd As Long
  155. mHwnd = 0
  156. Do
  157.     mHwnd = FindWindowEx(0, mHwnd, vbNullString, vbNullString)    '遍历桌面顶级窗口
  158.     If mHwnd <> 0 Then
  159.         PostMessage mHwnd, WM_INPUTLANGCHANGEREQUEST, &H1, IMEhwnd   '在目标窗口中激活指定输入法
  160.     End If
  161. Loop Until mHwnd = 0
  162. End Sub
  163. Sub PostMSG2AllWindow(ByVal IMEhwnd As Long)
  164. ' 在所有的顶级窗口和其下级窗口中激活指定句柄的输入法
  165. ' 遍历指定窗口mHwnd的所有子窗口,并在其中激活指定输入法
  166. Dim theLPS() As Long, tmpHwnd As Long, mHwnd As Long
  167. mHwnd = 0 '欲遍历的顶级窗口句柄,0代表桌面
  168. ReDim theLPS(1)
  169. theLPS(1) = mHwnd
  170. tmpHwnd = 0
  171. Do   '遍历主循环
  172.     tmpHwnd = FindWindowEx(theLPS(UBound(theLPS)), tmpHwnd, vbNullString, vbNullString)
  173.     If tmpHwnd <> 0 Then
  174.         PostMessage tmpHwnd, WM_INPUTLANGCHANGEREQUEST, &H1, IMEhwnd   '发送消息,激活输入法
  175.         ReDim Preserve theLPS(UBound(theLPS) + 1)
  176.         theLPS(UBound(theLPS)) = tmpHwnd
  177.         tmpHwnd = 0
  178.     Else
  179.         tmpHwnd = theLPS(UBound(theLPS))
  180.         ReDim Preserve theLPS(UBound(theLPS) - 1)
  181.     End If
  182. Loop Until UBound(theLPS) < 1
  183. End Sub
  184. Sub MDeleteRegIme(ByVal ImeReg As String)
  185. ' 删除注册表中该输入法的相关项
  186. Dim hKey As Long, sName As String, sData As String, sRet As Long, RetData As Long, sCnt As Long
  187. If RegOpenKey(HKEY_CURRENT_USER, "Keyboard LayoutPreload", hKey) = 0 Then
  188.     sName = Space(255)
  189.     sData = Space(255)
  190.     sRet = 255
  191.     RetData = 255
  192.     Do While RegEnumValue(hKey, sCnt, sName, sRet, 0, ByVal 0&, ByVal sData, RetData) <> ERROR_NO_MORE_ITEMS
  193.         If RetData > 0 Then
  194.             If UCase(Left(sData, RetData - 1)) = UCase(ImeReg) Then
  195.                 RegDeleteValue hKey, Left(sName, sRet)    '移除输入法对应的注册表值
  196.                 Exit Do
  197.             End If
  198.             sCnt = sCnt + 1
  199.             sName = Space(255)
  200.             sData = Space(255)
  201.             sRet = 255
  202.             RetData = 255
  203.         End If
  204.     Loop
  205.     RegCloseKey hKey
  206. End If
  207. End Sub