我知道是什么原因:主要是该消息不仅编辑窗口会接受到,而且IME窗口还会接受,对于微软拼音,有两个窗口,Default IME和PINGGNT,我应该如何屏蔽掉输入法窗口的消息呢?

解决方案 »

  1.   

    可以用HWND来区分吗?你试试吧:)
      

  2.   

    switch(pcw->message)
    {
    case WM_IME_STARTCOMPOSITION:
    if(m_hEditWnd == INVALID_HANDLE_VALUE)
    m_hEditWnd = pcw->hwnd;
    break;
    case WM_IME_ENDCOMPOSITION:
    if(m_hEditWnd == INVALID_HANDLE_VALUE)
    {
    // add this string into text buffer of application
    COPYDATASTRUCT copyData;
    copyData.cbData = strlen(m_szBuf)+1;
    copyData.lpData = m_szBuf;
    SendMessage(m_hWnd, WM_COPYDATA, 0, LPARAM(&copyData));
    }
    m_hEditWnd = INVALID_HANDLE_VALUE;
    break;
    case WM_IME_COMPOSITION: if ((lParam & GCS_RESULTSTR) && m_hEditWnd == pcw->hwnd)
    {
    TRACE("LPARAM: %X \n",lParam );
    HWND hWnd = ::GetActiveWindow();
    // HWND hWnd = ImmGetDefaultIMEWnd(GetActiveWindow());
    HIMC hIMC = ImmGetContext(hWnd);
    DWORD dwSize;
    if (!hIMC)
    goto lbErr;
    // Get the size of the result string.
    dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);

    // increase buffer size for NULL terminator, 
    //   maybe it is in UNICODE
    dwSize += sizeof(TCHAR);
    if(m_szBuf)
    delete[] m_szBuf;
    m_szBuf = new TCHAR[dwSize];
    memset(m_szBuf, 0, dwSize*sizeof(TCHAR));
    if (m_szBuf == NULL)
    goto lbErr;

    // Get the result strings that is generated by IME into lpstr.
    VERIFY(IMM_ERROR_NODATA != ImmGetCompositionString(hIMC, GCS_RESULTSTR, m_szBuf, dwSize));
    ImmReleaseContext(hWnd, hIMC);
    TRACE("Current Typed: %s\n", m_szBuf);
    }
    break;
    }
      

  3.   

    我在WM_IME_STARTCOMPOSITION消息里面记录下第一个发出这个消息的窗口句柄,然后在WM_IME_COMPOSITION消息里面得到中文句子m_szBuf,然后在WM_IME_ENDCOMPOSITION里面发出m_szBuf到App中
      

  4.   

    上面的方法初步解决了重复的错误,
    但是部分全角标点不能被我截获,原因是这些标点不是在CompositionWnd中输入的,而我过滤出的是Composition的窗口。
    还有,该程序可以截获notepad.exe,但是我在VC的编辑器里输入中文却不能被截获,在IE的地址栏里输入中文按下回车后,就不能再输入中文了。;(
    而在网页的编辑框里面输入中文会导致IE非法关闭;(
    Bug多多,恳请高人指点迷经!!
      

  5.   

    可以去这里看一看,有完整的解决方案,绝对实用:
    http://www.aslike.net
      

  6.   

    我最近也在作这方面的程序,
    用了一个网上别人发的Cime类:#pragma comment ( lib, "imm32.lib" )
    #include <windows.h>
    #include <imm.h>class CIme{
    bool g_bIme;//ime允许标志
    char g_szCompStr[ MAX_PATH ];//存储转换后的串
    char g_szCompReadStr[ MAX_PATH ];//存储输入的串
    char g_szCandList[ MAX_PATH ];//存储整理成字符串选字表
    int g_nImeCursor;//存储转换后的串中的光标位置
    CANDIDATELIST *g_lpCandList;//存储标准的选字表
    char g_szImeName[ 64 ];//存储输入法的名字
    bool g_bImeSharp;//全角标志
    bool g_bImeSymbol;//中文标点标志
    void ConvertCandList( CANDIDATELIST *pCandList, char *pszCandList );//将选字表整理成串
    public:
    CIme() : g_lpCandList( NULL ){ DisableIme(); }//通过DisableIme初始化一些数据
    ~CIme(){
    DisableIme();
    if( g_lpCandList ){
    GlobalFree( (HANDLE)g_lpCandList );
    g_lpCandList = NULL;
    }
    }
    //控制函数
    void DisableIme();//关闭并禁止输入法,如ime已经打开则关闭,此后玩家不能用热键呼出ime
    void EnableIme();//允许输入法,此后玩家可以用热键呼出ime
    void NextIme();//切换到下一种输入法,必须EnableIme后才有效
    void SharpIme( HWND hWnd );//切换全角/半角
    void SymbolIme( HWND hWnd );//切换中/英文标点 //状态函数
    char* GetImeName();//得到输入法名字,如果当前是英文则返回NULL
    bool IfImeSharp();//是否全角
    bool IfImeSymbol();//是否中文标点
    void GetImeInput( char **pszCompStr, char **pszCompReadStr, int *pnImeCursor, char **pszCandList );
    //得到输入法状态,四个指针任意可为NULL则此状态不回返回
    //在pszCompStr中返回转换后的串
    //在pszCompReadStr中返回键盘直接输入的串
    //在pnImeCursor中返回szCompStr的光标位置
    //在pszCandList中返回选字表,每项之间以\t分隔 //必须在消息中调用的函数,如果返回是true,则窗口函数应直接返回0,否则应传递给DefWindowProc
    bool OnWM_INPUTLANGCHANGEREQUEST();
    bool OnWM_INPUTLANGCHANGE( HWND hWnd );
    bool OnWM_IME_SETCONTEXT(){ return true; }
    bool OnWM_IME_STARTCOMPOSITION(){ return true; }
    bool OnWM_IME_ENDCOMPOSITION(){ return true; }
    bool OnWM_IME_NOTIFY( HWND hWnd, WPARAM wParam );
    bool OnWM_IME_COMPOSITION( HWND hWnd, LPARAM lParam );
    };void CIme::DisableIme(){
    while( ImmIsIME( GetKeyboardLayout( 0 )))
    ActivateKeyboardLayout(( HKL )HKL_NEXT, 0 );//如果ime打开通过循环切换到下一个关闭
    g_bIme = false;
    g_szImeName[ 0 ] = 0;
    g_szCompStr[ 0 ] = 0;
    g_szCompReadStr[ 0 ] = 0;
    g_szCandList[ 0 ] = 0;
    g_nImeCursor = 0;
    }void CIme::EnableIme(){
    g_bIme = true;
    }void CIme::NextIme(){
    if( g_bIme )ActivateKeyboardLayout(( HKL )HKL_NEXT, 0 );
    }void CIme::SharpIme( HWND hWnd ){
    ImmSimulateHotKey( hWnd, IME_CHOTKEY_SHAPE_TOGGLE );
    }void CIme::SymbolIme( HWND hWnd ){
    ImmSimulateHotKey( hWnd, IME_CHOTKEY_SYMBOL_TOGGLE );
    }
      

  7.   

    能把程序发过来看看吗?
    [email protected]
    我用dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);
    得到的dwsize是0 !
      

  8.   

    泥巴泥巴,能把程序发过来看看吗?
    [email protected]
    我用dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);
    得到的dwsize是0 !