像Photoshop CS一样管理Window Z顺序
因此,我有一个应用程序,其窗口行为我想表现得更像Photoshop CS。在Photoshop CS中,文档窗口始终位于工具窗口后面,但仍是顶级窗口。对于MDI子窗口,由于文档窗口实际上是子窗口,因此我们不能将其移到主窗口之外。但是,在CS中,我们可以将图像移到其他监视器上,相对于Visual Studio等停靠应用程序和常规MDI应用程序而言,这是一个很大的优势。
无论如何,这是我到目前为止的研究。我试图拦截WM_MOUSEACTIVATE消息,并使用DeferWindowPos命令对窗口进行自己的排序,然后返回MA_NOACTIVATEANDEAT,但这导致窗口无法正确激活,我相信还有其他一些命令可以"激活"一个没有调用WM_MOUSEACTIVATE的窗口(例如,我认为是SetFocus()),因此该方法可能仍然无法正常工作。
我相信Windows"激活"窗口的过程是
1.使用WM_NCACTIVATE和WM_ACTIVATE消息通知未激活的窗口
2.将窗口移至z顺序的顶部(发送WM_POSCHANGING,WM_POSCHANGED并重新绘制消息)
3.使用WM_NCACTIVATE和WM_ACTIVATE消息通知新激活的窗口。
似乎最干净的方法是拦截第一个WM_ACTIVATE消息,并以某种方式通知Windows我们将覆盖其执行z排序的方法,然后使用DeferWindowPos命令,但我无法确定知道怎么做。 Windows似乎一旦发送了WM_ACTIVATE消息,就已经准备好以自己的方式进行重新排序,因此,我使用的所有DeferWindowPos命令都将被覆盖。
现在,我有一个基本的实现准工作方式,当应用程序被激活时,它使工具窗口位于最顶层,而当工具窗口未被激活时,则使其变为非顶层,但这非常古怪(有时会像其他窗口一样位于其他窗口之上)。任务管理器,而Photoshop CS不会执行此操作,因此我认为Photoshop会以某种方式做不同的事情),而且似乎会出现一种更直观的方法。
无论如何,有人知道Photoshop CS是如何做到的,还是比使用toptop更好的方法?
解决方案
我想他们会因为他们没有使用.NET而在存在的许多年里滚动了自己的窗口代码,而现在,就像Amazon最初的OBIDOS一样,对他们的产品进行了定制(现成的( aka .NET的MDI支持)将不会接近。
我不喜欢没有真实答案的答案,但是如果像Photoshop那样的东西确实是目标,那么我们可能必须花费大量的时间和精力来获得相似的东西。值得我们花时间吗?请记住,许多年来,许多程序员和版本已经聚在一起,以使Photoshop的简单化窗口行为能够正确工作并让我们感觉自然。
看来我们已经必须深入研究Win32 API函数和值才能瞥见"解决方案",这应该是第一个危险信号。最终有可能吗?大概。但是取决于需求和时间以及我们只能决定的许多其他因素,这可能不切实际。
如果不熟悉Photoshop CS,则很难确切知道我们要实现的外观。
但是我想过,如果我们在创建工具窗口时创建了无模式对话框窗口,并确保它具有WS_POPUP样式,那么生成的工具窗口将不会被剪切到主父窗口,并且Windows将自动管理z-Order以确保工具窗口位于父窗口的顶部。
并且由于工具窗口对话框是无模式的,因此不会干扰主窗口。
像Photoshop CS一样管理Window Z顺序
我们应该以图像为父级创建工具窗口,以便Windows管理zorder。无需设置WS_POPUP或者WS_EX_TOOLWINDOW。这些标志仅控制窗口的呈现。
以图像窗口的窗口作为父窗口调用CreateWindowEx。
我没有看到关于Photoshop CS的任何引人注目的东西,这些东西要求接近这种黑客攻击水平的任何事情,而不能仅仅通过在创建窗口时指定正确的所有者窗口关系来完成。例如,如果我们有多个文档窗口,则必须在其他窗口上方显示的任何窗口都将其指定为该窗口的所有者,如果我们有多个文档窗口,则每个窗口都有其自己的一组子窗口,我们可以随着文档窗口的增加而动态地显示和隐藏它们。失去激活。
答复克里斯和伊曼纽尔,使用所有者窗口功能的问题是,一个窗口只能由另一个窗口拥有,而我们不能更改谁拥有一个窗口。因此,如果工具窗口A和B始终需要位于文档窗口C和D的顶部,那么当文档窗口C处于活动状态时,我希望它拥有窗口A和B,以便A和B始终位于其顶部。但是,当我激活文档窗口D时,我将不得不将工具窗口A和B的所有权更改为D,否则它们将落在窗口D的后面(因为它们由窗口C拥有)。但是,Windows不允许我们更改窗口的所有权,因此该选项不可用。
目前,我已经将其与最重要的功能配合使用,但这充其量只是一个技巧。我确实感到安慰,因为GIMP尝试使用2.6版来模仿Photoshop,但是即使是其实现有时也会表现出古怪,这使我相信它们的实现也是一种hack。
我们是否尝试过在主窗口获得焦点时将工具窗口置于最高位置,而在失去焦点时使工具窗口置于非最高位置?听起来我们已经开始研究这种解决方案了……但是要更加详细。
需要注意的是,似乎很有据可查的是,在进行z排序时,工具窗口表现出意外的行为。我还没有在MSDN上找到任何可以确认的信息,但是可能是Windows专门对其进行了管理。