现在好多在CE下做开发的都不使用CE的界面,所以也无法使用系统提供的输入法切换的功能。
如何自己枚举输入法,显示在自己应用的界面中,供用户选择呢?
以前在CE5下研究过一段时间相关的东东,分享出来大家一起学习。以求有抛砖引玉的作用,小心哦,不要被砖拍到,嘿嘿...
主要是下面这个类,一个.h文件:
1 /**************************************************************************** 2 * Copyright (C), 2006, Leo.Zheng 3 * File name: InputOper.h 4 * Description: CE 5.0 输入法列表的获得 5 * Version: Version 0.1 6 * History: Leo.Zheng created 2007-10-15 7 * ...... 8 *****************************************************************************/ 9 #ifndef __INPUT_OPERATION_ 10 #define __INPUT_OPERATION_ 11 #include "stdafx.h" 12 #include "Afx.h" 13 #include "Winreg.h" 14 #define IDBufSize 30 15 #define NameBufSize 100 16 struct InputLink 17 { 18 TCHAR tcID[IDBufSize]; //输入法代号。 19 TCHAR tcName[NameBufSize]; //输入法的说明文字。 20 InputLink* pNext; 21 }; 22 class CInputLanguage 23 { 24 private: 25 InputLink *m_pILHead; 26 // 27 bool ListAllIM() 28 { 29 HKEY hPreload; 30 HKEY hLayouts; 31 DWORD cp = IDBufSize; 32 TCHAR tcLp[IDBufSize]; 33 TCHAR tcLpDefault[IDBufSize]; 34 CString szID; 35 CString szValueName; 36 CString szProload = "Keyboard Layout//Preload"; // 输入法顺序 37 CString szLayouts = "System//CurrentControlSet//Control//Layouts//"; // 输入法名称 38 int i = 1; 39 DWORD lpT = REG_SZ; 40 // TCHAR tcBuffer[NameBufSize] = {0}; 41 DWORD dwLen = 0; 42 LONG nRetValue = 0; 43 44 // 读默认的输入法 45 if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,szProload,0,0,&hPreload)) 46 { 47 nRetValue = RegQueryValueEx(hPreload,TEXT(""),NULL,&lpT,(LPBYTE)tcLp,&cp); 48 if(ERROR_SUCCESS == nRetValue) 49 { 50 wcscpy(tcLpDefault,tcLp); 51 } 52 } 53 // 读所有的输入法 54 szID.Format(TEXT("%s//%d"),szProload,i); 55 56 while(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,szID,0,0,&hPreload)) 57 { 58 szValueName.Format(TEXT("%s"),TEXT("")); 59 // RegEnumKeyEx(hPreload,0,tcBuffer,&dwLen,NULL,NULL,NULL,NULL); 60 if(ERROR_SUCCESS == RegQueryValueEx(hPreload,szValueName,NULL,&lpT,(LPBYTE)tcLp,&cp)) 61 { 62 CString szTempName; 63 szTempName = szLayouts + (LPCTSTR)(LPTSTR)tcLp; 64 65 if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,szTempName,0,0,&hLayouts)) 66 { 67 TCHAR lpD[NameBufSize]; 68 DWORD lpS = NameBufSize; // DataSize 69 70 if(ERROR_SUCCESS == RegQueryValueEx(hLayouts,TEXT("Layout Text"),NULL,&lpT,(LPBYTE)lpD,&lpS)) 71 { 72 InputLink *pOne = m_pILHead; 73 InputLink *pTwo = (InputLink *)malloc(sizeof(struct InputLink)); 74 75 wcscpy(pTwo->tcID,tcLp); 76 wcscpy(pTwo->tcName,lpD); 77 pTwo->pNext = NULL; 78 if(pOne) 79 { 80 while(pOne->pNext) 81 { 82 pOne = pOne->pNext; 83 } 84 pOne->pNext = pTwo; 85 } 86 else 87 { 88 m_pILHead = pTwo; 89 } 90 } 91 } 92 ::RegCloseKey(hLayouts); 93 } 94 i++; 95 szID.Format(TEXT("%s//%d"),szProload,i); 96 } 97 98 ::RegCloseKey(hPreload); 99 return (NULL != m_pILHead); 100 } 101 // 102 void Clear() 103 { 104 InputLink *pOne = m_pILHead; 105 InputLink *pTwo; 106 107 while(pOne) 108 { 109 pTwo = pOne; 110 pOne = pOne->pNext; 111 free(pTwo); 112 } 113 m_pILHead = NULL; 114 } 115 public: 116 CInputLanguage() 117 { 118 m_pILHead = NULL; 119 ListAllIM(); 120 } 121 // 122 ~CInputLanguage() 123 { 124 Clear(); 125 } 126 // 127 bool SelectInputIM(InputLink *pIL) 128 { 129 if(!pIL) 130 return FALSE; 131 HKL hkl; 132 133 hkl = LoadKeyboardLayout(pIL->tcID,KLF_ACTIVATE); // 装载输入法 134 if(NULL == hkl) 135 return FALSE; 136 else 137 { 138 ActivateKeyboardLayout(hkl,KLF_SETFORPROCESS); // 激活输入法 139 } 140 141 return TRUE; 142 } 143 //获得输入法信息链表头结点指针。 144 InputLink* GetInputIMList() 145 { 146 return m_pILHead; 147 } 148 }; 149 #endif
调用示例:
1 // TestIM.cpp : Defines the entry point for the application. 2 // 3 #include "stdafx.h" 4 #include "InputOper.h" 5 int WINAPI WinMain( HINSTANCE hInstance, 6 HINSTANCE hPrevInstance, 7 LPTSTR lpCmdLine, 8 int nCmdShow) 9 { 10 CInputLanguage *InputTest; 11 InputLink *pLPList = NULL; 12 InputLink *pTmpLPList = NULL; 13 // TODO: Place code here. 14 InputTest = new CInputLanguage(); 15 pLPList = InputTest->GetInputIMList(); 16 17 pTmpLPList = pLPList; 18 while(NULL != pTmpLPList) 19 { 20 //DrawText(hdc, pTmpLPList->tcName, NameBufSize, &rt, 21 // DT_SINGLELINE | DT_VCENTER | DT_CENTER); 22 pTmpLPList = pTmpLPList->pNext; 23 RETAILMSG(1,(L"SIP name of No.%d is %s/r/n",pTmpLPList->tcName)); 24 } 25 InputTest->SelectInputIM(pTmpLPList); 26 return 0; 27 }