现在好多在CE下做开发的都不使用CE的界面,所以也无法使用系统提供的输入法切换的功能。
如何自己枚举输入法,显示在自己应用的界面中,供用户选择呢?
以前在CE5下研究过一段时间相关的东东,分享出来大家一起学习。以求有抛砖引玉的作用,小心哦,不要被砖拍到,嘿嘿...
主要是下面这个类,一个.h文件:
/**************************************************************************** * Copyright (C), 2006, Leo.Zheng * File name: InputOper.h * Description: CE 5.0 输入法列表的获得 * Version: Version 0.1 * History: Leo.Zheng created 2007-10-15 * ...... *****************************************************************************/ #ifndef __INPUT_OPERATION_ #define __INPUT_OPERATION_ #include "stdafx.h" #include "Afx.h" #include "Winreg.h" #define IDBufSize 30 #define NameBufSize 100 struct InputLink { TCHAR tcID[IDBufSize]; //输入法代号。 TCHAR tcName[NameBufSize]; //输入法的说明文字。 InputLink* pNext; }; class CInputLanguage { private: InputLink *m_pILHead; // bool ListAllIM() { HKEY hPreload; HKEY hLayouts; DWORD cp = IDBufSize; TCHAR tcLp[IDBufSize]; TCHAR tcLpDefault[IDBufSize]; CString szID; CString szValueName; CString szProload = "Keyboard Layout//Preload"; // 输入法顺序 CString szLayouts = "System//CurrentControlSet//Control//Layouts//"; // 输入法名称 int i = 1; DWORD lpT = REG_SZ; // TCHAR tcBuffer[NameBufSize] = {0}; DWORD dwLen = 0; LONG nRetValue = 0; // 读默认的输入法 if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,szProload,0,0,&hPreload)) { nRetValue = RegQueryValueEx(hPreload,TEXT(""),NULL,&lpT,(LPBYTE)tcLp,&cp); if(ERROR_SUCCESS == nRetValue) { wcscpy(tcLpDefault,tcLp); } } // 读所有的输入法 szID.Format(TEXT("%s//%d"),szProload,i); while(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER,szID,0,0,&hPreload)) { szValueName.Format(TEXT("%s"),TEXT("")); // RegEnumKeyEx(hPreload,0,tcBuffer,&dwLen,NULL,NULL,NULL,NULL); if(ERROR_SUCCESS == RegQueryValueEx(hPreload,szValueName,NULL,&lpT,(LPBYTE)tcLp,&cp)) { CString szTempName; szTempName = szLayouts + (LPCTSTR)(LPTSTR)tcLp; if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,szTempName,0,0,&hLayouts)) { TCHAR lpD[NameBufSize]; DWORD lpS = NameBufSize; // DataSize if(ERROR_SUCCESS == RegQueryValueEx(hLayouts,TEXT("Layout Text"),NULL,&lpT,(LPBYTE)lpD,&lpS)) { InputLink *pOne = m_pILHead; InputLink *pTwo = (InputLink *)malloc(sizeof(struct InputLink)); wcscpy(pTwo->tcID,tcLp); wcscpy(pTwo->tcName,lpD); pTwo->pNext = NULL; if(pOne) { while(pOne->pNext) { pOne = pOne->pNext; } pOne->pNext = pTwo; } else { m_pILHead = pTwo; } } } ::RegCloseKey(hLayouts); } i++; szID.Format(TEXT("%s//%d"),szProload,i); } ::RegCloseKey(hPreload); return (NULL != m_pILHead); } // void Clear() { InputLink *pOne = m_pILHead; InputLink *pTwo; while(pOne) { pTwo = pOne; pOne = pOne->pNext; free(pTwo); } m_pILHead = NULL; } public: CInputLanguage() { m_pILHead = NULL; ListAllIM(); } // ~CInputLanguage() { Clear(); } // bool SelectInputIM(InputLink *pIL) { if(!pIL) return FALSE; HKL hkl; hkl = LoadKeyboardLayout(pIL->tcID,KLF_ACTIVATE); // 装载输入法 if(NULL == hkl) return FALSE; else { ActivateKeyboardLayout(hkl,KLF_SETFORPROCESS); // 激活输入法 } return TRUE; } //获得输入法信息链表头结点指针。 InputLink* GetInputIMList() { return m_pILHead; } }; #endif
调用示例:
// TestIM.cpp : Defines the entry point for the application. // #include "stdafx.h" #include "InputOper.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { CInputLanguage *InputTest; InputLink *pLPList = NULL; InputLink *pTmpLPList = NULL; // TODO: Place code here. InputTest = new CInputLanguage(); pLPList = InputTest->GetInputIMList(); pTmpLPList = pLPList; while(NULL != pTmpLPList) { //DrawText(hdc, pTmpLPList->tcName, NameBufSize, &rt, // DT_SINGLELINE | DT_VCENTER | DT_CENTER); pTmpLPList = pTmpLPList->pNext; RETAILMSG(1,(L"SIP name of No.%d is %s/r/n",pTmpLPList->tcName)); } InputTest->SelectInputIM(pTmpLPList); return 0; }