MenuStrip的透明表单背景?

时间:2013-05-23 06:36:20

标签: c# transparency menustrip

根据SO上的很多问题,使表单背景透明的最佳方法是将其设置为一种相当未使用的颜色(如Magenta),然后设置表单TransparencyKey那种颜色。

this.BackColor = Color.Magenta;
this.TransparencyKey = Color.Magenta;

那部分工作正常。我遇到的问题是它在MenuStrip后面除了之外正常工作。 MenuStrip +透明背景中的半透明背景最终形式如下:

这就是MenuStrip的样子。它变为洋红色的部分是当MenuStrip本身设置为半透明时。

这是我的表单初始化函数的样子:

public frmMain() {
    this.TransparencyKey = Color.Magenta;
    InitializeComponent();
    this.BackColor = Color.Magenta;

    if(Properties.Settings.Default.windowTheme == 0) { // theme is light
        menuStrip.Renderer = new ToolStripProfessionalRenderer(new LightTheme());
    }
    else if(Properties.Settings.Default.windowTheme == 1) {
        menuStrip.Renderer = new ToolStripProfessionalRenderer(new DarkTheme());
    }

    menuStrip.Invalidate();
}

我的MenuStrip自定义渲染器(颜色仅用于测试):

public class LightTheme: ProfessionalColorTable {
    public override Color MenuItemSelected {
        get { return Color.FromArgb(255, Color.Yellow); }
    }

    public override Color MenuStripGradientBegin {
        get { return Color.FromArgb(255, Color.Black); }
    }

    public override Color MenuStripGradientEnd {
        get { return Color.FromArgb(0, Color.Gainsboro); }
    }
}

我真正想要实现的目标是让表单透明,并使MenuStrip的一部分透明,以便您可以看到它下面的桌面。有没有更好的方法,或解决这个问题的方法?

1 个答案:

答案 0 :(得分:1)

public override Color MenuStripGradientEnd {
    get { return Color.FromArgb(0, Color.Gainsboro); }
}

这是问题开始的地方,您为渐变结束颜色指定了alpha为0。哪个效果很好,alpha混合得很好。但它适用于背景颜色。所以你看到了洋红色的混合物。其中不再匹配颜色键,因此像素变得可见。

Windows内置的分层窗口功能支持两种方式将窗口与桌面混合,底层的winapi调用是SetLayeredWindowAttributes()。 Winforms支持LWA_COLORKEY选项,通过设置TransparencyKey属性而不是LWA_ALPHA选项来启用。称为“每像素alpha”。你可以在你需要启用它的pinvoke上找到大量的谷歌提示。

但是你会有一个粗鲁的惊喜,你会发现工具箱中的大多数控件都停止工作。 Winforms中的文本渲染是由GDI完成的,这是一个用alpha渲染文本的api。不可避免的副作用是,当你打开每像素alpha时,该文本现在也是透明的。你可以称之为功能,但由于你不能控制桌面颜色,也没有控制你背后的窗户,所以你可以称之为非常不切实际。

通过替换控件并使用像DirectWrite这样的文本渲染API,这也是可以修复的。但这相当多的工作,你只是不再从Winforms获得太多好处。 WPF支持每像素alpha,它不使用标准的Windows控件。