我的问题和http://topic.csdn.net/t/20051117/20/4400997.html里面的问题基本一致,在这里重复一遍,希望能够得到结果。我的目标是做一个类似于osk.exe的程序,但是功能有所扩展,即不仅能模拟键盘输入单字节字符,也可以向具有键盘输入焦点的窗口(任意的,比如word、qq、桌面)传送字符串。
我用了下面的方案:
自己的窗体form1,具有topmost和WS_EX_NOACTIVATE风格。窗体上安排一些speedbutton,代表要传送的字符串。这些我按钮的点击操作不会使form1得到焦点,但是按钮去可以工作。按钮点击后的操作如下:
1.利用getforegorundwindow得到窗口句柄;
2.利用GetWindowThreadProcessID得到活动窗口的线程ID;
3.利用GetCurrentThreadID得到form1的线程ID;
4.利用AttachThreadInput将上述两个线程关联起来;
5.利用GetFocus得到活动窗口的输入焦点句柄;
6.利用AttachThreadInput拆除两个线程的关联;
7.利用PostMessage想输入焦点窗口发送WM_Char消息
8.End。按理说这样就可以了,在加上其他完善性的工作基本上就完成了。但是事与愿违。执行完上述第4步的时候,前台窗口失去了焦点,这就使得Getfocus已经不能返回正确的结果了。为了找到原因,我将上述代码复制到了一个timer的事件中,执行后,前台窗口依旧失去焦点。于是去掉了窗口的WS_EX_NOACTIVATE风格,这样,运行后前台窗口就不再失去焦点了,上述代码可以工作了。但是因为需要点击form1上的按钮,因此使用定时器的方案的不能满足要求的,必须保证按钮后,前台窗口不失去焦点。现在的问题:
如何做到在form1有WS_EX_NOACTIVATE的情况下,AttachThreadInput后前台窗口不失去焦点?有人可能说可以用KEYBD_EVENT,我说KEYBD_EVENT可以模拟键盘按键,但是不能传送字符串。
可能有人说,setforegroundwindow或者bringwindowtotop就可以了。我说不行,因为在桌面上改文件名的时候,焦点只要失去,Windows就认为你改完了,这是一个不足,还有就是有些输入窗口,得到焦点就将字符串全选,比如IE的地址栏。现在请教各位大侠,并诚意邀请参与讨论,这个问题应该怎样解决?