Обработчик WndProc неэффективен - PullRequest
3 голосов
/ 13 декабря 2010

У меня есть следующий обработчик WndProc в моей форме. Это должно препятствовать перемещению формы по горизонтали (позволяя двигаться только по вертикали):

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);
}

Это работает, но когда пользователь перемещает форму, загрузка ЦП увеличивается очень значительно. Что может быть настолько неэффективным в этой функции и есть ли способы?

Ответы [ 2 ]

2 голосов
/ 13 декабря 2010

Я попробовал ваш код, и он работает хорошо.Как вы сказали, он не загружал процессор на 100%, а занимал всего ~ 16%.

Я полагаю, что на обработку уходит много времени, это рисунок вашей формы или фоновые окна.(а не реализация wndproc).

Попробуйте ограничить количество перерисовок, которые ваша форма может делать в секунду, добавив ожидание

System.Threading.Thread.Sleep(10);

после этой строки:

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

Сон 10 мс при перетаскиванииограничивает перерисовку вашей формы более 100 раз в секунду, оставляя неиспользуемым процессор…

РЕДАКТИРОВАТЬ: Забыл упомянуть, что добавление спящего режима изменило ~ 16% до ~ 12% на моем боксе.

1 голос
/ 13 декабря 2010

Вы можете просто проглотить сообщение, если не вызываете base.WndProc в своем блоке If

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

Другое решение (работает довольно хорошо, но иногда мерцает)

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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...