使用过Access的人都知道,在表数据输入时Access自动切换输入法,如某字段需要输入英文时自动切换到En输入状态,如另一字段需要输入中文自动切换到某中文输入状态;这给我们的数据输入提供了极大的方便。
如果在应用程序中也如Access那样为用户提供输入法智能自动切换,那么这样的应用程序不仅给用户带来了方便同时也显得我们更加专业化;这样我们的应用程序也就更加具有竞争力。
如大多数的系统配置一样,输入法的控制也是通过对相应的注册表项的修改来实现的;在本文里我们就不对相关注册表项的具体位置及相关项的说明进行解说;为了实用起见,我们就以代码来说话吧;具体代码如下:
/***************文件开始(InputLanguage.h)****************/
//InputLanguage.h
#ifndef INPUTLANGUAGE_H
#define INPUTLANGUAGE_H
#ifndef UNICODE
#define U_strcpy strcpy
#define U_strcmp strcmp
#else
#define U_strcpy wcscpy
#define U_strcmp wcscmp
#endif
typedef struct tag_ILNode
{
TCHAR ilID[15]; //输入法代号
TCHAR szName[100];//输入法的说明文字
tag_ILNode* pNext;
}ILNODE,*PILNODE;
class CInputLanguage
{
public:
CInputLanguage( );
~CInputLanguage( );
public:
//加载系统中所有已安装输入法
int LoadIL( void );
//根据输入法名称查找输入法
PILNODE FindILByName( TCHAR* pName );
//根据输入法代码查找输入法
PILNODE FindILByCode( TCHAR* pCode );
//获取当前输入当代码
int GetCurrentILCode( TCHAR* pCode );
//设置当前输入法
int SelectIL( PILNODE pIL );
//清空已加载输入法信息
int Clear( void );
private:
PILNODE m_pILHead;
};
#endif
/***************文件结束****************/
/***************文件开始(InputLanguage.cpp)****************/
//InputLanguage.cpp
#include "StdAfx.h"
#include "InputLanguage.h"
CInputLanguage::CInputLanguage( )
{
m_pILHead = NULL;
}
CInputLanguage::~CInputLanguage( )
{
Clear( );
}
int CInputLanguage::LoadIL( void )
{
HKEY hKey,hKey1;
DWORD cp=16;
TCHAR lp[15];
CString szID;
CString szKeyName,szKeyName1;
szKeyName = _T("Keyboard Layout\\Preload");
szKeyName1 = _T("System\\CurrentControlSet\\Control\\Keyboard Layouts\\");
int i=1;
szID.Format(_T("%d"),i);
DWORD lpT=REG_SZ;
if(::RegOpenKey(HKEY_CURRENT_USER,szKeyName,&hKey)==ERROR_SUCCESS )
{
while( ::RegQueryValueEx(hKey,szID,NULL,&lpT,(LPBYTE)lp,&cp) == ERROR_SUCCESS )
{
CString szTempName;
szTempName = szKeyName1 + (LPCTSTR)(LPTSTR)lp;
if(RegOpenKey(HKEY_LOCAL_MACHINE,szTempName,&hKey1)==ERROR_SUCCESS )
{
TCHAR lpD[100];
DWORD lpS=100; //DataSize
if(RegQueryValueEx(hKey1,_T("Layout Text"),NULL,&lpT,(LPBYTE)lpD,&lpS)==ERROR_SUCCESS)
{
PILNODE p1,p2;
p1 = m_pILHead;
p2 = new(ILNODE);
U_strcpy(p2->ilID,lp);
U_strcpy(p2->szName,lpD);
p2->pNext = NULL;
if( p1 )
{
while( p1->pNext )
{
p1 = p1->pNext;
}
p1->pNext = p2;
}else
{
m_pILHead = p2;
}
}
}
::RegCloseKey(hKey1);
i++;
szID.Format(_T("%d"),i);
}
}
::RegCloseKey(hKey);
if ( m_pILHead == NULL )
{
return -1;
}else
{
return 0;
}
}
int CInputLanguage::SelectIL( PILNODE pIL )
{
if( !pIL )
{
return -1;
}
HKL hkl;
hkl=LoadKeyboardLayout(pIL->ilID,KLF_ACTIVATE);//装载输入法
if( hkl==NULL )
{
return -2;
}else
{
ActivateKeyboardLayout(hkl,KLF_SETFORPROCESS);//激活输入法
}
return 0;
}
int CInputLanguage::Clear( void )
{
PILNODE p1,p2;
p1 = m_pILHead;
while( p1 )
{
p2 = p1;
p1 = p1->pNext;
delete(p2);
}
m_pILHead = NULL;
return 0;
}
PILNODE CInputLanguage::FindILByName( TCHAR* pName )
{
PILNODE p1;
p1 = m_pILHead;
while( p1 )
{
if ( U_strcmp( pName, p1->szName ) == 0 )
{
return p1;
}
p1 = p1->pNext;
}
return NULL;
}
PILNODE CInputLanguage::FindILByCode( TCHAR* pCode )
{
PILNODE p1;
p1 = m_pILHead;
while( p1 )
{
if ( U_strcmp( pCode, p1->ilID ) == 0 )
{
return p1;
}
p1 = p1->pNext;
}
return NULL;
}
int CInputLanguage::GetCurrentILCode( TCHAR* pCode )
{
int nRet;
nRet = GetKeyboardLayoutName( pCode );
if ( nRet != 0 )
{
return 0;
}else
{
return -1;
}
}
/***************文件结束****************/
//对于CinputLanguage类的使用方法请参考本文对应之例子代码。