蓝色:十分十分业余的翻译
红色:专业翻译
The secret life of GetWindowText
GetWindowText
的秘密生活
GetWindowText
的秘密
GetWindowText() is more complicated than you think. The documentation tries to explain its complexity with small words, which is great if you don't understand long words, but it also means that you're not getting the full story.
GetWindowText()
比你想象中的还在复杂.
相关的文档尝试用少量的词解释它的复杂性,这比用大量你不懂的词要好得多,
GetWindowText()
函数远比你想象中的要复杂.在GetWindowText函数帮助文档中试图通过简短的文字来解释这个函数的复杂性,如果你无法理解一些长篇大论的文字,那么这种做法无疑是很好的,但简短的文字同样意味着整个内容会变得晦涩难懂。
Here's an attempt to give the full story.
这里尝试介绍事情的始末
下面,我们就来讲述 GetWindowText函数的完整内容。
How windows manage their text
Window
如何管理它们的文字
窗体如何来管理文本
There are two ways window classes can manage their text.
They can either do it manually or they can let the system do it. The default is to let the system do it.
窗体类管理它们的文字有两种方法.它们不是通过手工或系统来管理.默认是通过系统来管理
在窗口类中可以通过两种方法来管理文本:即可以让窗口自己管理,也可以让系统进行管理,默认的情况是由系统进行管理。
If a window class lets the system manage its text, the system will do the following:
如果一个 窗体类让系统管理它的文字,系统将做以下这些:
如果窗口类让系统来管理文本,那么系统会进行以下的这些工作:
-
Default handling of the WM_NCCREATE message takes the lpWindowName parameter passed to CreateWindow/Ex and saves it in a "special place".
WM_NCCREATE
消息的默认处理函数将lpWindowName 参数传给 CreateWindow/Ex 并且将它保存在 “特殊的地方”
对WM_NCCREATE消息进行默认的处理:将传递给CreateWindow/Ex 函数的参数 lpWindowName提出出来, 并将这个字符串保存在某个“特殊位置”
-
Default handling of the WM_GETTEXT message retrieves the string from that "special place".
WM_GETTEXT
默认的处理函数从“特殊的地方”获取字符串
对WM_GETTEXT消息进行默认的处理:从“特殊的位置”上提取字符串
-
Default handling of the WM_SETTEXT message copies the string to that "special place".
WM_SETTEXT
消息的默认处理函数复制字符串到“特殊的地方”
对WM_SETTEXT消息进行默认的处理:从字符串复制到“特殊的位置”
On the other hand, if a window class manages its window text manually, the system will not do any special handling, and it is the window class's responsibility to respond to the WM_GETTEXT/WM_SETTEXT messages and return/save the strings explicitly.
另一方面, 如果一个 窗体类手工管理它的窗体文本,系统将不会做任何特殊处理,(不懂翻译)
另一方面,如果是由窗体类自己来管理窗体的文本,那么系统将不会做任何特殊处理,而是由窗体类来负责响应WM_GETTEXT/WM_SETTEXT消息,并且直接返回/保存字符串。
Frame windows typically let the system manage their window text. Custom controls typically manage their window text manually.
框架窗体通常让系统管理它们的窗体文本。自定义控件通常手动管理它们的窗体文本
框加窗口(Frame Windows)通常由系统来管理窗口中的文本,而自定义控制通常由它们自己来管理窗口中的文本
GetWindowText
GetWindowText has a problem: Window text needs to be readily available without hanging. FindWindow() needs to get window text in order to find a window. Task-switching applications need to get window text so they can display the window title in the switcher window. It should not be possible for a hung application to clog up other applications. This is particularly true of the task switcher scenario.
GetWindowText
存在一个问题:窗体文本需要不会被挂住随时都可以获取.
在GetWindowText函数中有一个问题:函数需要迅束地得到窗体文本并且不会被挂起。
FindWindow()
需要通过获取窗体文本来找到一个窗体
FindWindow
函数需要通过窗口文本来查找窗口
任务切换的各个应用程序 需要获取窗体文本,因为它们要显示被切换的窗体文本
而任务切换程序也需要获取窗口文本,以便在切换器窗口中显示窗体的标题
不能因为一个阻塞的应用程序阻碍到其它的应用程序.特别是在任务切换的情况下.
某个挂起的程序阻塞其它应用程序的情况是不应该发生的,这就是任务切换程序所要面对的实际情况.
This argues against sending WM_GETTEXT messages
, because the target window of the WM_GETTEXT might be hung. Instead, GetWindowText should use the "special place" since that cannot be affected by hung applications.
在发送 WM_GETTEXT消息的情况下有争议,因为目标窗体的 WM_GETEXT可能被阻塞住. 或者,GetWindowText 能使用“特殊的地方”而不受阻塞着的应用程序的影响.
这就要求不应该发送WM_GETTEXT消息,因为WM_GETTEXT的目标窗口可能被挂起。此时,GetWindowText应该从“特殊位置”上获取文本,因为这种做法不会受挂起程序的影响。
On the other hand, GetWindowText is used to retrieve text from controls on a dialog, and those controls frequently employ custom text management. This argues for sending WM_GETTEXT messages, because that is the only way to retrieve custom-managed text.
另一方面,GetWindowText 习惯于从对话框的控制中获取文本.而且这些控件通常采用自己的文本管理.
另一方面,GetWindowText也用于从对应框的控制中提取文本,而这些控件通常使用的是自定义的文本管理机制。
发送WM_GETTEXT消息的争议,因为那是唯一获取自定义管理文本的途径
因此,这又要求应该发送WM_GETTEXT消息,因为这是获取自定义管理文本的唯一方法
So GetWindowText strikes a compromise.
所以 GetWindowText采用折衷方案
于是,在 GetWindowText 函数中采取了一种折中的方法
-
If you are trying to GetWindowText() from a window in your own process, then GetWindowText() will send the WM_GETTEXT message.
-
If you are trying to GetWindowText() from a window in another process, then GetWindowText() will use the string from the "special place" and not send a message.
如果你尝试从一个你自已的进程的窗体 GetWindowText() ,那么 GetWindowsText() 将发送一个 WM_GETTEXT 消息
如果是同一进程的窗口中得到窗口文本,那么GetWindowText() 将发送 WM_GETTEXT 消息
如果你尝从其它进程的窗体 GetWindowsText(), 那么GetWindowText将从”特殊地方”使用字符串,而不会发送消息
如果是从另外一个进程中的窗体中得到窗口文本,那么GetWindowText将会在“特殊位置”上获取字符串,而不是发送消息
According to the first rule, if you are trying to get text from a window in your own process, and the window is hung, then GetWindowText() will also hang. But since the window belongs to your process, it's your own fault and you deserve to lose. Sending the WM_GETTEXT message ensures that text from windows that do custom text management (typically, custom controls) are properly retrieved.
根据第一条规则,如果你在自己的进程中尝试从窗体获取文件,那么窗体将阻塞,然而 GetWindowText() 也将阻塞. (不懂翻译).发送WM_TEXT消息保证窗体的文本执行自定义的文本管理(通常是自定义控件)将适当地恢复
根据第一条规则,如果你想要获取自己进程中的窗口文本,而这个窗口被挂起了,那么 GetWindowText 也会被挂起,不过因为这个窗体属于你的进程,所以函数挂起是你自己犯的错误,并且你应该为此负责。发送WM_GETTEXT消息将确保我们能够正确地得到那么使用自定义文本管理方式的文本
According to the second rule, if you are trying to get text from a window in another process, then GetWindowText() will not send a message; it will just retrieve the string from the "special place". Since the most common reason for getting text from a window in another process is to get the title of the frame, and since frame windows typically do not do custom window text manipulation, this usually gets the right string.
根据第二条规则, 如果你尝试从其它进程获取窗体文本, GetWindowText() 就不会发送消息; 它只是从“特殊的地方”取回字符串.从另一进程获取文本很多情况下是从框架获取标题,(不懂翻译)
根据第二条规则,如果想要获得另一进程中的窗口文本,那么 GetWindowText() 将不会发送消息,而只是从“特殊位置”上获取字符串,通常使用最多的方式是获取另一个进程的框架窗口文本,而在框架窗体中一般不会使用自定义的窗口文本管理方式,因此往往能够获取到正确的字符串。
The documentation simplifies this as "GetWindowText() cannot retrieve text from a window from another application."
文档简单的认为 GetWindowText 不能从另一应用程序获取文本
而在GetWindowText的帮助文档中将上述内容简化为“GetWindowText无法从另一应用程序窗口中得到文本”
What if I don't like these rules?
(
不懂翻译)
如果不喜欢这些规则,该怎么办?
If the second rule bothers you because you need to get text from a custom control in another process, then you can send the WM_GETTEXT message manually. Since you are not using GetWindowText(), you are not subject to its rules.
如果第二条规则让你感到很烦,因为你需要从其它进程的自定义控制获取文本.
然而你可以手工发送 WM_GETTEXT 消息,因为你不调用 GetWindowText() ,所以你不需要受它的规则约束。
如果你不喜欢第二条规则,例如希望得到另一进程中自定义控件的文本,那么可以自己发送WM_GETTEXT消息。此时,由于没有使用 GetWindowText() 函数,因此就不受这条规则的约束。
Note, however, that if the target window is hung, your application will also hang since SendMessage() will not return until the target window responds.
注:然后,如果目标窗体阻塞,你的应用程序从调用 SendMessage() 开始也会阻塞不会返回,直到目标窗体响应。
注意:如果目录窗口被挂起,那么你的应用程序将同样被挂起,因为SendMessage函数只有当目标窗体处理完这条消息时才会返回
Note also that since WM_GETTEXT is in the system message range (0 to WM_USER-1), you do not need to do any parameter marshalling (and in fact, you shouldn't). USER will do the marshalling for you.
同样需要注意的是,因为 WM_GETTEXT 是在系统消息范围之内,因此像把当前进程的缓冲区传送到目标进程以及从目标进程将结果字符串返回到当前进程中等这些操作(这个过程也被称为列集(marshalling)),就不需要你自己进行特殊的处理。事实上,无认你采取什么样的特殊处理,最终都是错误的,窗体管理器将自动将为你完成列集操作。
Can you give an example where this makes a difference?
你能否给出一个说明这种差异的示例?
Consider this control:
考虑下面这个控件
SampleWndProc(...)
{
case WM_GETTEXT:
lstrcpyn((LPTSTR)lParam, "Booga!", (int)wParam);
return lstrlen((LPTSTR)lParam);
case WM_GETTEXTLENGTH: return 7; // lstrlen("Booga!") + null
...
}
在应用程序A,我们进行了以下操作
Now consider application A that does
hwnd = CreateWindow("Sample", "Frappy", ...);
在应用程序B,这个进程得到应用程序A的窗体句柄
Now consider process B that gets the handle to the window created by application A (by whatever means).
TCHAR szBuf[80];
GetWindowText(hwnd, szBuf, 80);
上面这段代码将会返回 szbuf=”Frappy”,因为这是从“特殊位置”上获得窗口文本,然面,下面的代码
This will return szBuf = "Frappy" because it is getting the window text from the "special place". However,
SendMessage(hwnd, WM_GETTEXT, 80, (LPARAM)szBuf);
将返回szBuf = "Booga!"
will return szBuf = "Booga!"
Published Thursday, August 21, 2003 9:30 AM by oldnewthing
Filed under: Code