GetWindowText的怪异行为

作者: admin 分类: Windows api 发布时间: 2013-05-15 09:25 ė3,467 浏览数 6没有评论
文章转自王牌软件
站长推荐:NSetup一键部署软件
一键式完成美化安装包制作,自动增量升级,数据统计,数字签名。应对各种复杂场景,脚本模块化拆分,常规复杂的脚本代码,图形化设置。无需专业的研发经验,轻松完成项目部署。(www.nsetup.cn)

在看The old new thing时偶然发现GetWindowText这个API的一些八卦,翻了MSDN之后,觉得这个API的确很有意思,远不止之前所认为仅是简单的获取目标窗口的文字。

1.普遍真理

在写Win32程序时,GetWindowText最常见的用途是获取目标窗口的文本,以handle进行查找匹配。

即如下图

2.从MSDN说起

在MSDN中,对GetWindowText描述如下:

The GetWindowText function copies the text of the specified window’s title bar (if it has one) into a buffer. If the specified window is a control, the text of the control is copied. However, GetWindowText cannot retrieve the text of a control in another application.

这里所说的text of a control中的control指的是textbox一类的控件。

大意上,不能用GetWindowText去获取非自身进程控件的文本,这个经常被人忽略

这个看上去是一个很奇怪的问题,为什么GetWindowText的行为如此怪异?

3.追本溯源

在设计上,很多问题都可以归咎为历史遗留问题,GetWindowText的怪异行为也不例外。

在Windows1.0时代,那时的Win还是cooperative multitasked system。当一个程序获得控制权时,它将一直占用这个控制权,直到使用Peekmessage之类的函数释放控制权。而且拥有控制权的程序得保证所有 的窗体都能正常的响应消息,保证控制权的正常交接。

而GetWindowText最初的设计基于一个假设:GWT可以随时获得目标窗体的数据,也即目标窗体不会挂起。所以当时的GetWindowText只有一行代码:call了一下SendMessage,向目标窗体发送WM_GETTEXT消息

而到了Win32时代,Win已经是preemptive multitasked system了,当你要往一个窗体发送消息时,那个窗体可能还在挂起。

显然,原有的GetWindowText的行为遭到了挑战。

为了保证GetWindowText不受窗体挂起的影响,并且保证向后兼容,M$的工程师做出了一个折中的办法:

(1)如果目标窗体属于自身进程,仍然发送WM_GETTEXT消息。虽然目标窗体也可能处于挂起状态,但是M$的工程师认为,那是你的窗体,你得对这一切负责。
(2)如果目标窗体属于其他进程,就从窗体的special place中获取文本。(special place指的是CreateWindowEx时设置的窗口标题的内存地址)。

对于第二点,由于大部分控件的文本只有标题,所以这个方法在一定程度上是可行的,但是对于一类控件除外:TextBox一类的文本类控件。

这些控件的标题都为空,所以你用GetWindowText得到的结果永远是null

正确的做法是手动发送WM_GETTEXT之类的消息。

但是由于SendMessage需要一直等到消息处理完毕后才返回,所以如果目标窗口处于挂起状态,你还是得负起这个责任。

4.总结

GetWindowText的怪异行为说明两个问题:1)MSDN有时候也不是很靠谱,应该多看看Remark 2)设计上由于兼容性而产生的历史问题多得让人蛋疼



只回答业务咨询点击这里给我发消息 点击这里给我发消息

学习日记,兼职软件设计,软件修改,毕业设计。

本文出自 学习日记,转载时请注明出处及相应链接。

本文永久链接: https://www.softwareace.cn/?p=416

0

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">


Ɣ回顶部

无觅相关文章插件,快速提升流量