开发者

WndProc handler is inefficient

I have the following handler of WndProc in my form. It should prevent moving the form horizontally (allowing to move only vertically):

protected override void WndProc(ref System.Windows.Forms.Message m)
{
    if (!ShowCaption && m.Msg == 0x216)
    {  // Trap WM_MOVING
        var rc = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
        int w = rc.right - rc.left;
        rc.left = this.Left;
        rc.right = rc.left + w;
        Marshal.StructureToPtr(rc, m.LParam, false);
    }
    base.WndProc(ref m);
}

It works but when user moves the form CPU usage increases very significantly. What could be so inefficient 开发者_开发百科in this function and are there any ways to?


I tried your code, and it works well. It didn't saturated 100% CPU as you said, only took ~16%.

I suppose that what is taking a long time to process, is the drawing of your form, or the drawing of your background windows (and not the wndproc implementation).

Try limiting the amount of redraws that your form can do per second by adding a wait

System.Threading.Thread.Sleep(10);

after this line:

Marshal.StructureToPtr(rc, m.LParam, false);

Sleeping 10 ms while dragging limits your form from redrawing more than 100 times per second, while leaving some CPU unused...

EDIT: Forgot to mention that adding the sleep changed the ~16% to ~12% on my box.


You could just swallow the message if you don't call base.WndProc in your If block

if (!ShowCaption && m.Msg == 0x216)
{
    // Trap WM_MOVING
}
else
{
    base.WndProc(ref m);
}

Another solution (works quite well but somethimes flickers)

public partial class Form1 : Form
{
    private int initialX;
    public Form1()
    {
        InitializeComponent();
        initialX = this.Location.X;
    }

    private void Form1_LocationChanged(object sender, EventArgs e)
    {
        if (this.Location.X != initialX)
            this.Location = new Point(initialX, this.Location.Y);
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜