不同类型的 OS 中断处理程序必须将消息放入所述“消息队列”中,但是该队列驻留在进程地址空间的哪个位置?它是如何暴露给中断处理程序代码的?
窗口与线程相关联。每个具有窗口的线程在进程的地址空间中都有一个线程队列。操作系统在其自己的地址空间中有一个用于硬件生成事件的内部队列。使用事件的详细信息和其他状态信息(例如,哪个窗口具有焦点),操作系统将硬件事件转换为消息,然后将这些消息放置在适当的线程队列中。
发布的消息直接放置在目标窗口的线程队列中。
发送的消息通常直接处理(绕过队列)。
细节变得毛茸茸的。例如,线程队列不仅仅是消息列表——它们还维护一些状态信息。一些消息(如 WM_PAINT)并没有真正排队,而是在您查询队列并且它是空的时从附加状态信息合成。发送到其他线程拥有的窗口的消息实际上是发布到接收者的队列而不是直接处理,但是从调用者的角度来看,系统使它看起来像一个常规的阻塞发送。如果这会导致死锁(因为循环发送回原始线程),就会引起欢闹。
Jeffrey Richter 的书有很多(全部?)血腥细节。我的版本是旧的(高级 Windows)。当前版本似乎通过 C/C++ 称为 Windows。
操作系统做了很多工作来使消息流在调用者看来是合理的(并且相对简单)。
“翻译”信息是什么意思?调用 TranslateMessage() 的真正作用是什么?
它监视虚拟按键消息,当它识别出按键/按键组合时,它会添加字符消息。如果您不调用TranslateMessage,您将不会收到 WM_CHAR 之类的字符消息。
我怀疑它在返回之前直接发送字符消息(而不是发布它们)。我从未检查过,但我似乎记得 WM_CHAR 消息在 WM_KEYUP 之前到达。
一旦被 DispatchMessage() 发送,消息在到达我的 WndProc 之前会经过哪些地方(即操作系统如何处理它)?
DispatchMessage 将消息传递给目标窗口的 WndProc。一路上,它的一些钩子可能有机会看到消息(并可能干扰它)。