views:

1772

answers:

3

Anyone out there know how to make your .net windows form app sticky/snappy like Winamp so it snaps to the edges of the screen?

The target framework would be .NET 2.0 Windows Form written in C#, using VS08. I am looking to add this functionality to a custom user control, but I figured more people would benefit from having it described for the application and its main form.

Thank you.

+2  A: 

Just retrieve the current pixel height/width of the monitor you're on...

http://stackoverflow.com/questions/229528/how-to-determine-active-monitor-of-the-current-cursor-location/229651

... and process the location changed/moved events for the form. When you get within, say 25 pixels or so of an edge (your main form's Location.Left + form width) or height (your main form's Location.Top + form height), then go ahead and set the .Left and .Top properties so that your application "docks" in the corners.

Edit: One other note - when you actually do the "snapping" you may also want to move the cursor position the relative distance to make it stay on the same point on the window bar. Otherwise your form may become a giant ping pong ball between the cursor position and your "snappy" functionality as the MouseMove and form location changed events fight against each other.

routeNpingme
the only problem with that is once your docked you can never leave. Be sure to allow for a mouse move, (i.e. click and drag 25 pixels) once docked that can undock your form.
Neil N
If that were desired functionality, you could call it a "Docking Hotel California".
routeNpingme
Don't you think you should allow for the taskbar and other toolbars rather than obscuring them?
MarkJ
+7  A: 

This worked pretty well, works on multiple monitors, observes the taskbar:

  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }
    private const int SnapDist = 100;
    private bool DoSnap(int pos, int edge) {
      int delta = pos - edge;
      return delta > 0 && delta <= SnapDist;
    }
    protected override void  OnResizeEnd(EventArgs e) {
      base.OnResizeEnd(e);
      Screen scn = Screen.FromPoint(this.Location);
      if (DoSnap(this.Left, scn.WorkingArea.Left)) this.Left= scn.WorkingArea.Left;
      if (DoSnap(this.Top, scn.WorkingArea.Top)) this.Top = scn.WorkingArea.Top;
      if (DoSnap(scn.WorkingArea.Right, this.Right)) this.Left = scn.WorkingArea.Right - this.Width;
      if (DoSnap(scn.WorkingArea.Bottom, this.Bottom)) this.Top = scn.WorkingArea.Bottom - this.Height;
    }
  }
Hans Passant
+3  A: 

Great article at: link text