如何在 Windows Aero 模糊中保持 TextBox 文本不透明?
2024-03-07 09:56:01
如何让 Aero 模糊中的 TextBox 文本保持不透明?
引言
在 Windows Vista、7 和 10 中,利用 Aero 模糊效果创建无边框窗体的方法是使用 UpdateAeroBlur
函数。然而,这个函数会导致一个烦恼的副作用:TextBox 控件中的文本变得透明。
问题
使用抗锯齿文本 GDI+ 绘制的按钮文本仍然是不透明的,而 TextBox 控件中的文本却变成了透明。虽然尝试了 SetLayeredWindowAttributes
函数,但问题仍然存在。
解决方案
解决这个问题的办法是修改 UpdateAeroBlur
函数,添加以下代码行:
// 在调用 DwmEnableBlurBehindWindow 之前添加此行
NativeApi.SetWindowLongPtr(Handle, GWL_EXSTYLE, (IntPtr)(
NativeApi.GetWindowLongPtr(Handle, GWL_EXSTYLE) |
NativeApi.WS_EX_LAYERED
));
运作原理
这个代码行将 WS_EX_LAYERED
扩展样式添加到窗口。这允许窗口混合自身和底层窗口,从而使 TextBox 文本保持不透明。
更新后的 UpdateAeroBlur 函数
以下是更新后的 UpdateAeroBlur
函数:
private void UpdateAeroBlur() {
if (!SupportsAeroBlur) //do not do anything if XP or older
return;
else if (useSetWindowComposition) { //true if SetWindowCompositionAttribute function
//exists in user32.dll
AccentPolicy accent = new AccentPolicy();
accent.AccentState = enableAeroBlur ? AccentState.ENABLE_BLURBEHIND : AccentState.DISABLED;
WindowCompositionAttributeData data = new WindowCompositionAttributeData();
data.Attribute = DwmWindowAttribute.ACCENT_POLICY;
data.SizeOfData = AccentPolicy.Size;
unsafe
{
data.Data = new IntPtr(&accent);
}
NativeApi.SetWindowCompositionAttribute(Handle, ref data);
}
// 在调用 DwmEnableBlurBehindWindow 之前添加此行
NativeApi.SetWindowLongPtr(Handle, GWL_EXSTYLE, (IntPtr)(
NativeApi.GetWindowLongPtr(Handle, GWL_EXSTYLE) |
NativeApi.WS_EX_LAYERED
));
DWM_BLURBEHIND style = new DWM_BLURBEHIND() {
dwFlags = DWM_BB.Enable,
fEnable = true
};
NativeApi.DwmEnableBlurBehindWindow(Handle, ref style);
}
结论
通过修改 UpdateAeroBlur
函数并添加 WS_EX_LAYERED
扩展样式,可以使 TextBox 文本在 Aero 模糊中保持不透明,同时保持边框的半透明效果。
常见问题解答
1. 这个解决方案适用于所有版本的 Windows 吗?
是的,它适用于 Windows Vista、7 和 10。
2. 我需要使用 SetLayeredWindowAttributes
函数吗?
不需要。修改后的 UpdateAeroBlur
函数已经包括了必要的更改。
3. 为什么 GDI+ 按钮文本保持不透明,而 TextBox 文本不会?
这是因为按钮文本使用抗锯齿文本 GDI+ 绘制,而 TextBox 文本则使用非抗锯齿文本 GDI+ 绘制。
4. 除了修改 UpdateAeroBlur
函数之外,还有什么其他方法可以解决这个问题吗?
没有。修改 UpdateAeroBlur
函数是解决这个问题的唯一方法。
5. 这个解决方案有性能问题吗?
不,这个解决方案对性能没有影响。