问题标签 [layered-windows]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
2304 浏览

windows - 在 UpdateLayeredWindow 调用之后,分层窗口仍然收到 WM_PAINT 消息

我的应用程序中有几个分层窗口UpdateLayeredWindow()用于处理它们的视觉表示。根据MSDN 关于分层窗口的文章,“在使用UpdateLayeredWindow()应用程序时不需要响应WM_PAINT或其他绘画消息。” 他们共享一些与非分层窗口相同的消息处理程序,所以我想WM_PAINT如果目标是分层窗口,我会提前从处理中返回。

当然,这导致了一个主要问题:如果其中一个分层窗口确实收到了一条WM_PAINT消息,那么输入队列最终会被无穷无尽的WM_PAINT消息流淹没。这个最终结果是有道理的,因为窗口永远不会被验证,所以它会一直认为它需要绘制(我不应该在没有验证或BeginPaint()ing 等的情况下从处理程序返回),但是什么没有意义这就是它首先收到消息的原因,因为它对正在使用的窗口没有影响UpdateLayeredWindow()

它甚至不会可靠地发生——只是偶尔,而不是每次窗口的像素需要重绘。DefWindowProc()回退到分层窗口收到消息时恢复了理智WM_PAINT,但我觉得发生了一些我不明白的事情。考虑到这个问题很少出现,我担心这可能只是隐藏了一个更微妙的问题。UpdateLayeredWindow()使用仍会偶尔收到消息的窗口是否是预期的行为WM_PAINT?只要我处理得当,这有关系吗?

附加信息,如果需要:窗口UpdateLayeredWindow()在创建后立即调用,然后它自己留下(它不会再次调用它,因为它不会改变)。使用 C++ 和 win32 API,没有 MFC。

0 投票
1 回答
841 浏览

c# - Window Sitters - 分层窗口颜色键控和点击

几年前,我在 Visual Basic 6 中制作了一个窗口保姆,它使用分层窗口颜色键控来轻松地使表单非矩形。

本周早些时候,我尝试用 C# 重写 window sitter,判断旧代码一团糟,并注意到表单客户端矩形内的任何点击都被表单捕获,而 VB6 版本的点击下降到下面的任何内容 if您没有在任何可见部分内单击。这当然是一件非常重要的事情。

手动调用分层 Windows API (VB6) 和我不知道的 TransparancyKey 属性 (.Net) 之间是否有一些区别,或者这里还有更多?

0 投票
2 回答
1903 浏览

wpf - 在 Windows 上绘制叠加图形的最佳方法是什么?

我正在使用需要创建各种自定义窗口类型的 Win32 应用程序。特别是,这些窗口通常是非矩形的,有阴影,或者大部分是透明的。

我目前正在使用WS_EX_LAYEREDwithUpdateLayeredWindow创建透明窗口,然后可以在其上绘制任意图形。但是,我发现分层窗口受到限制,因为您不能有分层的子窗口,分层窗口也不能正确承载“普通”Win32 控件。

我们的代码库已有数年历史,主要使用 Win32 和 GDI,但我们正在对事物进行现代化改造,是时候研究更新的技术了。

我考虑过在 WPF 中进行自定义窗口化,但我担心我所读到的有关“空域”问题的内容。似乎 WPF 使用分层窗口来完成其每像素 alpha 混合,因此它似乎也会受到我以前经历过的限制的影响。

我对 Direct2D 知之甚少(真的一无所知),但该技术听起来可能很有趣。虽然,我找不到任何关于它能够做覆盖窗口的参考。

所以,所有这些都让我想到了我的问题:在 Windows 下做覆盖窗口的最佳技术是什么?(Vista 和 Win7 至少,XP 会很高兴)

我是否忽略了一些特别好的技术?任何建议,将不胜感激。

0 投票
0 回答
261 浏览

com - 分层窗口和 COM 拖动图像

我有一个程序,它显示一个主窗口、一个分层窗口并实现 COM 拖放。笼统:

  1. 我创建了一个普通的顶级窗口。
  2. 我使用 WS_EX_LAYERED 和 UpdateLayeredWindow/SetLayeredWindowAttributes 创建了一个分层窗口(我都试过了)。分层窗口位于 1 中创建的窗口之上。分层窗口不是子窗口。
  3. 然后我通过 COM DoDragDrop 函数开始拖放。在 IDropSource::QueryContinueDrag 中,我调用 ImageList_BeginDrag、ImageList_DragMove 等。

问题是,COM 显示的拖动图像(它是图像列表中的图像)显示在分层窗口下方而不是在其顶部。光标显示在分层窗口的顶部(如预期的那样)。从下到上,我得到的分层是:

  • 主窗口(底部)
  • COM拖动图像
  • 分层窗口
  • 光标(上)

它应该是:

  • 主窗口(底部)
  • 分层窗口
  • COM拖动图像
  • 光标(上)

我已经应用了 KB943326“重叠的分层窗口在 Windows Server 2003 或 Windows XP 中没有以正确的顺序显示”(“ http://support.microsoft.com/kb/943326 ”),但没有区别。

我正在运行 XP SP2。

任何建议表示赞赏,因为我已经没有想法了......

谢谢,苏绿

0 投票
3 回答
8960 浏览

winapi - Win32:如何使阴影尊重非矩形分层窗口?

我通过添加WS_EX_LAYERED扩展样式创建了一个分层窗口:

Windows 将使用黑色作为色度键颜色值。我将留下一个黑色的大边框以使问题变得明显:

替代文字


构建窗口后,我告诉它使用黑色作为色度键颜色

现在弹出的分层窗口显示为部分透明:

替代文字


问题是最后一步。我想使用自 Windows XP 以来可用的CS_DROPSHADOW类样式来创建投影:

出现了投影,但是阴影包围了原来的矩形窗口,并且没有考虑到分层窗口提供的窗口透明度:

有谁知道我在某个地方错过了什么神奇的选项,可以让投影尊重非矩形分层窗口?


出现此问题的另一个示例是当您不包含 6px 填充/边距时。Windows® 主题绘制的提示窗口是非矩形的。这会在窗口透明的地方留下一个小的可见间隙,但不会出现投影:

替代文字

正如您从 Internet Explorer 的提示中看到的那样,Microsoft 已设法使其工作:

替代文字


仔细查看 Windowstooltips类提示窗口。使用SpyXX - 我可以获得它的窗口矩形和类样式:

SpyXX 说:

所以一切都指向窗口本身是 104x20 像素,在窗口本身之外有阴影。(这与 一致CS_DROPSHADOW。)

接下来我可以查看tooltips窗口类的样式:

有趣的是,它不使用CS_SAVEBITS( 0x800); 这对于小型、短暂的窗口很有用。

它也不使用CS_DROPSHADOW( 0x20000)。所以现在我想知道它是如何在自己的窗口之外绘制的?

注意:透明分层窗口被记录为区域的首选技术。

编辑: Windows 2000 出现了分层 Windows。CS_DropShadow 是随 XP 添加的。

0 投票
3 回答
5069 浏览

windows - 如何在窗外画画?

查看 Windows类提示窗口,我看到它在提示窗口的实际矩形之外tooltips绘制了阴影。

使用SpyXX - 我可以获得工具提示的窗口矩形和类样式:

您会注意到您看到的投影实际上位于正在绘制的窗口之外。我怎样才能在窗外画一个阴影,同时在窗外

注意阴影不是使用标准CS_DROPSHADOW类样式绘制的。我已经通过实验证实了这一点,并且还可以在SpyXX中查看窗口的类样式;它不使用CS_DROPSHADOW

那么我怎样才能在窗外画画呢?

注意:尝试在桌面上绘制 DC 已失效。来自 Greg Schechter 的重定向 GDI、DirectX 和 WPF 应用程序

在屏幕上绘图和读取 - Baaaad!

最后,由于我们在重定向主题,一个特别危险的做法是写入屏幕,或者通过使用 GetDC(NULL) 并写入,或者尝试做 XOR 橡皮筋线等。有两个写入屏幕不好的主要原因:

它很昂贵……写入屏幕本身并不昂贵,但它几乎总是伴随着从屏幕读取,因为在写入屏幕时通常会执行诸如 XOR 之类的读取-修改-写入操作。从显存表面读取非常昂贵,需要与 DWM 同步,并且会停止整个 GPU 管道以及 DWM 应用程序管道。
这是不可预测的……如果您以某种方式设法到达实际的主节点并对其进行写入,则无法预测您写入主节点的内容将在屏幕上保留多长时间。由于UCE不知道,它可能会在下一帧刷新时被清除,也可能会持续很长时间,这取决于屏幕上还需要更新什么。(无论如何,我们确实不允许直接写入主节点,正因为如此......如果您尝试访问 DirectDraw 主节点,例如,DWM 将关闭,直到访问应用程序退出)

0 投票
1 回答
1062 浏览

c++ - 在分层窗口上调用 InvalidateRect 后在 OnPaint 中获取空的更新矩形

我试图弄清楚为什么当我在透明窗口上调用 InvalidateRect 时得到一个空的更新矩形。这个想法是我在窗口上绘制了一些东西(它被临时切换为绘图的 alpha 为 1/255),然后我将其切换到完全透明模式(即 alpha 为 0)以便与桌面&能够在桌面顶部的屏幕上移动绘图。

当我尝试移动绘图时,我得到了它的边界矩形并使用它来调用 InvalidateRect,如下所示:

InvalidateRect(m_hTarget, &winRect, FALSE);

我已经确认 winRect 确实是正确的,并且 m_hTarget 是正确的窗口并且它的矩形完全包含 winRect。

我进入与 m_hTarget 对应的类中的 OnPaint 处理程序,该处理程序派生自 CWnd。在那里,我创建了一个 CPaintDC,但是当我尝试访问更新矩形 (dcPaint.m_ps.rcPaint) 时,它始终是空的。这个矩形被传递给一个函数,该函数确定我们是否需要更新屏幕(在透明窗口的情况下使用 UpdateLayeredWindow)。

如果我在这里硬编码一个非空矩形,其余代码可以正常工作并且我可以在屏幕上移动绘图。

我尝试在 InvalidateRect 中将“FALSE”参数更改为“TRUE”,但没有任何效果。我还尝试使用标准 CDC,然后在我的 OnPaint 处理程序中使用 BeginPaint/EndPaint 方法,以确保 CPaintDC 没有做奇怪的事情……但我得到了相同的结果。

我使用的代码最初是为不透明的窗口设计的。如果 m_hTarget 对应于一个不透明的窗口,则同一组函数调用会导致将正确(即非空)矩形传递给 OnPaint。但是,一旦窗口分层,它似乎就不能正常工作。

0 投票
1 回答
1888 浏览

c++ - 始终保持窗口位于顶部——包括菜单 (win32)

我希望有一个始终位于顶部的分层窗口,我可以完成,但仍有某些屏幕元素仍会在其上绘制,例如菜单(包括开始菜单)。

有什么方法可以使我的应用程序的窗口或子窗口具有足够高的 top-ness 属性,以便在另一个应用程序的菜单上绘制?或者是否有一些内置的东西可以确保当前活动应用程序中的菜单始终绘制在顶部?

事实上,我不太了解菜单的工作原理。因此,试图让我的窗口“像菜单一样”以期让它涵盖更多内容,这对我来说甚至可能没有任何意义。

0 投票
1 回答
751 浏览

delphi - 分层窗口的系统菜单?

Delphi 2009 中的分层窗口和系统菜单存在问题。也就是说,我们的分层窗口(没有边框)没有系统菜单。当我说系统菜单时,我指的是单击应用程序图标时获得的菜单,右键单击其标题栏或(在 Windows 7 中,添加 shift 键)右键单击任务栏中的应用程序:

控制菜单

当您尝试访问系统菜单时,例如通过右键单击此类分层窗口的任务栏图标,分层窗口会升起。为什么是这样?是否有某种样式要设置,或者某种事件要处理?

这是一个匆忙制作的演示,展示了这个问题。不过,它确实可以用任何带有 bsNone 边框样式的形式复制。

http://ompldr.org/vODd5dw

0 投票
2 回答
530 浏览

winapi - Windows 中的换肤引擎:只绘制“脏”区域还是一次绘制整个窗口?

我想制作一个能够使用 alpha 混合绘制自定义形状窗口的蒙皮引擎。也就是说,它将使用分层窗口 ( UpdateLayeredWindow )。一个典型的窗口将在其背景中包含几十个其他位图,范围从 10×10 到例如 300×150 像素。在最坏的情况下,这些元素中的大多数将具有高达 30 fps 的流畅动画。一切都将是 alpha 混合的,我将为此使用 Direct2D(是的,我知道旧的 Windows 版本不支持它)。一般来说,Winamp 的现代皮肤引擎是最接近的例子。

考虑到这一切并考虑到现代 PC 的性能,我可以在每一帧重绘整个窗口还是必须限制到某种剪辑矩形?