转载地址:http://blog.sina.com.cn/s/blog_4ed1e0e40100g8ag.html

今天碰到一个问题:如何在程序A中模拟Tab按键消息发送给前台窗口(foreground window)?

正常情况在对话框程序中,用户敲击Tab键后,窗体会收到WM_KEYDOWN消息,wParam为VK_TAB,而MSG结构中的hwnd则为上一个拥有键盘焦点的控件的窗口句柄。

在程序A中获取前台窗口是件容易的事,GetForegroundWindow就OK了。如何获得前台窗口上当前拥有键盘焦点的控件的窗口句柄呢?

获取拥有键盘焦点的窗口的句柄,可以用GetFocus。但是,看看MSDN中关于GetFocus的说明,有这么一句:The GetFocus function retrieves the handle to the window that has the keyboard focus, if the window is attached to the calling thread's message queue. 前半句好理解,正是我们想要的。可是,后面有个“但是”——如果窗口贴附到(attached to)调用线程的消息队列。

这个“但是”很要命,因为前台窗口显然没有贴附到程序A的调用线程的消息队列中。怎么办?

幸好Windows为我们提供了AttachThreadInput,它可以将一个线程的输入处理机制贴附到另一个线程。这样我们就有了下面的代码:
    // 获取创建前台窗口的线程
    DWORD dwThread = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
    // 将前台窗口线程贴附到当前线程(也就是程序A中的调用线程)
    AttachThreadInput(dwThread, GetCurrentThreadId(), TRUE); //将前台窗口贴附到程序A的调用线程的消息队列中,前台窗口与程序A共享键盘输入消息
    // 获取前台焦点窗口句柄
    HWND hFocus = GetFocus();
    // 解除贴附
    AttachThreadInput(dwThread, GetCurrentThreadId(), FALSE);
    // 发送消息
    PostMessage(hFocus, WM_KEYDOWN, VK_TAB, 0);
    ......

理解:AttachThreadInput()实现了不同线程之间的通信,上文中,AttachThreadInput()实现了将前台窗口贴附到本程序的调用线程的消息队列中,并使用GetFocus()获取到前台拥有输入焦点的窗口控件,因为AttachThreadInput()本函数(既“连接线程输入函数”)允许线程和进程共享输入队列。连接了线程后,输入焦点、窗口激活、鼠标捕获、键盘状态以及输入队列状态都会进入共享状态。  所以程序A中发送信息,相当于(贴附到A的)前台窗口发送信息。

转载于:https://blog.51cto.com/whatever957/1595668

AttachThreadInput的使用与理解相关推荐

  1. AttachThreadInput的用法

    今天碰到一个问题:如何在程序A中模拟Tab按键消息发送给前台窗口(foreground window)? 正 常情况在对话框程序中,用户敲击Tab键后,窗体会收到WM_KEYDOWN消息,wParam ...

  2. VC获取其它程序窗口焦点方法 AttachThreadInput的用法

    1.不同线程的处理方法 如何在2K/xp下使窗口获取焦点 //捕捉并设置当前焦点窗口为我们的窗口 AttachThreadInput(     GetWindowThreadProcessId(    ...

  3. [转]无焦点显示窗口解决方法 [转]AttachThreadInput的用法

    tag: 激活无焦点窗口 转自:http://blog.csdn.net/abcpanpeng/archive/2009/12/29/5099580.aspx 1.不同线程的处理方法 如何在2K/xp ...

  4. 无焦点显示窗口解决方法 [转]AttachThreadInput的用法

    tag: 激活无焦点窗口 转自:http://blog.csdn.net/abcpanpeng/archive/2009/12/29/5099580.aspx 1.不同线程的处理方法 如何在2K/xp ...

  5. 通用解题法——回溯算法(理解+练习)

    积累算法经验,积累解题方法--回溯算法,你必须要掌握的解题方法! 什么是回溯算法呢? 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就&quo ...

  6. stream流对象的理解及使用

    我的理解:用stream流式处理数据,将数据用一个一个方法去 . (点,即调用) 得到新的数据结果,可以一步达成. 有多种方式生成 Stream Source: 从 Collection 和数组 Co ...

  7. Linux shell 学习笔记(11)— 理解输入和输出(标准输入、输出、错误以及临时重定向和永久重定向)

    1. 理解输入和输出 1.1 标准文件描述符 Linux 系统将每个对象当作文件处理.这包括输入和输出进程.Linux 用文件描述符(file descriptor)来标识每个文件对象.文件描述符是一 ...

  8. java局部变量全局变量,实例变量的理解

    java局部变量全局变量,实例变量的理解 局部变量 可以理解为写在方法中的变量. public class Variable {//类变量static String name = "小明&q ...

  9. 智能文档理解:通用文档预训练模型

    预训练模型到底是什么,它是如何被应用在产品里,未来又有哪些机会和挑战? 预训练模型把迁移学习很好地用起来了,让我们感到眼前一亮.这和小孩子读书一样,一开始语文.数学.化学都学,读书.网上游戏等,在脑子 ...

最新文章

  1. EM: 生而为菌,自强不息-嗜酸杆菌在重金属污染土壤中的生态适应性机制
  2. Excel的日期格式约定与解析
  3. 进程间通信(4) 匿名管道
  4. Http协议简单介绍
  5. 全局变量的异步I/O问题
  6. Mysql密码忘记了怎么办?
  7. 算法总结-1算法入门
  8. linux虚拟化桌面协议,桌面虚拟化传输协议之android spice
  9. 计算机图形设计案例,9《计算机图形图像的设计的案例实训题.doc
  10. 达观智能制造知识图谱平台助力实现先进制造业“十四五”规划
  11. 微型计算机系统软件包括哪些,计算机的软件系统包括哪些内容
  12. Android基础夯实--重温动画(四)之属性动画 ValueAnimator详解
  13. iOS开发bug消灭之:Your application has presented a UIAlertController of style ...
  14. mysql备份文件如何还原数据库文件_数据库备份文件还原方法
  15. html5写自我介绍,一分钟标签式自我介绍4篇
  16. 3DES加密(iOS,Android,Java)
  17. 经典排序算法之:堆排序
  18. android 后台数据获取,android post方式给后台服务器传递数据
  19. 使用Visual Studio怎样制作登录界面
  20. python中列表概念,Python 列表的简单介绍

热门文章

  1. LINUX下使用IntelliJ IDEA Community Edition配置lua编辑器Emmylua
  2. python3爬取全民K歌
  3. 氢os 7android 5次 n,一加7手机的氢OS系统,在国内处于什么水平?看完后瞬间明白了...
  4. 【青书学堂】管理学基础(直播课) 第一学期 作业
  5. python—selenium —xpath定位方法详解
  6. java键盘输入整数_Java中从键盘输入多个整数的方法
  7. 瑞安市计算机技术学校,瑞安市第七中学2019年招生简章
  8. shell清除文件末尾所有空行
  9. 第三方系统使用用户名密码绑定微信号,怎么验证登录状态安全
  10. ios7版 30天精通iPhone手机编程 第1天 ios7开发基础知识点