无边界形式上的闪烁阴影

时间:2013-11-27 01:32:01

标签: c# winforms shadow flicker

有没有办法为无边框表单创建一个阴影,在调整表单大小时不会闪烁?现在我正在使用CreateParams。

protected override CreateParams CreateParams
{
    get
    {
        const int CS_DROPSHADOW = 0x20000;
        CreateParams cp = base.CreateParams;
        cp.ClassStyle |= CS_DROPSHADOW;
        return cp;
    }
}

但是当调整窗体大小时,阴影部分变为白色,然后变回阴影,闪烁。表格的其余部分不是因为我使用this.DoubleBuffered = true;
任何帮助表示赞赏,谢谢!

修改
我使用SendMessage

调整表单大小

private const int WM_NCLBUTTONDOWN = 0xa1;
SendMessage(handle, WM_NCLBUTTONDOWN, dir, 0);

dir是一个int,根据我想要调整表单的方向而变化。

1 个答案:

答案 0 :(得分:1)

我认为您的问题是由您的实施引起的,以支持使用问题中发布的SendMessage进行自定义大小调整。我尝试使用WndProc捕获消息WM_NCHITTEST来实现调整大小,并将结果返回到鼠标位置。当您调整顶部和左侧边缘并且其他边缘根本没有闪烁时,看起来没有任何闪烁。所以我认为你可以尝试这个代码,它对我有用:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        DoubleBuffered = true;
        FormBorderStyle = FormBorderStyle.None;
    }
    protected override CreateParams CreateParams
    {
        get
        {
            const int CS_DROPSHADOW = 0x20000;
            CreateParams cp = base.CreateParams;
            cp.ClassStyle |= CS_DROPSHADOW;
            return cp;
        }
    }
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x84) //WM_NCHITTEST = 0x84
        {
            int x = m.LParam.ToInt32() & 0xffff;
            int y = m.LParam.ToInt32() >> 16;
            int codex, codey;
            Point p = PointToClient(new Point(x, y));
            codey = p.Y < 5 ? 2 : p.Y > ClientSize.Height - 5 ? 1 : 0;
            codex = p.X < 5 ? 2 : p.X > ClientSize.Width - 5 ? 1 : 0;
            switch (codex + (codey<<2))
            {
                case 10://Top-Left
                    m.Result = (IntPtr)13;
                    return;
                case 8://Top
                    m.Result = (IntPtr)12;
                    return;
                case 9://Top-Right
                    m.Result = (IntPtr)14;
                    return;
                case 2://Left
                    m.Result = (IntPtr)10;
                    return;
                case 1://Right
                    m.Result = (IntPtr)11;
                    return;
                case 6://Bottom-Left
                    m.Result = (IntPtr)16;
                    return;
                case 4://Bottom
                    m.Result = (IntPtr)15;
                    return;
                case 5://Bottom-Right;
                    m.Result = (IntPtr)17;
                    return;
            }                
        }
        base.WndProc(ref m);
    }
}

请注意,请勿使用SendMessage自定义大小调整,只需使用上面的代码。