2010-12-13 18 views
3

Ich habe den folgenden Handler von WndProc in meinem Formular. Es sollte horizontal Bewegen der Form verhindern (so dass nur vertikal bewegen):WndProc Handler ist ineffizient

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

Es funktioniert aber, wenn der Benutzer bewegt die Form CPU-Auslastung steigt sehr deutlich. Was könnte in dieser Funktion so ineffizient sein und gibt es irgendwelche Möglichkeiten?

+0

Hohe CPU-Auslastung ist nicht unbedingt eine schlechte Sache. Ist das eigentlich ein Problem, oder warum schaust du auf die CPU-Auslastung? http://blogs.msdn.com/b/oldnewthing/archive/2010/12/03/10097861.aspx –

+0

Es ist wirklich ein Problem: Es verursacht andere Prozess hängen – SiberianGuy

+0

Zuordnung ist auf dieser Website erforderlich. –

Antwort

2

Ich habe versucht, Ihre Code, und es funktioniert gut. Es hat nicht 100% CPU gesättigt, wie du gesagt hast, nur ~ 16%.

Ich nehme an, dass das Zeichnen Ihres Formulars oder das Zeichnen Ihrer Hintergrundfenster (und nicht die WnDproc-Implementierung) lange dauert.

versuchen, die Menge von redraws begrenzen, die Ihre Form

System.Threading.Thread.Sleep(10); 

nach dieser Zeile

durch Hinzufügen einer Wartezeit pro Sekunde tun können:

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

10 ms Schlafen während Grenzen Sie Ihr Formular zieht mehr von Nachziehen als 100 Mal pro Sekunde, während einige CPU unbenutzt lassen ...

EDIT: vergessen zu erwähnen, dass das Hinzufügen der Schlaf verändert die ~ 16% bis ~ 12% auf meiner Box.

1

Sie könnten nur die Nachricht schlucken, wenn du deine nicht base.WndProc rufen in Wenn Block

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

Eine andere Lösung (ganz gut funktioniert, aber somethimes flackert)

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

Hm ... Sieht aus wie es nicht hilft – SiberianGuy

+0

Eine andere Lösung hinzugefügt –