我的表单中有以下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);
}
它可以工作但是当用户移动表单时CPU使用率会显着增加。在这个函数中可能效率如此低,有什么办法吗?
答案 0 :(得分:2)
我尝试了你的代码,效果很好。如你所说,它并没有使100%CPU饱和,只占了约16%。
我认为花费很长时间处理的是绘制表单或绘制背景窗口(而不是wndproc实现)。
尝试通过添加等待
来限制表单每秒可以执行的重绘次数System.Threading.Thread.Sleep(10);
这一行之后:
Marshal.StructureToPtr(rc, m.LParam, false);
在拖动时睡10毫秒限制你的表格每秒重绘超过100次,同时留下一些CPU未使用......
编辑:忘记提及添加睡眠在我的盒子上改变了~16%~12%。
答案 1 :(得分:1)
如果你没有在你的If块
中调用base.WndProc,你可以吞下这条消息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);
}
}