初探WINDOWS下IME程式設計 (轉)

worldblog發表於2007-12-09
初探WINDOWS下IME程式設計 (轉)[@more@]大家知道,許多有IME屬性。這麼好用的東西VC可沒自帶,怎麼辦呢?其實,可透過登錄檔,用實現。下面說一下本人對IME的研究結果,並提供示例工程供大家參考:

示例工程 10.6K


本文示例執行結果如上圖

1、將用到的API

RegOpenKey:開啟登錄檔一鍵
RegQueryValue:查詢一鍵值
RegQueryValueEx:同上
RegCloseKey:關閉開啟的鍵

LoadKeyboardLayout:裝載輸入法
ActivateKeyboardLayout:啟用輸入法

2、IME資訊在登錄檔中的位置

在HKEY_USERS:".DEFAULTkeyboard layoutpreload"放的是已的輸入法,下有幾個以數字為名的子鍵,內容是輸入法代號(keyboard layout),如"e0040804",其中左4位是裝置程式碼(device ntifier),右4位是語言程式碼(language identifier)。例如上面:左e004指智慧ABC,右0804指大陸中文。(詳見MSDN)
在HKEY_LOCAL_MACHINE:"SystemCurrentControlSetControlKeyboard Layouts"放的是已註冊的輸入法。他的子鍵名為輸入法代號(keyboard layout),內容為該輸入法的ime,名稱等資訊。

3、主要思路

我們可先把已裝的輸入法列舉出來(從登錄檔),選擇其一後,再啟用該輸入法。
兩關鍵:
HKL LoadKeyboardLayout(LPCTSTR pwszKLID,UINT Flags);
第一個引數是待開啟的輸入法代號,如"e0040804"(智慧ABC);
第二個引數是標誌位,如KLF_ACTIVATE(啟用)。

HKL ActivateKeyboardLayout(HKL hkl,UINT Flags);
第一個引數是開啟的輸入法控制程式碼(由LoadKeyboardLayout返回);
第二個引數是標誌位,如KLF_SETFORPROCESS。(詳見MSDN)

4、例子程式

新建一基於對話方塊的工程,加入一combobox控制元件,增加控制變數m_cb1。加入一edit控制元件,增加控制變數m_edt1.對combobox,增加對CBN_SELCHANGE的對映函式OnSelchangeCombo1()。對edit1,增加對EN_SETFOCUOS的SetfocusEdit1().在對話方塊類標頭檔案的public:下加入陣列宣告:CString lst[10];
在OnInitDialog()的return前加如下程式碼: HKEY hk,hk1;
long cp=16;
char lp[15];
char a[2];
a[0]='1';
a[1]='';
CString str,str1;
str=".DEFAULTkeyboard layoutpreload";//已裝的輸入法。注:有所不同
str+=a;
int i=0;
while(::RegOpenKey(HKEY_USERS,str,&hk)==ERROR_SUCCESS)//開啟鍵
{
a[0]++;//下一子鍵
str=".DEFAULTkeyboard layoutpreload";
str+=a;
if(::RegQueryValue(hk,NULL,lp,&cp)!=ERROR_SUCCESS)//已裝的輸入法
MessageBox("Error");
::RegEnumKeyEx
str1="SystemCurrentControlSetControlKeyboard Layouts";//keyboardlayoutLayout
str1+=lp;
lst[i++]=lp;
//開啟對應的keyboardlayoutLayout
if(RegOpenKey(HKEY_LOCAL_MACHINE,str1,&hk1)==ERROR_SUCCESS)
{
LPBYTE lpD=new BYTE[80];//DataValue
D lpT=REG_SZ;//DataType
DWORD lpS=80; //DataSize
if(RegQueryValueEx(hk1,"Layout text",NULL,&lpT,lpD,&lpS)!=ERROR_SUCCESS)
MessageBox("Query error",(LPCTSTR)lpD);
m_cb1.AddString((LPCTSTR)lpD);
delete lpD;
}
else MessageBox("open error");
RegCloseKey(hk1);
}
::RegCloseKey(hk);
m_cb1.SetCurSel(0);
在OnSetfocusEdit1()加入如下程式碼: CString temp;
temp=m_cb1.GetCurSel()!=CB_ERR?lst[m_cb1.GetCurSel()]:"00000409";
HKL hkl;
hkl=LoadKeyboardLayout(temp,KLF_ACTIVATE);//裝載輸入法
if(hkl==NULL) OnOK();
ActivateKeyboardLayout(hkl,KLF_SETFORPROCESS);//啟用輸入法
在OnSelchangeCombo1()加入如下程式碼: m_edt1.SetFocus();
即可編譯執行。
5、注意:win2000下有所不同。登錄檔HKEY_USERS:".DEFAULTkeyboard layoutpreload沒有子鍵只有以數字為名的項,值為輸入法代號(keyboard layout)。在示例程式碼中不僅提供了WIN 9X下的程式碼,也提供了2000下的相應程式碼段,具體請參考示例工程。



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-990660/,如需轉載,請註明出處,否則將追究法律責任。

相關文章