How do you use DwmGetColorizationColor
?
The documentation says it returns two values:
0xAARRGGBB
containing the color used for glass compositionHere's a color that i like, a nice puke green:
You can notice the color is greeny, and the translucent title bar (against a white background) shows the snot color very clearly:
i try to get the color from …
使用GDI +绘制各种颜色:
brush = new SolidBrush(color);
graphics.FillRectangle(brush, x, y, width, height);
Run Code Online (Sandbox Code Playgroud)
您会注意到在玻璃上没有显示不透明的颜色:
我如何在玻璃上画出纯色?
您还会注意到完全不透明的颜色会根据颜色的不同而有所不同:
有人能指出我在桌面合成器上的文档,解释了如何处理不同的颜色?
您还会注意到FillRectangle
行为与以下不同FillEllipse
:
FillEllipse
不透明的颜色会产生不透明的颜色FillRectangle
不透明的颜色部分(或完全)透明请解释非感性行为.
Alwayslearning建议我改变合成模式.来自MSDN:
CompositingMode枚举
该CompositingMode枚举指定如何呈现的颜色与背景颜色组合.此枚举由使用
Graphics::GetCompositingMode
和"图形:: SetCompositingMode"的方法图形类.Run Code Online (Sandbox Code Playgroud)CompositingModeSourceOver
指定在渲染颜色时,它与背景颜色混合.混合由要渲染的颜色的alpha分量确定.
Run Code Online (Sandbox Code Playgroud)CompositingModeSourceCopy
指定在渲染颜色时,它会覆盖背景颜色.此模式不能与TextRenderingHintClearTypeGridFit一起使用.
从描述来看CompositingModeSourceCopy
,听起来这不是我想要的选择.从它所施加的限制来看,它听起来像我想要的选项.并且通过禁用合成或透明度,它不是我想要的选项,因为它执行SourceCopy而不是SourceBlend:
幸运的是,这不是一个我必须考虑的邪恶,因为它不能解决我的实际问题.构建我的graphics
对象后,我尝试更改合成模式:
graphics = new Graphics(hDC);
graphics.SetCompositingMode(CompositingModeSourceCopy); //CompositingModeSourceCopy = 1
Run Code Online (Sandbox Code Playgroud)
结果对输出没有影响:
我必须在客户区涂上什么颜色才能制作玻璃?
我使用以下方法将表单框架扩展到客户区:
DwmExtendFrameIntoClientArea(self.Handle, margins);
Run Code Online (Sandbox Code Playgroud)
我找不到微软的官方文档,说明DWM用玻璃代替什么颜色和/或alpha.DwmExtendFrameInClientArea上的文档甚至没有提到需要自定义颜色.只有传闻和神话,甚至需要特殊的颜色.
我能找到的最接近的是MSDN上的主题:
使用DWM的自定义窗口框架
为了使扩展帧可见,每个扩展帧的边下面的区域必须具有alpha值为0的像素数据.
更新:和博客文章:
Windows Vista for Developers - 第3部分 - 桌面窗口管理器
碰巧RGB黑色(0x00000000)的位模式与100%透明ARGB的位模式相同,因此您可以使用"黑色"GDI画笔实际绘制并假设您已指示DWM模糊绘制区域,结果将是所需的玻璃效果.
如果我按照他们的字面意思(alpha值为零的像素数据),我构造一个零alpha的颜色,并在扩展区域绘制:
Color fillColor = Color.FromArgb(0, 0, 0, 0); //(a, r, g, b)
e.Graphics.FillRectangle(new SolidBrush(fillColor), e.ClipRectangle);
Run Code Online (Sandbox Code Playgroud)
但玻璃效果没有出现:
替代文字http://i46.tinypic.com/anlmd4.png
如果我忽略引用的MSDN主题,而是使用完全不透明的黑色(而不是完全透明的黑色):
Color fillColor = Color.FromArgb(255, 0, 0, 0); //(a, r, g, b)
e.Graphics.FillRectangle(new SolidBrush(fillColor), e.ClipRectangle);
Run Code Online (Sandbox Code Playgroud)
玻璃效果确实出现了:
alt text http://i45.tinypic.com/2ug2ias.png
然后我开始相信不透明的黑色是DWM用玻璃代替的像素值.
但那我如何在玻璃区域上画黑色物品呢?
我测试过在玻璃区域上画一个黑色矩形,旁边有一个圆圈.奇怪的是,矩形没有出现,而圆圈确实出现; 两者颜色相同:
Brush …
Run Code Online (Sandbox Code Playgroud) 我在WinXP下构建了一个.dll,声称它在加载时无法找到DWMAPI.DLL.问题是这个DLL是Vista DLL,对于安装了IE7的XP用户来说这是一个已知问题.建议通过添加/删除程序卸载IE7或修复.NET Framework.我做了修理,没有任何改变.我不打算卸载IE7,因为必须有一个更好的解决方案,而不是"重新安装Windows".
我读过有关试图卸载IE7的人的坏话,所以我不愿意走那条路.
我在Visual Studio 2003(7.1)下使用C++.我没有看到我可能在应用程序启动时强制延迟加载的选项.我刚刚创建DLL项目时使用了默认设置.我刚刚找到了一个有趣的选项,链接器 - >输入 - >延迟加载的DLL,所以我把DWMAPI.DLL放在那里强迫它延迟加载.但是,我在链接时得到了这个:
LINK : warning LNK4199: /DELAYLOAD:dwmapi.dll ignored; no imports found from dwmapi.dll
Run Code Online (Sandbox Code Playgroud)
..当然,它在尝试加载我的DLL时没有改变.为了它,我添加了导致DWMAPI.DLL的整个DLL树,我收到相同的消息.(对于记录,它是foundation.dll-> shell32.dll-> shdocvw.dll-> mshtml.dll-> ieframe.dll-> dwmapi.dll.)
为了更具体地说明我正在做什么,我正在编写一个Maya插件并在脚本编辑器中获取始终有用的文本:
// Error: Unable to dynamically load : D:/blahblahblah/mydll.mll
The specified module could not be found.
//
// Error: The operation completed successfully.
//
// Error: The operation completed successfully.
(mydll) //
Run Code Online (Sandbox Code Playgroud)
我使用Dependency Walker来初步追踪问题,这就是我引导DWMAPI.DLL的原因.这些消息取决于我,DWMAPI.DLL是唯一一个旁边有黄色问号的东西:
Warning: At least one delay-load dependency module was not found.
Warning: At least one module has an unresolved …
Run Code Online (Sandbox Code Playgroud) 我在Eclipse中使用Maven时遇到了一个奇怪的配置问题.虽然我可以构建项目并将其部署到tomcat而没有任何错误,但Marker选项卡仍然显示以下消息:
[-] Maven Java EE Configuration Problem
(x) JavaServer Faces 1.2 can not be installed : One or more constraints have not been satisfied.
(x) JavaServer Faces 1.2 requires Dynamic Web Module 2.5 or newer.
Run Code Online (Sandbox Code Playgroud)
我实际上使用的是动态Web模块2.4,它将成为消息的来源.我需要将其更改为至少2.5才能使用JSF.问题是,我甚至没有使用JSF.
因此,项目的一个依赖项可能需要它.我运行以下命令来查找项目的依赖关系树:
mvn dependency:tree -DoutputFile=<i>/path/to/outputFile/dependencies.txt</i>
Run Code Online (Sandbox Code Playgroud)
而且惊喜!没有提到JSF 1.2.
编辑忘记添加我的电脑设置:
操作系统:Ubuntu 12.10
Eclipse:4.2 SR1
Java:jdk1.5.0_22和jdk1.7
Apache Maven:3.0.4
Maven主页:/ usr/share/maven
m2e:1.3.1.20130219-1424
m2e-wtp:0.17.0.20130212-1821
我的同事都没有遇到这个问题.其中两个使用Windows,两个使用Ubuntu 12.10.其中一个使用Eclipse 4.2,其他使用Eclipse 3.7.显然,这要么与4.2SR1有关,要么与我的项目设置有关.但我无法找到问题所在.
这是我的pom.xml文件:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edited</groupId>
<artifactId>edited</artifactId>
<packaging>war</packaging>
<version>edited</version>
<name>edited</name>
<distributionManagement>
<repository>
<id>deployment</id>
<name>Internal Releases</name>
<url>http://edited/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>deployment</id> …
Run Code Online (Sandbox Code Playgroud) 我很困惑Delphi 2009/2010对Windows中Aero Theme Glass功能的支持,以及DoubleBuffered的含义,以及与Aero glass有什么关系.我发现DoubleBuffered不仅是VCL中的一个属性,它也可以在.net WinForms中找到.最初我想知道它是否设置了公共控件库使用的某种窗口样式位,或者是什么.它为什么使用,何时使用?
[更新:我应该说我知道什么是"双缓冲",作为减少闪烁的一般技术,我想知道的是,为什么它与在Windows Vista中的Aero Glass窗格上渲染控件有任何关系? Windows 7,特别是为什么所有东西的按钮需要双缓冲设置为真,才能在玻璃上工作?下面链接的博客文章似乎最有用.]
特别是,我对DoubleBuffered属性感到困惑,我想知道它为什么存在,以及它在窗体和控件中的玻璃支持和双缓冲属性之间的关系是什么.当您阅读像这样的C++文章时,您会发现没有提到双缓冲.
[更新2:以下内容包含一些事实错误,并已修改:]
我发现一些C++开发人员正在讨论他们如何调用SetLayeredWindowAttributes以避免DWM/Aero合成导致的"黑色变成玻璃"故障,当你在经典的Win32应用程序中打开它时[但是下面的博客链接告诉我这不再起作用在Windows 7中,实际上只在Vista中短暂工作,直到微软阻止它].[开始错误的想法]我们不应该使用其他颜色,如明亮的洋红色,并使其变成玻璃透明色?[结束错误的想法]
什么时候应该设置和不设置DoubleBuffered的规则,以及为什么DoubleBuffered首先添加到VCL?设置什么时候会引起问题?(看来远程桌面是一种情况,但这是唯一的情况吗?)当它没有设置时,我们会搞清楚按钮文本的渲染,很可能是因为看起来Delphi没有改变默认的"渲染黑色如玻璃"在Aero DWM中.
在我看来,Aero Glass渲染基本上是以奇怪或难以理解的方式进行的[由Windows本身,而不是仅仅包含此功能的Delphi],以及2009/2010年的许多内部VCL源代码StdCtrls中的类必须做很多复杂的逻辑才能正确地在Aero Glass上呈现内容,但它仍然存在很多问题,并且看起来像是错误的,并且这可能是这个相关问题和qc问题的背后. [更新3:玻璃上的很多渲染故障,在VCL中在常见控件中渲染错误,看起来,微软并不关心修复.简而言之,Delphi VCL代码修复无法解决这样一个事实:古老的Windows通用控件库和现代[但奇特的] Aero Glass合成功能彼此不太相似,并且不能特别合作.感谢微软建立如此高质量的技术,并将其释放到世界各地.
如果它还不够有趣; 为什么我们有ParentDoubleBuffered?
[7月30日更新:这个问题对我很有意思,因为我认为它表明,当你拥有一个庞大的现有VCL框架时,使用Windows API解决这个问题是一个很难的问题.
我有一个wxWidgets应用程序,它有许多子opengl窗口.我正在使用自己的GL画布类,而不是wx类.Windows共享他们的OpenGL上下文.我不认为它是wxwidgets的事实在这里真的很重要.
opengl窗口是窗口的子窗口,它们是彼此的兄弟,包含在选项卡控件中.MDI样式界面的种类,但它不是MDI窗口..每个窗口都可以单独调整大小.除非启用Aero且DWM处于活动状态,否则一切都很可爱.
调整任何窗口(甚至不是opengl窗口)的大小会导致所有opengl窗口偶尔闪烁,其中包含一个陈旧的后备存储视图,其中包含屏幕上那个非opengl的垃圾.这仅在启用Aero时发生.
我很确定这是DWM实际上没有在其绘图表面后备存储上的opengl内容,并且窗口没有在正确的时刻重新绘制.
我已经尝试了很多东西来解决这个问题,我确实有一个解决方案,但它不是很好,并且需要将带有glReadPixels的帧缓冲区读入DIB,然后在我的onPaint例程中将其渲染到绘制DC.这种解决方法仅在DWM处于活动状态时才启用,但我根本不必这样做,因为它会稍微损害性能(但在功能强大的系统上也不会太糟糕 - 场景是相对简单的3d图形).也不推荐混合使用GDI和opengl,但这种方法令人惊讶.我现在可以忍受它,但我宁愿不必.如果我想截取子窗口的截图,我仍然需要在WM_PRINT中执行此操作,我没有看到解决方法.
有谁知道更好的解决方案吗?
在有人要求之前我肯定会做以下事情:
我试过了:
禁用DWM不是一种选择.
据我所知,如果你在OpenGL上使用Direct3D,这甚至是一个问题,虽然我没有测试过它,因为它代表了很多工作.
我正在开发一个应用程序,以网格样式在屏幕上定位窗口.在Windows 10上运行时,窗口之间存在巨大差距.进一步调查显示GetWindowRect
返回意外值,包括一个不可见的边框,但我不能让它返回带有可见边框的实际值.
1)这个帖子暗示这是设计的,你可以通过链接winver = 6来"修复"它.我的环境不允许这样,但我已经试图改变PE MajorOperatingSystemVersion
和MajorSubsystemVersion
6个无影响
2)同一个线程还建议使用DwmGetWindowAttribute
with DWMWA_EXTENDED_FRAME_BOUNDS
从DWM获取真实坐标,这有效,但意味着改变到达窗口坐标的每个地方.它也不允许设置值,让我们反转过程以便能够设置窗口大小.
3)这个问题表明在这个过程中缺乏DPI意识.既没有在清单中设置DPI感知标志,也没有调用SetProcessDpiAwareness
任何结果.
4)一时兴起,我还尝试添加Windows Vista,7,8,8.1和10兼容性标志,并且Windows主题清单没有任何变化.
这个窗口移动到0x0,1280x1024,据说可以填满整个屏幕,当查询坐标时,我们得到相同的值.然而,窗口实际上是14像素更窄,以考虑旧版Windows上的边框.
我怎样才能说服Windows让我使用真实的窗口坐标?
有关使用Qt和DWM的示例,请参阅在Windows上使用Blur Behind.替代文字http://labs.trolltech.com/blogs/wp-content/uploads/2009/09/blurbehind2.png
我想用Qt创建一个Windows Aero Glass窗口,现在它看起来像这样:
但在调用一些my_window->repaint()
我的窗口后,标签就会破碎:
但现在,如果我稍微调整窗口大小,它会重新正确重新绘制.
问题是:如何擦除窗口背景,以便小部件在干净的玻璃上绘画?
重现问题的简短代码是(Vista with Aero):
class Window(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
self.setLayout(QVBoxLayout())
self.layout().addWidget(QLabel("This is the text"))
# let the whole window be a glass
self.setAttribute(Qt.WA_NoSystemBackground)
from ctypes import windll, c_int, byref
windll.dwmapi.DwmExtendFrameIntoClientArea(c_int(self.winId()), byref(c_int(-1)))
def mousePressEvent(self, event):
self.repaint()
Run Code Online (Sandbox Code Playgroud)
您可以立即单击该窗口,也可以单击Alt-Tab
几次.
无论如何,使用带有Aero Glass的标签并不是我所需要的,因为QLabel不知道如何用一缕光线(如窗口的标题)来绘制自己.我需要的是清洁"玻璃"的一般方法.
在Windows 10上使用未记录的SetWindowCompositionAttribute
API,可以为窗口启用玻璃.玻璃是白色或透明的,如截图所示:
但是,Windows 10"开始"菜单和通知中心(均使用玻璃)都与强调色混合,如下所示:
它是如何做到的?
以下示例中的重点颜色为浅紫色 - 这是设置应用程序中的屏幕截图:
此示例代码中定义的AccentPolicy结构具有重音状态,标志和渐变颜色字段:
AccentPolicy = packed record
AccentState: Integer;
AccentFlags: Integer;
GradientColor: Integer;
AnimationId: Integer;
end;
Run Code Online (Sandbox Code Playgroud)
并且州可以具有以下任何值:
ACCENT_ENABLE_GRADIENT = 1;
ACCENT_ENABLE_TRANSPARENTGRADIENT = 2;
ACCENT_ENABLE_BLURBEHIND = 3;
Run Code Online (Sandbox Code Playgroud)
请注意,前两个是在这个github gist上找到的.
第三个工作正常 - 这使玻璃.其他两个,
所以这就越来越近了,它似乎是像音量控制小程序一样使用的一些弹出窗口.
这些值不能一起排序,并且GradientColor字段的值除了必须为非零之外没有任何效果.
直接在玻璃窗口上绘图会导致非常奇怪的混合.这里用红色填充客户区(ABGR格式为0x000000FF):
任何非零的alpha,例如0xAA0000FF,都不会产生任何颜色:
既不匹配"开始"菜单或通知区域的外观.
这些窗户是如何做到的?
dwm ×10
aero ×5
aero-glass ×3
winapi ×3
windows ×2
windows-10 ×2
c++ ×1
composition ×1
delphi ×1
direct3d ×1
dll ×1
eclipse ×1
gdi+ ×1
m2e ×1
maven ×1
opengl ×1
pyqt ×1
vb6 ×1
windows-xp ×1