|
//====================================================
//| Downloaded From |
//| Visual C# Kicks - http://www.vcskicks.com/ |
//| License - http://www.vcskicks.com/license.html |
//====================================================
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace WindowShake
{
public class ShakeForm : Form
{
const int WM_NCMOUSEMOVE = 0xA0;
const int WM_NCLBUTTONDOWN = 0xA1;
const int WM_NCRBUTTONDOWN = 0xA4;
const int WM_WINDOWPOSCHANGED = 0x0047;
private bool captureMovement;
private DateTime captureStart;
private DateTime captureEnd;
private List<Point> movements;
public event EventHandler FormShaken;
protected override void WndProc(ref Message m)
{
//Set primary mouse button
int mouseButton = SystemInformation.MouseButtonsSwapped ? WM_NCRBUTTONDOWN : WM_NCLBUTTONDOWN;
if (m.Msg == mouseButton) //Mouse Down
{
//Start capturing window movements
captureStart = DateTime.Now;
captureMovement = true;
}
else if (captureMovement && m.Msg == WM_NCMOUSEMOVE) //Left Mouse Up
{
//Stop capturing window movements
captureEnd = DateTime.Now;
captureMovement = false;
//Process movement data
ProcessMovement();
}
if (m.Msg == WM_WINDOWPOSCHANGED)
{
if (captureMovement)
{
//Initialize movement list
if (movements == null)
movements = new List<Point>();
//Store current position
movements.Add(new Point(this.Left, this.Top));
}
}
base.WndProc(ref m);
}
private void ProcessMovement()
{
if (this.WasShaken() && FormShaken != null)
FormShaken(this, EventArgs.Empty);
//Reset Markers
movements.Clear();
movements = null;
captureStart = DateTime.MinValue;
captureEnd = DateTime.MinValue;
}
private bool WasShaken()
{
if (movements != null)
{
//Calculate average point from all the collected positions
Point avg = GetAveragePoint(movements);
//Calculate difference of average point to current position
Point deltaPoint = new Point();
deltaPoint.X = this.Left - avg.X;
deltaPoint.Y = this.Top - avg.Y;
//Calculate the number of milliseconds that spanned while the window moved
//Note: Only uses seconds and milliseconds
TimeSpan movementTime = captureEnd.Subtract(captureStart);
int msSpan = (movementTime.Seconds * 1000 + movementTime.Milliseconds);
//If values fall within a certain range, then the window was shaken
return msSpan <= 600 && //speed of the shake in milliseconds
movements.Count >= 30 && //amount of movements in the shake
Math.Abs(deltaPoint.X) <= 30 && Math.Abs(deltaPoint.Y) <= 30; //average "size" of shake
}
return false;
}
private Point GetAveragePoint(List<Point> points)
{
Point avg = new Point();
foreach (Point p in points)
{
avg.X += p.X;
avg.Y += p.Y;
}
avg.X /= points.Count;
avg.Y /= points.Count;
return avg;
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.