【问题标题】:Transparent Form Woes (Form shows up black, form doesn't show up at all)透明表格问题(表格显示为黑色,表格根本不显示)
【发布时间】:2012-12-07 02:07:52
【问题描述】:

我正在尝试创建一个仍会响应鼠标移动和单击事件的透明表单,以在用户单击鼠标之前显示我们公司的徽标,但有时表单和标志根本不会出现,在其他时候它们会出现,但背景是黑色的。

我是这样称呼我的表单的:

MouseAlertForm maf = new MouseAlertForm(Win32.GetCursorPosition());
maf.Show();

maf.Show() 导致表单根本不显示(Show(this) 相同),maf.ShowDialog() 导致黑色背景。这是MouseAlertForm 的代码。

public sealed partial class MouseAlertForm : Form
{
    private Image Logo;
    public Point MouseLocation { get; private set; }

    public MouseAlertForm(Point location)
    {
        InitializeComponent();
        MouseLocation = location; 

        // Allow transparent backgrounds.
        SetStyle(ControlStyles.SupportsTransparentBackColor, true);

        // Set up this form to be maximum size, with no borders, and have a nearly transparent background.
        this.TopMost = true;
        this.DoubleBuffered = true;
        this.ShowInTaskbar = false;
        this.FormBorderStyle = FormBorderStyle.None;
        this.WindowState = FormWindowState.Maximized;
        this.BackColor = Color.FromArgb(1,255,255,255);

        // Load the Image.
        var assemlby = Assembly.GetAssembly(new AssemblyTypeLinker().GetType());
        if (assemlby != null)
            Logo = Image.FromStream(assemlby.GetManifestResourceStream("MyProgram.MyLogo.png"));
    }

    /// <summary>
    /// Update the current mouse location, and invalidate the control causing a re-draw.
    /// </summary>
    /// <param name="e"></param>
    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);

        MouseLocation = e.Location;
        Invalidate();
    }

    /// <summary>
    /// Release our logo, and close the form.
    /// </summary>
    /// <param name="e"></param>
    protected override void OnMouseClick(MouseEventArgs e)
    {
        base.OnMouseClick(e);

        Logo.Dispose();
        this.Close();
    }

    /// <summary>
    /// Clear what was previously drawn, and if we have a mouse location, draw the logo in that area.
    /// </summary>
    /// <param name="e"></param>
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        // Clear the background back to a nearly transparent white.
        e.Graphics.Clear(Color.FromArgb(1, 255, 255, 255));

        if (MouseLocation != Point.Empty)
        {
            // Draw our logo in the spot of the current mouse location.
            e.Graphics.DrawImage(Logo, MouseLocation.X - 100, MouseLocation.Y - 100, 200, 200);
        }
    }
}

编辑:似乎即使在我认为是背景的情况下也会创建黑色背景。我将我的BackColor 设置为完整的 255,并将其设为蓝色,然后将 alpha 分量慢慢降低到 0,只留下我看到的黑色背景。这是 ShowDialog 的特点吗?这个背景是从哪里来的?

【问题讨论】:

  • 必须是表格,为什么不是面板?
  • 面板也可以工作,让我试一试!我真的不介意它是什么,只要它占据整个桌面,是透明的,并且可以显示我的标志。 :)
  • @gaynorvader 我还是没有运气。请记住,这是从一个应用程序启动的,该应用程序本身没有任何形式,只有一个任务栏图标。
  • 我记得尝试通过调整不透明度来使表单淡入淡出。每当您从 100% 切换到其他任何值时,都会导致表单闪烁黑色并偶尔保持黑色。我通过只将不透明度提高到 99.9% 来解决它。我不确定这是否与您的颜色切换问题有关,但可能值得考虑。
  • 设置不透明度的问题是,当它绘制的图像应该完全可见时,对 e.Graphics.DrawImage 的调用也遵循相同的不透明度。不过感谢您的评论!

标签: c# .net winforms graphics mouse


【解决方案1】:

这里是修复。首先,因为我现在覆盖了OnPaint,而在之前的实现中我没有,我经常使用CreateGraphics()。但是由于我覆盖了OnPaint,它带有自己的图形对象,当它无效时为我清除,因此我不需要自己清除它。

其次,我不知道为什么,但之前使用 BackColorTransparencyKey 导致 MouseMoveMouseClick 事件未注册,但我再次相信,因为我正在覆盖他们反对附在他们身上,尽管TransparencyKey,他们还是被解雇了。

public sealed partial class MouseAlertForm : Form
{
    private Image Logo;
    public Point MouseLocation { get; private set; }

    public MouseAlertForm(Point location)
    {
        InitializeComponent();
        MouseLocation = location; 

        // Allow transparent backgrounds.
        SetStyle(ControlStyles.SupportsTransparentBackColor, true);

        // Set up this form to be maximum size, with no borders, and have a nearly transparent background.
        this.TopMost = true;
        this.DoubleBuffered = true;
        this.ShowInTaskbar = false;
        this.FormBorderStyle = FormBorderStyle.None;
        this.WindowState = FormWindowState.Maximized;

        this.BackColor = Color.Lime;
        this.TransparencyKey = Color.Lime;

        // Load the Image.
        var assembly = Assembly.GetAssembly(new AssemblyTypeLinker().GetType());
        if (assembly != null)
            Logo = Image.FromStream(assembly.GetManifestResourceStream("MyProgram.MyLogo.png"));
    }

    /// <summary>
    /// Update the current mouse location, and invalidate the control causing a re-draw.
    /// </summary>
    /// <param name="e"></param>
    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);

        MouseLocation = e.Location;
        Invalidate();
    }

    /// <summary>
    /// Release our logo, and close the form.
    /// </summary>
    /// <param name="e"></param>
    protected override void OnMouseClick(MouseEventArgs e)
    {
        base.OnMouseClick(e);

        Logo.Dispose();
        this.Close();
    }

    /// <summary>
    /// Clear what was previously drawn, and if we have a mouse location, draw the logo in that area.
    /// </summary>
    /// <param name="e"></param>
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        if (MouseLocation != Point.Empty)
        {
            // Draw our logo in the spot of the current mouse location.
            e.Graphics.DrawImage(Logo, MouseLocation.X - 100, MouseLocation.Y - 100, 200, 200);
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-22
    • 2019-03-27
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多