在Windows上,如果我的子窗口的z顺序相对于它的一个同胞发生变化,是否会得到一个WM_WINDOWPOSCHANGED?

我正在试图插入一个自定义的小部件到Internet Explorer 8的url栏,停止和重新加载button旁边。 这只是我个人的生产力提升。

IE框架的这个部分的“窗口模型”是一个“地址栏根”窗口,它拥有包含IE8 url栏的窗口:一个编辑框,一个组合控件,以及停止和重载button。

从另一个进程中,我创build了一个新的WS_CHILD窗口(具有一个自定义的类名),这个窗口由IE的地址栏根窗口生成,因此使它成为编辑框的同级并停止/重新加载。 我使用HWND_TOP的hwndInsertAfter调用SetWindowPos,以确保它出现在urlbar的“上方”(即“in”)。 这很好地工作,我看到我的窗口最初绘在IE的urlbar。

但是,当我激活IE窗口时,urlbar编辑控件跳回到我的窗口前面。 我知道这是因为我仍然看到我的窗口绘制在urlbar后面,并且因为当我打印 – > GetTopWindow()到计时器上的debugging控制台时,它将成为urlbar编辑控件的HWND。

如果我更新我的消息循环以WM_PAINT HWND_TOP调用SetWindowPos,事情会更好 – 现在当我激活IE窗口并移动它,我的控制适当地停留在urlbar的编辑控制上方。 但是,只要我切换IE浏览器的标签,这将更新IE浏览器的urlbar编辑控件的文本之间切换,我的控制权移回编辑控件后面。 (注意:当我最大化或恢复窗口时也会发生这种情况。)

所以我的问题是:

1)IE浏览器是否有意将其urlbar编辑控件重新放在z顺序的顶部,每当您点击IE中的一个标签时,或者我在理解Windows绘画和z顺序的工作方式时是否存在差距? 我的理解是,一旦你指定了子窗口的 z顺序(最终用户不能操作),那么顺序应该保持到编程改变为止。 所以,即使IE正在重新制作其选项卡select的编辑控件,而我不重新粉刷或以其他方式作用于我的窗口,我的窗口应该仍然坚持顶部。

2)鉴于我的窗口的Z顺序明显改变,不应该得到一个WM_WINDOWPOSCHANGING / WM_WINDOWPOSCHANGED? 如果是这样,我至less可以回应这个事件,并保持在Edit控件之上。 但即使当我点击一个标签时,即使我的debugging窗口输出确认地址栏的根的GetTopWindow()成为编辑控件的HWND,当我点击一个标签时,即使我看到WM_WINDOWPOSCHANGING / WM_WINDOWPOSCHANGED被发送到HWND_TOP的HWND_TOP的hwndInsertAfter编辑控件,当我点击一个选项卡时,我自己的窗口不会收到任何消息,将允许我保持z顺序不变。 这对我来说似乎是错误的,解决它会迫使我在IE浏览器的进程中运行,并挂接所有发送到其编辑控件的消息只是为了让事件响应:(

感谢您的帮助!

  1. 当你改变标签的时候,IE浏览器很有可能在控制Z的顺序。 在IE9中,URL栏和标签有一个共同的父项。 当你选择一个新的选项卡时,它会激活URL栏(激活通常会把窗口置于本地Z命令的顶部)。

  2. 不,你得到WM_WINDOWPOSCHANGED当一个SetWindowPos函数作用于你的窗口。 如果某些兄弟姐妹的z-次序改变了,你就不会收到消息。 没有人在窗口上调用SetWindowPos。 你可以通过编写一个测试程序来看到这个问题,这个程序可以处理一些子窗口的z顺序。

这是有道理的,因为可能会有任意数量的兄弟窗口,并且通知所有这些窗口可能是无限的开销。 要想把这些信息传递给所有的兄弟姐妹,给出一些兄弟姐妹可以通过进一步洗牌z顺序来作出反应,也几乎是不可能的。 尚未收到第一个通知的兄弟姐妹现在是否有两个待处理的通知? 他们是否立即发布或发布? 如果队列增长并且增长,直到它溢出呢?

这与WM_KILLFOCUS / WM_SETFOCUS通知不同,它至多影响两个窗口。 这对通知的数量有合理的限制。 即使有失控的无限循环,因为丢失的控件试图窃取焦点,队列也不会溢出,因为每个WM_KILLFOCUS只有一个SetFocus调用被传递。

另外,Windows可能需要对失去焦点做出反应是合理的。 窗口C需要知道B现在位于A之上而不是相反,所以为什么设计系统发送了10个不必要的消息?

对你不能控制的应用程序的UI进行黑客攻击,并且没有明确定义的API来完成你想要做的事情类型,这是从难到不可能的,而且总是很脆弱。 推出工具栏和浏览器定制的团队会雇用比您期望的更多的人,而他们大部分时间都在用Spy ++进行探索并进行实验。 这本质上是黑客攻击。