向某个窗口发送汉字时,自动打开输入法。(2k下正常,98下错!请帮助!)(100分)

  • 主题发起人 主题发起人 sanmzhou
  • 开始时间 开始时间
S

sanmzhou

Unregistered / Unconfirmed
GUEST, unregistred user!
[:(]<br><br>我下面这段代码,是向一个窗口中传送字母或汉字,<br>经测试在2k下一切正常,但在98下,向单层窗口(如记事本)能正常显示传送的汉字,<br>但在多层窗口,如word中,必须手动打开中文输入法才能正常显示汉字,否则显示为<br>乱码!请大家帮我查一下错!谢谢拉!<br><br>///////////////////////////////////<br>// 向当前窗口输出内容<br>///////////////////////////////////<br>function input_process(var str : array of char ; outlen : integer ; Frm_H : THandle) : boolean ; stdcall;<br>var<br>&nbsp; h_Wnd : HWND;<br>&nbsp; num : array[0..3] of char ;<br>&nbsp; dwThreadID, dwCurrentThreadID : DWORD;<br>&nbsp; pt: TPoint;<br>&nbsp; CR_flag : BYTE;<br>&nbsp; old_hkl ,myhkl: HKL;<br>&nbsp; setflag : integer;<br>&nbsp; i : integer;<br>&nbsp; main_handle : THandle;<br>begin<br>&nbsp; main_handle := Frm_H;<br>&nbsp; CR_flag := $0d;<br>&nbsp; setflag := 0;<br>&nbsp; &nbsp; //检查哪个窗口掌握光标<br>&nbsp; &nbsp; GetCursorPos(pt);<br>&nbsp; &nbsp; h_Wnd := WindowFromPoint(pt);<br>&nbsp; &nbsp; //获得光标所有者的线程ID<br>&nbsp; &nbsp; dwThreadID := GetWindowThreadProcessId(h_Wnd,nil);<br>&nbsp; &nbsp; //获得当前线程的ID<br>&nbsp; &nbsp; dwCurrentThreadID := GetCurrentThreadId();<br>&nbsp; &nbsp; old_hkl := GetKeyBoardLayOut(0); &nbsp;//保存旧的HKL<br>&nbsp; &nbsp; if (dwCurrentThreadID &lt;&gt; dwThreadID) then &nbsp;//如果输入焦点在别的线程<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; if AttachThreadInput(dwThreadID,dwCurrentThreadID,True) then //连接线程<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; h_Wnd := GetFocus();<br>&nbsp; &nbsp; &nbsp; &nbsp; if outlen = 1 then //如串口内容为单个字符<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; num[0] := str[0];<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ord(num[0]) = $08 then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keybd_event( VK_BACK,VK_BACK,KEYEVENTF_EXTENDEDKEY,0 );<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keybd_event( VK_BACK,VK_BACK,KEYEVENTF_KEYUP,0);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end else if ord(num[0]) = $0A then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keybd_event( VK_RETURN,VK_RETURN,KEYEVENTF_EXTENDEDKEY,0 );<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; keybd_event( VK_RETURN,VK_RETURN,KEYEVENTF_KEYUP,0);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SendMessage(h_Wnd,WM_IME_CHAR,ord(num[0]),0);<br>&nbsp; &nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; &nbsp; else if outlen = 2 then &nbsp;//如串口内容为双字节,打开汉字输入法<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if screen.Imes.Count = 0 then &nbsp; //screen.Imes.Count 得到系统中文输入法个数<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; showMessage(addIME);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if not ImmIsIME(GetKeyBoardLayOut(0)) then //判断是否在中文状态,若不是<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; myhkl:=hkl(screen.Imes.objects[screen.Imes.Count-1]);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //得到objects[screen.Imes.Count-1]对应的HKL句柄<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; activatekeyboardlayout(myhkl,KLF_ACTIVATE);//让得到的HKL句柄起作用<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setflag :=1 ;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for i:=0 to 1 do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PostMessage(h_Wnd,WM_CHAR,WPARAM(str),1); &nbsp; //使用WM_CHAR信号<br><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if setflag = 1 then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//如打开了新的中文输入法,则关闭它<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; activatekeyboardlayout(old_hkl,KLF_ACTIVATE);//让旧的HKL句柄起作用。<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setflag := 0;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AttachThreadInput(dwThreadID,dwCurrentThreadID,False); //解除线程连接<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>end;
 
我试了一下<br>使用WM_CHAR送字符,记事本正常,UltraEdit和Word都错,UltraEdit收到的全是FF<br>使用WM_IME_CHAR送,UltraEdit也正常了,但WORD还是乱码<br>在送字符前,先送WM_INPUTLANGCHANGEREQUEST和WM_INPUTLANGCHANGE,转到中文输入法,<br>再送WM_IME_NOTIFY带IMN_OPENCANDIDATE打开输入法,就可以用WM_IME_CHAR给WORD送中文字符了,<br>但是可以明显地看到WORD里中文输入法小窗口的打开和关闭,很讨厌<br>
 
事实上,在98下跟踪中文输入过程,根本没向WORD发送WM_IME_CHAR消息<br>因此怀疑WORD自己处理了WM_IME_STARTCOMPOSITION、WM_IME_COMPOSITION和WM_IME_ENDCOMPOSITION消息<br>郁闷中
 
astros!<br>刚才,我使用如下语句:<br>&nbsp; SendMessage(h_Wnd, WM_INPUTLANGCHANGEREQUEST, 0, 0);<br>&nbsp; SendMessage(h_Wnd, WM_INPUTLANGCHANGE, 0, 0);<br>&nbsp; SendMessage(h_Wnd, WM_IME_NOTIFY, IMN_OPENCANDIDATE, 0);<br>在2000下调试时,运行时在左下脚会弹出一个当前输入法状态的小窗口,<br>在所有的编辑窗口(word,ultra等)都能正常显示中文,<br>但我转到98下运行时发现无法弹出当前输入法状态的小窗口,<br>所以,在输入中文时,又显示为乱码!请问为什么?谢谢
 
我没有2000,没试过<br>不过我在98下的程序和你的不一样:<br>&nbsp; &nbsp; HKL chkl = (HKL)(Screen-&gt;Imes-&gt;Objects[0]);<br>&nbsp; &nbsp; SendMessage(hcwnd, WM_INPUTLANGCHANGEREQUEST, 1, (long)chkl);<br>&nbsp; &nbsp; SendMessage(hcwnd, WM_INPUTLANGCHANGE, GB2312_CHARSET, (long)chkl);<br>&nbsp; &nbsp; SendMessage(hcwnd, WM_IME_NOTIFY, IMN_OPENCANDIDATE, 0);<br>是不是这个原因?
 
不错!正是这个原因,我试了一下!<br>请问,那如何关闭中文输入法,还原到<br>英文输入法呢?<br>一定要关掉输入法状态的小窗口!<br>我现在关不掉!(98下)
 
我是这么做的:<br>&nbsp; &nbsp; HKL ehkl = (HKL)0x04090409;<br>&nbsp; &nbsp; SendMessage(hcwnd, WM_IME_NOTIFY, IMN_CLOSECANDIDATE, 0);<br>&nbsp; &nbsp; SendMessage(hcwnd, WM_INPUTLANGCHANGEREQUEST, 1, (long)ehkl);<br>&nbsp; &nbsp; SendMessage(hcwnd, WM_INPUTLANGCHANGE, 1, (long)ehkl);<br>这个0X04090409是我跟踪消息得到的,只知道0X0409是美国英语的语言代码,但字符集里查不到这个代码的意义<br>
 
另外,我实际使用时,发现使用<br>&nbsp; &nbsp; HKL chkl = (HKL)(Screen-&gt;Imes-&gt;Objects[0]);<br>&nbsp; &nbsp; SendMessage(hcwnd, WM_INPUTLANGCHANGEREQUEST, 1, (long)chkl);<br>&nbsp; &nbsp; SendMessage(hcwnd, WM_INPUTLANGCHANGE, GB2312_CHARSET, (long)chkl);<br>&nbsp; &nbsp; SendMessage(hcwnd, WM_IME_NOTIFY, IMN_OPENCANDIDATE, 0);<br>时,呼叫和被叫两个线程的输入法状态窗口都打开了。<br>而<br>&nbsp; &nbsp;HKL ehkl = (HKL)0x04090409;<br>&nbsp; &nbsp; SendMessage(hcwnd, WM_IME_NOTIFY, IMN_CLOSECANDIDATE, 0);<br>&nbsp; &nbsp; SendMessage(hcwnd, WM_INPUTLANGCHANGEREQUEST, 1, (long)ehkl);<br>&nbsp; &nbsp; SendMessage(hcwnd, WM_INPUTLANGCHANGE, 1, (long)ehkl);<br>时,被叫的线程的输入法状态窗口关掉了,但呼叫的线程却没有关掉!<br>为什么?
 
奇怪了,我在98下试过多次,发送消息进程的输入法窗口从没打开过
 
后退
顶部