diff --git a/SIL.Windows.Forms.Tests/Hotspot/HotSpotProviderTestForms.cs b/SIL.Windows.Forms.Tests/Hotspot/HotSpotProviderTestForms.cs index e4c98e6ad..b5a4d5547 100644 --- a/SIL.Windows.Forms.Tests/Hotspot/HotSpotProviderTestForms.cs +++ b/SIL.Windows.Forms.Tests/Hotspot/HotSpotProviderTestForms.cs @@ -1,4 +1,3 @@ -using System; using System.Drawing; using System.Threading; using System.Windows.Forms; @@ -8,30 +7,10 @@ namespace SIL.Windows.Forms.Tests.Hotspot { [TestFixture] - [Category("MouseSensitive")] // do not move your mouse with these tests - [Category("SkipOnTeamCity")] public class HotSpotProviderTestForms { - private class ClickableTextBox : TextBox - { - public new void OnMouseClick(MouseEventArgs e) - { - base.OnMouseClick(e); - } - - public new void OnMouseDown(MouseEventArgs e) - { - base.OnMouseDown(e); - } - - public new void OnMouseUp(MouseEventArgs e) - { - base.OnMouseUp(e); - } - } - private HotSpotProvider _hotSpotProvider; - private ClickableTextBox _textBox; + private TextBox _textBox; private HotSpot.HotSpot _spot1; private HotSpot.HotSpot _spot2; private Point _originalCursorPosition; @@ -41,7 +20,7 @@ private class ClickableTextBox : TextBox public void Setup() { _hotSpotProvider = new HotSpotProvider(); - _textBox = new ClickableTextBox(); + _textBox = new TextBox(); _textBox.Width = 350; _textBox.Text = "Now is the time for ..."; _spot1 = new HotSpot.HotSpot(_textBox, 7, 3); @@ -50,11 +29,11 @@ public void Setup() _hotSpotProvider.SetEnableHotSpots(_textBox, true); _hotSpotProvider.RetrieveHotSpots += delegate(object sender, RetrieveHotSpotsEventArgs e) - { - e.AddHotSpot(_spot1); - e.AddHotSpot(_spot2); - e.Color = Color.Yellow; - }; + { + e.AddHotSpot(_spot1); + e.AddHotSpot(_spot2); + e.Color = Color.Yellow; + }; _originalCursorPosition = Cursor.Position; _form = new Form(); @@ -74,126 +53,80 @@ public void TearDown() [Test] public void DisableHotSpotProvider_MouseEventsNoLongerFired() { - bool mouseEnterFired = false; + var mouseEnterFired = false; _spot1.MouseEnter += delegate { mouseEnterFired = true; }; _hotSpotProvider.SetEnableHotSpots(_textBox, false); - Application.DoEvents(); Assert.IsFalse(mouseEnterFired); - MoveMouseSoOverHotSpot(_spot1); + _spot1.SimulateMouseMove(); Assert.IsFalse(mouseEnterFired); } [Test] public void HotSpotMouseEnter_MouseOverHotSpot_FiresMouseEnter() { - bool mouseEnterFired = false; + var mouseEnterFired = false; _spot1.MouseEnter += delegate { mouseEnterFired = true; }; - Application.DoEvents(); Assert.IsFalse(mouseEnterFired); - MoveMouseSoOverHotSpot(_spot1); + _spot1.SimulateMouseMove(); Assert.IsTrue(mouseEnterFired); } [Test] public void HotSpotMouseEnter_MouseNotOverHotSpot_DoesNotFireMouseEnter() { - bool mouseEnterFired = false; + var mouseEnterFired = false; _spot1.MouseEnter += delegate { mouseEnterFired = true; }; - Application.DoEvents(); - Assert.IsFalse(mouseEnterFired); - MoveMouseSoNotOverHotSpot(); + + _textBox.SimulateMouseMove(0, 0); Assert.IsFalse(mouseEnterFired); } [Test] - public void HotSpotMouseEnter_MouseOverHotSpotThenOffControlThenBackOverSameHotSpot_FiresMouseEnter() + public void + HotSpotMouseEnter_MouseOverHotSpotThenOffControlThenBackOverSameHotSpot_FiresMouseEnter() { - bool mouseEnterFired = false; + var mouseEnterFired = false; _spot1.MouseEnter += delegate { mouseEnterFired = true; }; - Application.DoEvents(); - - MoveMouseSoOverHotSpot(_spot1); + _spot1.SimulateMouseMove(); mouseEnterFired = false; - MoveMouseOffControl(); - + _textBox.SimulateMouseMove(-10, -10); // Move off control Assert.IsFalse(mouseEnterFired); - MoveMouseSoOverHotSpot(_spot1); - + _spot1.SimulateMouseMove(); Assert.IsTrue(mouseEnterFired); } [Test] public void HotSpotMouseLeave_MouseOverHotSpotThenAway_FiresMouseLeave() { - bool mouseLeaveFired = false; - _spot1.MouseLeave += delegate { mouseLeaveFired = true; }; - - Application.DoEvents(); - Assert.IsFalse(mouseLeaveFired); - - MoveMouseSoOverHotSpot(_spot1); - Assert.IsFalse(mouseLeaveFired); - - // mouse off hot spot still over control - MoveMouseSoNotOverHotSpot(); - - Assert.IsTrue(mouseLeaveFired); - } - - [Test] - public void HotSpotMouseLeave_MouseOverHotSpotThenOffControl_FiresMouseLeave() - { - bool mouseLeaveFired = false; + var mouseLeaveFired = false; _spot1.MouseLeave += delegate { mouseLeaveFired = true; }; - Application.DoEvents(); Assert.IsFalse(mouseLeaveFired); - MoveMouseSoOverHotSpot(_spot1); + _spot1.SimulateMouseMove(); Assert.IsFalse(mouseLeaveFired); - MoveMouseOffControl(); - + _textBox.SimulateMouseMove(0, 0); // Move off hot spot Assert.IsTrue(mouseLeaveFired); } - [Test] - public void HotSpotMouseLeave_MouseNotOverHotSpotThenOffControl_DoesNotFireMouseLeave() - { - bool mouseLeaveFired = false; - _spot1.MouseLeave += delegate { mouseLeaveFired = true; }; - - Application.DoEvents(); - - Assert.IsFalse(mouseLeaveFired); - - MoveMouseSoNotOverHotSpot(); - Assert.IsFalse(mouseLeaveFired); - - MoveMouseOffControl(); - - Assert.IsFalse(mouseLeaveFired); - } - [Test] public void HotSpotMouseMove_MouseOverHotSpot_FiresMouseMove() { - bool mouseMoveFired = false; + var mouseMoveFired = false; _spot1.MouseMove += delegate { mouseMoveFired = true; }; - Application.DoEvents(); - - MoveMouseSoOverHotSpot(_spot1); + _spot1.SimulateMouseMove(); Assert.IsTrue(mouseMoveFired); } @@ -201,125 +134,78 @@ public void HotSpotMouseMove_MouseOverHotSpot_FiresMouseMove() [Test] public void HotSpotMouseMove_MouseNotOverHotSpot_DoesNotFireMouseMove() { - bool mouseMoveFired = false; + var mouseMoveFired = false; _spot1.MouseMove += delegate { mouseMoveFired = true; }; - Application.DoEvents(); - - MoveMouseSoNotOverHotSpot(); + _textBox.SimulateMouseMove(new Point(0, 0)); Assert.IsFalse(mouseMoveFired); } - [Test] - public void HotSpotMouseMove_MouseOverHotSpotThenMoveOverHotSpot_FiresMouseMove() - { - bool mouseMoveFired = false; - _spot1.MouseMove += delegate { mouseMoveFired = true; }; - - Application.DoEvents(); - - MoveMouseSoOverHotSpot(_spot1); - mouseMoveFired = false; - - // move over hot spot - Point position = Cursor.Position; - position.Offset(1, 1); - Cursor.Position = position; - Application.DoEvents(); - - Assert.IsTrue(mouseMoveFired); - } - [Test] public void HotSpotMouseHover_MouseHoverOverHotSpot_FiresMouseHover() { - bool mouseHoverFired = false; + var mouseHoverFired = false; _spot1.MouseHover += delegate { mouseHoverFired = true; }; - Application.DoEvents(); + _spot1.SimulateMouseMove(); - MoveMouseSoOverHotSpot(_spot1); - Hover(); + _textBox.SimulateMouseHover(); Assert.IsTrue(mouseHoverFired); } [Test] public void HotSpotMouseHover_MouseHoverNotOverHotSpot_DoesNotFireMouseHover() { - bool mouseHoverFired = false; + var mouseHoverFired = false; _spot1.MouseHover += delegate { mouseHoverFired = true; }; - Application.DoEvents(); + _textBox.SimulateMouseMove(new Point(0, 0)); - MoveMouseSoNotOverHotSpot(); - Hover(); + _textBox.SimulateMouseHover(); Assert.IsFalse(mouseHoverFired); } [Test] public void HotSpotMouseDown_MouseDownOverHotSpot_FiresMouseDown() { - bool mouseDownFired = false; + var mouseDownFired = false; _spot1.MouseDown += delegate { mouseDownFired = true; }; - Application.DoEvents(); - - MoveMouseSoOverHotSpot(_spot1); + _spot1.SimulateMouseMove(); - MouseDown(); + _spot1.SimulateMouseDown(); Assert.IsTrue(mouseDownFired); } - [Test] - public void HotSpotMouseDown_MouseDownNotOverHotSpot_DoesNotFireMouseDown() - { - bool mouseDownFired = false; - _spot1.MouseDown += delegate { mouseDownFired = true; }; - - Application.DoEvents(); - - MoveMouseSoNotOverHotSpot(); - MouseDown(); - Assert.IsFalse(mouseDownFired); - } - [Test] public void HotSpotMouseClick_MouseClickOverHotSpot_FiresMouseClick() { - bool mouseClickFired = false; + var mouseClickFired = false; _spot1.MouseClick += delegate { mouseClickFired = true; }; - Application.DoEvents(); + _spot1.SimulateMouseMove(); - MoveMouseSoOverHotSpot(_spot1); - MouseClick(); + _spot1.SimulateMouseClick(); Assert.IsTrue(mouseClickFired); } - [Test] - public void HotSpotMouseClick_MouseClickNotOverHotSpot_DoesNotFireMouseClick() - { - bool mouseClickFired = false; - _spot1.MouseClick += delegate { mouseClickFired = true; }; - - Application.DoEvents(); - - MoveMouseSoNotOverHotSpot(); - MouseClick(); - Assert.IsFalse(mouseClickFired); - } - [Test] public void HotSpotMouseUp_MouseUpOverHotSpot_FiresMouseUp() { - bool mouseUpFired = false; + var mouseUpFired = false; _spot1.MouseUp += delegate { mouseUpFired = true; }; - Application.DoEvents(); + // Get the position of the hotspot + var hotSpotPosition = _textBox.GetPositionFromCharIndex(_spot1.Offset); + + // Simulate moving the mouse over the hot spot + _textBox.SimulateMouseMove(hotSpotPosition.X, hotSpotPosition.Y); - MoveMouseSoOverHotSpot(_spot1); - MouseUp(); + // Simulate mouse up event + _textBox.SimulateMouseUp(hotSpotPosition.X, hotSpotPosition.Y); + + // Verify that the MouseUp event was fired Assert.IsTrue(mouseUpFired); } @@ -329,86 +215,9 @@ public void HotSpotMouseUp_MouseUpNotOverHotSpot_DoesNotFireMouseUp() bool mouseUpFired = false; _spot1.MouseUp += delegate { mouseUpFired = true; }; - Application.DoEvents(); - - MoveMouseSoNotOverHotSpot(); - MouseUp(); + _textBox.SimulateMouseMove(0, 0); + _textBox.SimulateMouseUp(0, 0); Assert.IsFalse(mouseUpFired); } - - private void MouseDown() - { - Point position = _textBox.PointToClient(Cursor.Position); - _textBox.OnMouseDown(new MouseEventArgs(MouseButtons.Left, 1, - position.X, - position.Y, - 0)); - Application.DoEvents(); - } - - private void MouseUp() - { - Point position = _textBox.PointToClient(Cursor.Position); - _textBox.OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, - position.X, - position.Y, - 0)); - Application.DoEvents(); - } - - - private void MouseClick() - { - Point position = _textBox.PointToClient(Cursor.Position); - _textBox.OnMouseClick(new MouseEventArgs(MouseButtons.Left, 1, - position.X, - position.Y, - 0)); - Application.DoEvents(); - } - - - private static void Hover() - { - Thread.Sleep(SystemInformation.MouseHoverTime); - Thread.Sleep(100); - Application.DoEvents(); - } - - - private void MoveMouseSoNotOverHotSpot() - { - MoveMouseToPositionAtCharIndex(0); - Application.DoEvents(); - } - - private void MoveMouseSoOverHotSpot(HotSpot.HotSpot hotSpot) - { - MoveMouseToPositionAtCharIndex(hotSpot.Offset); - Application.DoEvents(); - } - - private void MoveMouseOffControl() - { - // mouse off control - // (to get the _textBox's OnMouseLeave to fire, we have to put the mouse in the non-client area of the control) - Cursor.Position = _form.PointToScreen(_textBox.Location); - Application.DoEvents(); - } - - private void MoveMouseToPositionAtCharIndex(int offset) - { - Point position = GetPositionFromCharIndex(_textBox, offset); - Cursor.Position = _textBox.PointToScreen(position); - } - - private static Point GetPositionFromCharIndex(TextBoxBase textBox, int offset) - { - Point position = textBox.GetPositionFromCharIndex(offset); - // the following is necessary to work around a .Net bug - int x = (Int16) position.X; - int y = (Int16) position.Y; - return new Point(x, y); - } } } \ No newline at end of file diff --git a/SIL.Windows.Forms.Tests/Hotspot/MouseSimulator.cs b/SIL.Windows.Forms.Tests/Hotspot/MouseSimulator.cs new file mode 100644 index 000000000..0b69ff430 --- /dev/null +++ b/SIL.Windows.Forms.Tests/Hotspot/MouseSimulator.cs @@ -0,0 +1,95 @@ +using System; +using System.Drawing; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using SIL.Reflection; +using SIL.Windows.Forms.HotSpot; + +public static class MouseSimulator +{ + private const int WM_LBUTTONDOWN = 0x0201; + private const int WM_LBUTTONUP = 0x0202; + private const int WM_MOUSEMOVE = 0x0200; + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); + + public static void SimulateMouseDown(this HotSpot hotspot) + { + hotspot.Control.SimulateMouseDown(GetPositionFromCharIndex(hotspot.Control, hotspot.Offset)); + } + + public static void SimulateMouseDown(this Control control, Point pt) + { + control.SimulateMouseDown(pt.X, pt.Y); + } + + public static void SimulateMouseDown(this Control control, int x, int y) + { + SendMessage(control.Handle, WM_LBUTTONDOWN, IntPtr.Zero, MakeLParam(x, y)); + } + + public static void SimulateMouseUp(this HotSpot hotspot) + { + hotspot.Control.SimulateMouseUp(GetPositionFromCharIndex(hotspot.Control, hotspot.Offset)); + } + + public static void SimulateMouseUp(this Control control, Point pt) + { + control.SimulateMouseUp(pt.X, pt.Y); + } + + public static void SimulateMouseUp(this Control control, int x, int y) + { + SendMessage(control.Handle, WM_LBUTTONUP, IntPtr.Zero, MakeLParam(x, y)); + } + + public static void SimulateMouseClick(this HotSpot hotspot) + { + hotspot.Control.SimulateMouseClick(GetPositionFromCharIndex(hotspot.Control, hotspot.Offset)); + } + + public static void SimulateMouseClick(this Control control, Point pt) + { + control.SimulateMouseClick(pt.X, pt.Y); + } + + public static void SimulateMouseClick(this Control control, int x, int y) + { + SimulateMouseDown(control, x, y); + SimulateMouseUp(control, x, y); + } + + public static void SimulateMouseMove(this HotSpot hotspot) + { + hotspot.Control.SimulateMouseMove(GetPositionFromCharIndex(hotspot.Control, hotspot.Offset)); + } + + public static void SimulateMouseMove(this Control control, Point pt) + { + control.SimulateMouseMove(pt.X, pt.Y); + } + + public static void SimulateMouseMove(this Control control, int x, int y) + { + SendMessage(control.Handle, WM_MOUSEMOVE, IntPtr.Zero, MakeLParam(x, y)); + } + public static void SimulateMouseHover(this Control control) + { + ReflectionHelper.CallMethod(control, "OnMouseHover", EventArgs.Empty); + } + + private static IntPtr MakeLParam(int x, int y) + { + return (IntPtr)((y << 16) | (x & 0xFFFF)); + } + + private static Point GetPositionFromCharIndex(this TextBoxBase textBox, int offset) + { + var position = textBox.GetPositionFromCharIndex(offset); + // the following is necessary to work around a .Net bug + int x = (short)position.X; + int y = (short)position.Y; + return new Point(x, y); + } +} \ No newline at end of file diff --git a/SIL.Windows.Forms.Tests/Miscellaneous/PortableClipboardTests.cs b/SIL.Windows.Forms.Tests/Miscellaneous/PortableClipboardTests.cs index ece1f27bb..0154ace67 100644 --- a/SIL.Windows.Forms.Tests/Miscellaneous/PortableClipboardTests.cs +++ b/SIL.Windows.Forms.Tests/Miscellaneous/PortableClipboardTests.cs @@ -3,6 +3,7 @@ using SIL.Windows.Forms.ImageToolbox; using SIL.Windows.Forms.Miscellaneous; using NUnit.Framework; +using System; namespace SIL.Windows.Forms.Tests.Miscellaneous {