翻译 《The Old New Thing》 - The secret life of GetWindowText

2024-04-01 01:36

本文主要是介绍翻译 《The Old New Thing》 - The secret life of GetWindowText,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

The secret life of GetWindowText - The Old New Thing (microsoft.com)icon-default.png?t=N7T8https://devblogs.microsoft.com/oldnewthing/20030821-00/?p=42833

 Raymond Chen 2003年8月21日


简要

GetWindowText() 函数比你想象的要复杂得多。尽管官方文档试图用简练的语言来阐述它,但这也就意味着你无法获得完整的信息。这里我们尝试给出一个完整的解释。

 


 

窗口如何管理它们的文本

        窗口类有两种方式来管理它们的文本。可以用户自己手动管理,也可以让系统来代劳。默认情况下,是让系统来管理的。

        如果一个窗口类让系统来管理它的文本,系统会执行以下操作:

  • 默认的 WM_NCCREATE 消息处理会取 CreateWindow/Ex 传入的 lpWindowName 参数,并将其保存在一个“特殊的地方”。
  • 默认的 WM_GETTEXT 消息处理会从那个“特殊的地方”检索字符串。
  • 默认的 WM_SETTEXT 消息处理会将字符串复制到那个“特殊的地方”。

        另一方面,如果一个窗口类手动管理它的窗口文本,系统不会做任何特殊处理,窗口类需要自己响应 WM_GETTEXT/WM_SETTEXT 消息,并显式地返回/保存字符串。

        典型的"框架窗口"(Frame Window)通常让系统管理它们的窗口文本。自定义控件通常手动管理它们的窗口文本。

GetWindowText() 的问题

  GetWindowText() 面临一个问题:窗口文本需要随时可用,不能卡住。FindWindow() 需要获取窗口文本以便找到窗口。任务切换应用程序需要获取窗口文本,以便在切换窗口中显示窗口标题。不应该允许卡住的应用程序阻塞其他应用程序。这在任务切换场景中尤其重要。

        这就不能用发送 WM_GETTEXT 消息的方式,因为处理 WM_GETTEXT 的目标窗口可能已经卡住了。相反,GetWindowText() 应该使用“特殊的地方”,因为那里不会受到应用程序卡住的影响。

        另一方面,GetWindowText() 用于从对话框上的控件中检索文本,而这些控件经常使用自定义文本管理。这就支持发送 WM_GETTEXT 消息,因为这是检索自定义管理文本的唯一方法。

所以 GetWindowText() 采取了折中的方法。

  • 如果从自己进程中的窗口获取文本,那么 GetWindowText() 会发送 WM_GETTEXT 消息。
  • 如果从其他进程中的窗口获取文本,那么 GetWindowText() 会使用“特殊的地方”中的字符串,而不发送消息。

        根据第一条规则,如果你尝试从自己进程中的窗口获取文本,而该窗口卡住了,那么 GetWindowText() 也会卡住。但因为窗口属于你的进程,这是你自己的问题,你自作自受。发送 WM_GETTEXT 消息确保了自定义文本管理的窗口(通常是自定义控件)的文本被正确检索。

        根据第二条规则,如果你尝试从另一个进程中的窗口获取文本,那么 GetWindowText() 不会发送消息;它只会从“特殊的地方”检索字符串。因为从另一个进程中的窗口获取文本的最常见原因是获取框架窗口的标题,而框架窗口通常不会进行自定义窗口文本操作,这通常会得到正确的字符串。

        文档将这简化为“GetWindowText() 无法从另一个应用程序的窗口检索文本。”(To retrieve the text of a control in another process, send a WM_GETTEXT message directly instead of calling GetWindowText.)

如果我不喜欢这些规则怎么办?

        如果第二条规则让你感到困扰,因为你需要从另一个进程中的自定义控件中获取文本,那么你可以手动发送 WM_GETTEXT 消息。由于你没有使用 GetWindowText(),所以你不受其规则的约束。

        不过,请注意,如果目标窗口卡住了,你的应用程序也会卡住,因为 SendMessage() 会在目标窗口响应之前一直等待。

        还要注意,由于 WM_GETTEXT 在系统消息范围内(0 到 WM_USER-1),你不需要做数据编码转换的工作(实际上,你不应该这么做)。USER(user32.dll ) 会为你做好这些工作。

你能举一个这样的例子吗?

假设有这样一个控件:

SampleWndProc(...)
{case WM_GETTEXT:lstrcpyn((LPTSTR)lParam, "Booga!", (int)wParam);return lstrlen((LPTSTR)lParam);case WM_GETTEXTLENGTH: return 7; // lstrlen("Booga!") + null...
}
现在考虑应用程序 A 执行以下操作:
hwnd = CreateWindow("Sample", "Frappy", ...);

现在考虑进程 B 获取应用程序 A 创建的窗口的句柄(通过任何手段)。

TCHAR szBuf[80];
GetWindowText(hwnd, szBuf, 80);

这将返回 szBuf = "Frappy",因为它是从“特殊的地方”获取窗口文本的。然而,

SendMessage(hwnd, WM_GETTEXT, 80, (LPARAM)szBuf);

将返回 szBuf = "Booga!"

这篇关于翻译 《The Old New Thing》 - The secret life of GetWindowText的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/865903

相关文章

90、k8s之secret+configMap

一、secret配置管理 配置管理: 加密配置:保存密码,token,其他敏感信息的k8s资源 应用配置:我们需要定制化的给应用进行配置,我们需要把定制好的配置文件同步到pod当中容器 1.1、加密配置: secret: [root@master01 ~]# kubectl get secrets ##查看加密配置[root@master01 ~]# kubectl get se

论文翻译:arxiv-2024 Benchmark Data Contamination of Large Language Models: A Survey

Benchmark Data Contamination of Large Language Models: A Survey https://arxiv.org/abs/2406.04244 大规模语言模型的基准数据污染:一项综述 文章目录 大规模语言模型的基准数据污染:一项综述摘要1 引言 摘要 大规模语言模型(LLMs),如GPT-4、Claude-3和Gemini的快

论文翻译:ICLR-2024 PROVING TEST SET CONTAMINATION IN BLACK BOX LANGUAGE MODELS

PROVING TEST SET CONTAMINATION IN BLACK BOX LANGUAGE MODELS https://openreview.net/forum?id=KS8mIvetg2 验证测试集污染在黑盒语言模型中 文章目录 验证测试集污染在黑盒语言模型中摘要1 引言 摘要 大型语言模型是在大量互联网数据上训练的,这引发了人们的担忧和猜测,即它们可能已

java线程深度解析(一)——java new 接口?匿名内部类给你答案

http://blog.csdn.net/daybreak1209/article/details/51305477 一、内部类 1、内部类初识 一般,一个类里主要包含类的方法和属性,但在Java中还提出在类中继续定义类(内部类)的概念。 内部类的定义:类的内部定义类 先来看一个实例 [html]  view plain copy pu

string字符会调用new分配堆内存吗

gcc的string默认大小是32个字节,字符串小于等于15直接保存在栈上,超过之后才会使用new分配。

excel翻译软件有哪些?如何高效提翻译?

你是否曾在面对满屏的英文Excel表格时感到头疼?项目报告、数据分析、财务报表... 当这些重要的信息被语言壁垒阻挡时,效率和理解度都会大打折扣。别担心,只需3分钟,我将带你轻松解锁excel翻译成中文的秘籍。 无论是职场新人还是老手,这一技巧都将是你的得力助手,让你在信息的海洋中畅游无阻。 方法一:使用同声传译王软件 同声传译王是一款专业的翻译软件,它支持多种语言翻译,可以excel

MonoHuman: Animatable Human Neural Field from Monocular Video 翻译

MonoHuman:来自单目视频的可动画人类神经场 摘要。利用自由视图控制来动画化虚拟化身对于诸如虚拟现实和数字娱乐之类的各种应用来说是至关重要的。已有的研究试图利用神经辐射场(NeRF)的表征能力从单目视频中重建人体。最近的工作提出将变形网络移植到NeRF中,以进一步模拟人类神经场的动力学,从而动画化逼真的人类运动。然而,这种流水线要么依赖于姿态相关的表示,要么由于帧无关的优化而缺乏运动一致性

linux dlopen手册翻译

名称 dlclose, dlopen, dlmopen 打开和关闭一个共享对象 简介 #include <dlfcn.h>void *dlopen(const char*filename, int flags);int dlclose(void *handle);#define _GNU_SOURCE#include <dlfcn.h>void *dlmoopen(Lmid_t lm

从计组中从重温C中浮点数表示及C程序翻译过程

目录 移码​编辑  传统浮点表示格式 浮点数的存储(ieee 754)->修炼内功 例子:   ​编辑 浮点数取的过程   C程序翻译过程 移码  传统浮点表示格式 浮点数的存储(ieee 754)->修炼内功 根据国际标准IEEE(电⽓和电⼦⼯程协会)  32位 例子:    64位    IEEE754对有效数字M和

List list = new ArrayList();和ArrayList list=new ArrayList();的区别?

List是一个接口,而ArrayList 是一个类。 ArrayList 继承并实现了List。 List list = new ArrayList();这句创建了一个ArrayList的对象后把上溯到了List。此时它是一个List对象了,有些ArrayList有但是List没有的属性和方法,它就不能再用了。而ArrayList list=new ArrayList();创建一对象则保留了A