输入法是如何被激活的?

a220315410 2011-01-14 10:59:28
输入法激活的一般原则是,具有当前焦点的控件允许接受键盘输入的时候,输入法被激活。
那这个激活的过程是如何实现的?或者是如何实现对具有当前焦点的控件是允许键盘输入的?
这个判断是由系统完成还是由输入法自己完成的?
希望各位大大能够提供具体的资料。
...全文
178 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
a220315410 2011-01-17
  • 打赏
  • 举报
回复
谢谢各位的帮助,结贴。
webipstin 2011-01-14
  • 打赏
  • 举报
回复
在Windows系统中一般都安装了至少三种输入法,在输入数据时常常会切换输入法,虽然Windows系统提供了切换快捷健,但对输入工作还是带来了不少麻烦。如果在应用程序中为用户提供智能输入法自动切换,那么这样的应用程序就显得更加专业、更加具有竞争力。不知你可用过Access,在表数据输入时Access自动切换输入法,如某字段需要输入英文时自动切换到En输入状态,如另一字段需要输入中文自动切换到某中文输入状态。

  本文将对如何在Windows应用程序中动态的控制输入法的技术进行探讨。在DELPHI中许多控件都有控制输入法的属性,用户在设计时只要设置好这个属性就可以了,但在VC中并不直接提供对输入法的控制,要在VC应用中实现这种功能必须调用Windows API。在本文中我将用一个类将与输入法操作有关的Windows API函数进行封装,读者可以直接将这个类导入项目工程中,通过操作这个类来实现对输入法的控制,这样更适合于面向对象的开发。

  要想控制输入法,首先要解决的问题是如果获得系统已安装的输入法信息。在Windows平台下,每个安装的输入法都在注册表中注册了相关信息。在“HKEY_CURRENT_USER\keyboard layout\preload”键下就可以找到这些信息,键下由以1为基的递增数字做为值名(暂取名为数字号),其值的内容是一个由八个数字组成的字符串(暂取名为代号,如 "e0040804 "),其中左4位是设备代码(device identifier),右4位是语言代码(language identifier)。例如上面:左e004指智能ABC,右0804指大陆中文。在MSDN中对所有代码做了详细的说明,如感兴趣请浏览MSDN相关内容。另外要说明一点的是在Windows98版本中输入法注册信息与上面说明略有不同,它是将已安装的输入法的数字号做为…\Preload下面的子键,而Windows2000将数字号做为…\Preload键下的值。

   通过读取注册表中的输入法信息,可以列出所有已安装的输入法,但得到的输入法信息只是一些让人难懂的数字串,如何将这些数字串翻译成易懂的文字说明呢?同样, 在HKEY_LOCAL_MACHINE: "System\CurrentControlSet\Control\Keyboard Layouts\ "键下注册了这些信息,它的子键名为输入法代号(keyboard layout),内容为该输入法的ime文件,名称等信息。到此,我们已经了解了Windows系统控制输入法的原理知识,下面我们开始着手创建一个控制输入法的C++类,主要步骤如下:

  1. 创建一个新类,新类名为:CInputLanguage

  2. 新建一个保存输入法信息的结构。当加载系统已安装的输入法信息时,用一个此结构的链表来保存输入法信息。

struct IL{
 char ilID[15]; //输入法代号。
 char szName[100];//输入法的说明文字。
 IL* pNext;
};

  3. 加入一个私有的成员变量

   IL* m_pILHead;

  4. 加入加载输入法列表信息的成员函数

//此函数只针对Windows2000以上版本,如要在Windows98版本的代码请与笔者联系。

BOOL CInputLanguage::LoadInputLanguage()
{
 HKEY hKey,hKey1;
 DWORD cp=16;
 char lp[15];
 CString szID;
 CString szKeyName,szKeyName1;
 szKeyName = "Keyboard Layout\\Preload ";
 szKeyName1 = "System\\CurrentControlSet\\Control\\Keyboard Layouts\\ ";

 int i=1;
 szID.Format( "%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 )
   {
    char lpD[100];
    DWORD lpS=100; //DataSize
    if(RegQueryValueEx(hKey1, "Layout text ",NULL,&lpT,(LPBYTE)lpD,&lpS)==ERROR_SUCCESS)
    {
     IL* p1,*p2;
     p1 = m_pILHead;
     p2 = new(IL);
     strcpy(p2-> ilID,lp);
     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( "%d ",i);
  }
 }

 ::RegCloseKey(hKey);
 return (m_pILHead != NULL );

}


  5. 加入选择输入法成员函数

BOOL CInputLanguage::SelectInputLanguage(IL *pIL)

{
 if( !pIL ) return FALSE;
  HKL hkl;
  hkl=LoadKeyboardLayout(pIL-> ilID,KLF_ACTIVATE);//装载输入法
  if(hkl==NULL) return FALSE;
  else{
   ActivateKeyboardLayout(hkl,KLF_SETFORPROCESS);//激活输入法
  }
  return TRUE;

}


  6. 其它部分

CInputLanguage::CInputLanguage()

{
 m_pILHead = NULL;
 LoadInputLanguage();

}

CInputLanguage::~CInputLanguage()

{
 Clear();
}

//消除链表内存。

void CInputLanguage::Clear()

{
 IL* p1,*p2;
 p1 = m_pILHead;

 while( p1 )
 {
  p2 = p1;
  p1 = p1-> pNext;
  delete(p2);
 }
 m_pILHead = NULL;

}

//获得输入法信息链表头结点指针。

IL* CInputLanguage::GetInputLanguageList()

{
 return m_pILHead;
}



  使用此类时,只要将其头文件包括到要调用的文件中,调用GetInputLanguageList函数可以得到输入法信息链表的头结点指针,通过遍历此链表得到所有已安装的输入法的信息;通过SelectInputLanguage函数可以自由的控制输入法了
a220315410 2011-01-14
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 qiuchengw 的回复:]
应该是由系统完成的.
我的猜测是:
1.系统维护一个输入法列表,输入法将自己注册到系统
2.当一个窗口需要键盘输入的时候,系统为窗口挂接一个默认的输入法
3.当窗口需要切换输入法的时候,系统响应切换请求,在自己维护的列表中切换输入法

------------------------
以上纯属猜测...
[/Quote]
这个可能性的确比较高。起码输入法在安装的时候,的确是需要在注册表中注册的。如果是由输入法自身来完成焦点的监测的话,毕竟存在不必要的负荷(尤其是输入法多的时候),更麻烦的是,所有输入法都会自动启动,这个情况怎一个乱字了得。。。
qiuchengw 2011-01-14
  • 打赏
  • 举报
回复
应该是由系统完成的.
我的猜测是:
1.系统维护一个输入法列表,输入法将自己注册到系统
2.当一个窗口需要键盘输入的时候,系统为窗口挂接一个默认的输入法
3.当窗口需要切换输入法的时候,系统响应切换请求,在自己维护的列表中切换输入法

------------------------
以上纯属猜测...
a220315410 2011-01-14
  • 打赏
  • 举报
回复
一般不是都激活默认输入法的么?
我不考虑它激活哪个输入法,我只是想问,这个输入法被激活的过程是怎么样的。
ningweidong 2011-01-14
  • 打赏
  • 举报
回复
但是你怎么知道用户想用哪一种输入法?
好像还没有哪个程序有这个功能吧
tubo_true 2011-01-14
  • 打赏
  • 举报
回复
up

也有此问

16,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧