我试图将自定义窗口小部件插入Internet Explorer 8网址栏中的“停止”和“重新加载”按钮旁边。这只是我个人的生产力提高者。
IE框架此部分的“窗口模型”是“地址栏根”窗口,该窗口拥有包含IE8网址栏的窗口:编辑框,组合控件以及停止和重新加载按钮。
在另一个过程中,我创建了一个新的WS_CHILD窗口(具有自定义类名),该窗口由IE的地址栏根窗口作为父窗口,从而使其成为编辑框和停止/重新加载的同级窗口。我用HWND_TOP的hwndInsertAfter调用SetWindowPos,以确保它显示在网址栏的“上方”(即“在”中)。效果很好,我看到窗口最初是在IE网址栏中绘制的。
但是,当我激活IE窗口时,网址栏编辑控件会跳回到窗口的前面。我知道这种情况的发生是因为我仍然看到我的窗口被绘制在URLbar的后面,并且因为当我在计时器上打印-> GetTopWindow()到调试控制台时,它成为URLBar编辑控件的HWND。
如果我更新消息循环以在WM_PAINT上使用HWND_TOP调用SetWindowPos,情况会更好-现在,当我激活IE窗口并四处移动时,我的控件将正确地放置在网址栏中的编辑控件上方。但是,一旦我在IE选项卡之间进行切换(更新IE的网址栏Edit控件的文本),我的控件就会移回到Edit控件后面。 (注意:当我最大化或还原窗口时,也会发生这种情况。)
所以我的问题是:
1)每次您单击IE中的选项卡时,IE可能有意将urlbar编辑控件放回到z顺序的顶部,还是我对Windows绘画和z顺序的工作方式有了解?我的理解是,一旦您指定了子窗口的z顺序(最终用户无法操作),该顺序应保持不变,直到以编程方式进行更改为止。因此,即使IE在选择选项卡时正在重新绘制其Edit控件,而我并未在窗口上重新绘制或以其他方式作用,我的窗口仍应牢固地保持在顶部。
2)鉴于我的窗口的z顺序显然在变化,它不应该收到WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED吗?如果是这样,我至少可以响应该事件并使自己保持在Edit控件的顶部。但是,即使当我单击选项卡时我可以看到我的窗口在urlbar Edit控件后面绘画,并且即使我的调试窗口输出确认了当我单击选项卡时地址栏根目录的GetTopWindow()成为Edit控件的HWND ,尽管当我单击选项卡时,我看到WM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED通过HWND_TOP的hwndInsertAfter发送到Edit控件时,我自己的窗口也没有收到任何使我保持z顺序恒定的消息。这对我来说似乎是错误的,解决该问题将迫使我在IE的进程中运行,并钩住所有发送到其Edit控件的消息,只是为了使事件响应:(
谢谢您的帮助!
最佳答案
这是有道理的,因为可能有任意数量的同级窗口,并且通知所有同级窗口可能会有无数的开销。考虑到某些 sibling 可以通过进一步改组z阶来使用react,几乎不可能想出一套一致的规则来将这些消息传递给所有 sibling 。尚未收到第一个通知的 sibling 现在有两个待处理的通知吗?他们会立即发布或 dispatch 吗?如果队列不断增长直到溢出,该怎么办?
这与WM_KILLFOCUS/WM_SETFOCUS通知不同,因为它最多影响两个窗口。这对通知的数量设置了合理的界限。即使由于失控试图抢回焦点而导致失控的无限循环,该队列也不会溢出,因为每个交付的WM_KILLFOCUS都只有一个SetFocus调用。
同样,窗口可能需要对失去焦点使用react是合理的。窗口C需要知道B现在位于A之上而不是相反的可能性要小得多,那么为什么将系统设计为发送数十亿不必要的消息呢?
破解您无法控制的应用程序的UI,这些应用程序没有定义良好的API来执行您想做的事情,这是困难的,甚至是不可能的,而且总是脆弱的。推出工具栏和浏览器自定义设置的小组雇用的人员比您预期的要多,他们整天都在使用Spy++进行探索和试验。它是天生的黑客行为。
关于windows - 在Windows上,当其子顺序相对于其同级之一改变时,我的子窗口是否应该获得WM_WINDOWPOSCHANGED?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6348743/