正在做一个完全自绘的编辑控件,要能处理中文。但出现了一个问题,我在程序中要响应WM_KEYDOWN消息,其中有处理左右按键来控制光标,但是当用拼音输入法进行中文输入的时候,用左右键选词和用Backspace键消去拼音字母的时候,我的控件也会同时收到相应的按键消息,也就是说,一个按键,同时引发了输入法光标的移动和我自己程序的光标的移动,但这是我不希望发生的。我希望在输入法中的任何操作对我都是透明的,我只响应WM_IME_CHAR来获得它最终的输出结果,如何才能做到?
希望各位不吝赐教,得解后定送高分!

解决方案 »

  1.   

    那就判断下按[和]的时候拼音输入法有没有启动 如果没启动才响应WM_KEYDOWN
    嘿嘿 具体怎么判断 还的找找资料
      

  2.   

    在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函数可以自由的控制输入法了
      

  3.   

    我原来做过一个编辑软件,处理过输入法,处理成功了,我是在CRichEditView中处理的,只怕不能合适你的,如果可以,把你的代码发过来,我调试一下,看能不能想出类似的办法:[email protected]
      

  4.   

    to fengqinggao(风清高):不好意思,那个源代码比较繁杂,无法脱离项目的大环境运行。
    你能简单说一下思路吗?我想只需要解决当输入法在操作的时候,WM_KEYDOWN消息自动被屏蔽即可,注意,不仅仅是针对拼音输入法,最好能适用于所有输入法。to 42252343(大跃进的猪):
    如果是通过检测输入法是否已经打开的方法,感觉还是会有缺陷,例如:微软拼音输入法3.0 中,SHIFT键可以进行中英切换,在英文状态下,虽然输入法是打开状态,但是这时的方向键控制我还是需要处理的。
      

  5.   

    你的可能比较复杂,呵呵,那我只提两个我认为关键的地方:
    1、在OnKeyDown函数中,输入中文的时候,nChar参数都是229,可以用这个特点来区别并处理;
    2、在OnKeyDown和OnKeyUp函数中处理中文,以及删除键、反向删除键,在OnChar中处理英文和字符;仅供参考,:)
      

  6.   

    to fengqinggao(风清高):果然!真是一语点醒我梦中人呀:)
    不过... 这229的依据是什么呀?各种输入法都是这样吗?有什么官方资料可考的么?