You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C#中使用SetWindowLong和SetLayeredWindowAttributes设置分层透明失效问题

问题原因分析
  • 当你给Form设置WS_EX_LAYERED属性并将Alpha值设为0时,整个分层窗口(包括所有子控件)都会继承这个完全透明的属性,所以整个界面都变成透明状态。
  • PictureBox作为标准子控件,无法直接通过SetWindowLong设置WS_EX_LAYERED来实现独立的半透明效果——Windows的分层窗口机制中,子窗口默认不支持分层属性,即便强行设置也不会生效,反而会因为父窗口的全局透明被覆盖。
正确实现方案

要达成「Form完全透明、PictureBox半透明」的效果,推荐使用TransparencyKey实现Form透明,再通过重绘PictureBox实现半透明:

步骤1:设置Form透明

通过TransparencyKey让Form中指定颜色的区域完全透明,同时保留子控件的可见性:

public Form1()
{
    InitializeComponent();
    // 选一个不常用的颜色作为透明键,设置Form背景色与透明键一致
    this.BackColor = Color.Magenta;
    this.TransparencyKey = Color.Magenta;
}

步骤2:实现PictureBox半透明

方式一:自定义半透明PictureBox控件

重写PictureBox的OnPaint方法,通过半透明画笔绘制内容:

public class TransparentPictureBox : PictureBox
{
    private float _opacity = 0.5f; // 半透明程度,范围0-1
    public float Opacity
    {
        get => _opacity;
        set
        {
            _opacity = Math.Clamp(value, 0f, 1f);
            Invalidate();
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        if (Image != null)
        {
            // 使用半透明画笔绘制图片
            using (var brush = new ImageBrush(Image))
            {
                brush.Opacity = _opacity;
                e.Graphics.FillRectangle(brush, ClientRectangle);
            }
        }
        base.OnPaint(e);
    }
}

在Form中使用这个自定义控件,设置Opacity = 0.5f即可实现半透明效果。

方式二:使用带Alpha通道的图片

直接给PictureBox设置一张带半透明通道的PNG图片,无需额外代码,图片本身的半透明效果会直接显示。

备选方案:分层窗口直接绘制(复杂场景)

如果必须使用SetLayeredWindowAttributes,则需要放弃直接使用PictureBox,改为在Form的Paint事件中直接绘制半透明内容:

const int GWL_EXSTYLE = -20;
const uint WS_EX_LAYERED = 0x80000;
const uint LWA_ALPHA = 0x2;

[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
[DllImport("user32.dll")]
static extern bool SetLayeredWindowAttributes(IntPtr hWnd, uint crKey, byte bAlpha, uint dwFlags);

void Form_Load(object sender, EventArgs e)
{
    // 给Form设置分层属性
    SetWindowLong(this.Handle, GWL_EXSTYLE, WS_EX_LAYERED);
    // 设置Form完全透明
    SetLayeredWindowAttributes(this.Handle, 0, 0, LWA_ALPHA);
}

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    // 直接在Form上绘制半透明图片
    if (picBox1.Image != null)
    {
        using (var img = picBox1.Image)
        {
            e.Graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
            e.Graphics.DrawImage(img, picBox1.Bounds, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel);
            // 调整透明度
            var colorMatrix = new System.Drawing.Imaging.ColorMatrix
            {
                Matrix33 = 0.5f // 半透明程度,范围0-1
            };
            var imageAttr = new System.Drawing.Imaging.ImageAttributes();
            imageAttr.SetColorMatrix(colorMatrix);
            e.Graphics.DrawImage(img, picBox1.Bounds, 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, imageAttr);
        }
    }
}

内容的提问来源于stack exchange,提问作者지디늅

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 10:19:58