新建一个ATL工程建一个activex控件,在网页中用js调用其函数:
功能大体是:以IOleClientSite接口取得这个控件的父窗口P,创建线程B,B里建一个P的子窗口C并有自己的消息循环。现在C可能在窗口处理函数里调MessageBox(NULL,...),弹出了如果先不关闭,激活其他窗口再回来关闭,窗口C就再也收不到输入法相关消息(WM_IME_SETCONTEXT,.ect).除非再弹后保证关闭MsgBox前激活的窗口是C,才回复正常。经SPY++观察发现正常情况下,MsgBox弹出时C收到WM_IME_SETCONTEXT,fSet = 0,关闭收到同样消息,fSet = 1. 如果关闭前激活的是其他窗口,后者将收不到,且以后IME相关的消息再也收不到了,即使在WM_SETFOCUS时主动发一个WM_IME_SETCONTEXT也无法恢复。具体表现为CTRL + SPACE单单产生KEYDOWN,UP消息,中间没有IME消息(正常是有的)以上情况如果C建立在和P同一个线程就不会有问题,即便激活其他窗口后关闭MSGBOX收不到WM_IME_SETCONTEXT,但点击窗口C时会收到WM_IME_SETCONTEXT,一切又正常;不在同一线程时,如果没出现上面操作,C有焦点,点击时会收到WM_IME_SETCONTEXT,但调用栈和同一线程时不同。一旦有这些操作后就都不行了。         创建线程B的原因是C的窗口过程处理非常多的东西,且是个写好的dll。
放同一线程的方案试过,但绕的更多了。有人遇到过这种问题么,做那些操作后windows为什么就不通知窗口C相关的IME消息了。估计是因为窗口没满足什么条件?

解决方案 »

  1.   

    有ActiveX控件,父子窗口不在同一线程,输入法相关经验的求分析吧,困扰一周了。
    其实用同一线程的方案做了,但感觉改的比较绕(hook主线程的加速键,跨线程发消息,遇到很多问题。比在不同线程方案曲折很多,但问题都知道原因,能掌控)。                  
    不同线程做法其实很自然,却有这个问题。
      

  2.   

    If the application has created an IME window, it should call ImmIsUIMessage. Otherwise, it should pass this message to DefWindowProc.
    你是自己处理了WM_IME_SETCONTEXT消息还是交给了ImmIsUIMessage处理的,或者是DefWindowProc.
      

  3.   

    因为是activeX,所以IE负责消息循环,所以IE可能对WM_IME_SETCONTEXT做了处理,而你自己起的新线程中创建的窗口有自己的消息队列,对WM_IME_SETCONTEXT的处理方式是否正确.
      

  4.   

    2F
    我没建IME WINDOWS,这个窗口只是能接受IME消息而已,所有的IME消息(实际上就只有IME_NOTIFY)只是拿到做了写读取信息相关,然后给默认的处理函数了。
    3F
    自己的消息队列对这些IME消息都是默认处理。
      

  5.   

    对于IME没什么经验,有个建议,你可以做个简单的实验,不用ocx,而用exe来模拟你的环境,很简单的在线程中创建一个类似的对话框,看看是否和ocx中的现象一致.要判断的问题有两个,就是在线程中创建的窗口的父窗口是谁,父窗口是否和该窗口在同一消息队列中,对结果会产生什么影响.还有就是IE对IME消息是否有特殊处理.