From 20411aaf7ef4e8966acff94ebb5a5b81714ac9f1 Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Sun, 5 Jan 2014 01:51:14 -0800 Subject: [PATCH 01/16] Add UIItem hightlighting. --- .../Drawing/ScreenRectangle.cs | 69 +++++++++++++++++++ src/TestStack.White/UIItems/UIItem.cs | 15 ++++ .../WindowsAPI/NativeWindow.cs | 14 ++++ 3 files changed, 98 insertions(+) create mode 100644 src/TestStack.White/Drawing/ScreenRectangle.cs diff --git a/src/TestStack.White/Drawing/ScreenRectangle.cs b/src/TestStack.White/Drawing/ScreenRectangle.cs new file mode 100644 index 00000000..0255fe8e --- /dev/null +++ b/src/TestStack.White/Drawing/ScreenRectangle.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows; +using System.Windows.Forms; + +namespace TestStack.White.Drawing +{ + internal class ScreenRectangle + { + Form form = new Form(); + internal ScreenRectangle(Rect rectangle) + { + form.FormBorderStyle = FormBorderStyle.None; + form.ShowInTaskbar = false; + form.TopMost = true; + form.Left = 0; + form.Top = 0; + form.Width = 1; + form.Height = 1; + form.BackColor = Color.Red; + form.Opacity = 0.8; + form.Visible = true; + + //Set popup style + int num1 = TestStack.White.WindowsAPI.NativeWindow.GetWindowLong(form.Handle, -20); + TestStack.White.WindowsAPI.NativeWindow.SetWindowLong(form.Handle, -20, num1 | 0x80); + + TestStack.White.WindowsAPI.NativeWindow.SetWindowPos(form.Handle, new IntPtr(-1), Convert.ToInt32(rectangle.X), Convert.ToInt32(rectangle.Y), + Convert.ToInt32(rectangle.Width), Convert.ToInt32(rectangle.Height), 0x10); + } + public void Show() + { + TestStack.White.WindowsAPI.NativeWindow.ShowWindow(form.Handle, 8); + } + public void Hide() + { + form.Hide(); + } + } + + internal class FrameRectangle + { + private ScreenRectangle leftRectangle; + private ScreenRectangle topRectangle; + private ScreenRectangle rightRectangle; + private ScreenRectangle bottomRectangle; + private ScreenRectangle[] rectangles; + private int width = 3; + + public FrameRectangle(Rect boundingRectangle) + { + leftRectangle = new ScreenRectangle(new Rect(boundingRectangle.X - width, boundingRectangle.Y - width, width, boundingRectangle.Height + 2*width)); + topRectangle = new ScreenRectangle(new Rect(boundingRectangle.X, boundingRectangle.Y - width, boundingRectangle.Width, width)); + rightRectangle = new ScreenRectangle(new Rect(boundingRectangle.X + boundingRectangle.Width, boundingRectangle.Y - width, width, boundingRectangle.Height + 2*width)); + bottomRectangle = new ScreenRectangle(new Rect(boundingRectangle.X, boundingRectangle.Y + boundingRectangle.Height, boundingRectangle.Width, width)); + rectangles = new ScreenRectangle[] { leftRectangle, topRectangle, rightRectangle, bottomRectangle }; + } + public void Highlight() + { + rectangles.ToList().ForEach(x => x.Show()); + Thread.Sleep(1000); + rectangles.ToList().ForEach(x => x.Hide()); + } + } +} diff --git a/src/TestStack.White/UIItems/UIItem.cs b/src/TestStack.White/UIItems/UIItem.cs index 2a974fff..c3a86cdb 100644 --- a/src/TestStack.White/UIItems/UIItem.cs +++ b/src/TestStack.White/UIItems/UIItem.cs @@ -20,6 +20,8 @@ using TestStack.White.WindowsAPI; using Action = TestStack.White.UIItems.Actions.Action; using Point = System.Windows.Point; +using System.Runtime.InteropServices; +using System.Windows.Forms; namespace TestStack.White.UIItems { @@ -424,5 +426,18 @@ public virtual void RaiseClickEvent() var invokePattern = (InvokePattern) Pattern(InvokePattern.Pattern); if (invokePattern != null) invokePattern.Invoke(); } + + /// + /// Highlight UIItem with the red frame for 1 second + /// + public void DrawHighlight() + { + Rect rectangle = this.AutomationElement.Current.BoundingRectangle; + + if (rectangle != Rect.Empty) + { + new Drawing.FrameRectangle(rectangle).Highlight(); + } + } } } \ No newline at end of file diff --git a/src/TestStack.White/WindowsAPI/NativeWindow.cs b/src/TestStack.White/WindowsAPI/NativeWindow.cs index f8ce0006..4f8a96a8 100644 --- a/src/TestStack.White/WindowsAPI/NativeWindow.cs +++ b/src/TestStack.White/WindowsAPI/NativeWindow.cs @@ -45,5 +45,19 @@ public virtual COLORREF TextColor return GetTextColor(GetDC(handle)); } } + + //Native methods needed for highlighting UIItems + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + internal static extern bool SetWindowPos(IntPtr hWnd, IntPtr hwndAfter, int x, int y, int width, int height, int flags); + [return: MarshalAs(UnmanagedType.Bool)] + + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + internal static extern int GetWindowLong(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); } } From 5abb2412c469648b5795720f598db644ecfa72c3 Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Sun, 5 Jan 2014 06:39:11 -0800 Subject: [PATCH 02/16] Add HighlightTimeout to configuration --- .../Configuration/CoreAppXmlConfiguration.cs | 7 ++++ .../Configuration/CoreConfiguration.cs | 1 + .../Drawing/ScreenRectangle.cs | 42 ++++++++++++------- src/TestStack.White/TestStack.White.csproj | 1 + src/TestStack.White/UIItems/UIItem.cs | 2 +- .../WindowsAPI/NativeWindow.cs | 1 - 6 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/TestStack.White/Configuration/CoreAppXmlConfiguration.cs b/src/TestStack.White/Configuration/CoreAppXmlConfiguration.cs index d69d45d5..738b3d50 100644 --- a/src/TestStack.White/Configuration/CoreAppXmlConfiguration.cs +++ b/src/TestStack.White/Configuration/CoreAppXmlConfiguration.cs @@ -26,6 +26,7 @@ static CoreAppXmlConfiguration() DefaultValues.Add("PopupTimeout", 5000); DefaultValues.Add("TooltipWaitTime", 3000); DefaultValues.Add("SuggestionListTimeout", 3000); + DefaultValues.Add("HighlightTimeout", 1000); DefaultValues.Add("DefaultDateFormat", DateFormat.CultureDefault.ToString()); DefaultValues.Add("DragStepCount", 1); DefaultValues.Add("InProc", false); @@ -108,6 +109,12 @@ public virtual int SuggestionListTimeout set { SetUsedValue("SuggestionListTimeout", value); } } + public virtual int HighlightTimeout + { + get { return Convert.ToInt32(UsedValues["HighlightTimeout"]); } + set { SetUsedValue("HighlightTimeout", value); } + } + public virtual DateFormat DefaultDateFormat { get { return DateFormat.Parse(UsedValues["DefaultDateFormat"]); } diff --git a/src/TestStack.White/Configuration/CoreConfiguration.cs b/src/TestStack.White/Configuration/CoreConfiguration.cs index 17d99e11..0b29c2d1 100644 --- a/src/TestStack.White/Configuration/CoreConfiguration.cs +++ b/src/TestStack.White/Configuration/CoreConfiguration.cs @@ -23,6 +23,7 @@ public interface ICoreConfiguration int PopupTimeout { get; set; } int TooltipWaitTime { get; set; } int SuggestionListTimeout { get; set; } + int HighlightTimeout { get; set; } DateFormat DefaultDateFormat { get; set; } int DragStepCount { get; set; } bool InProc { get; set; } diff --git a/src/TestStack.White/Drawing/ScreenRectangle.cs b/src/TestStack.White/Drawing/ScreenRectangle.cs index 0255fe8e..f702a0b3 100644 --- a/src/TestStack.White/Drawing/ScreenRectangle.cs +++ b/src/TestStack.White/Drawing/ScreenRectangle.cs @@ -6,12 +6,16 @@ using System.Threading; using System.Windows; using System.Windows.Forms; +using TestStack.White.Configuration; namespace TestStack.White.Drawing { internal class ScreenRectangle { - Form form = new Form(); + private Form form = new Form(); + //TODO: Think about making color configurable + private Color Color = Color.Red; + internal ScreenRectangle(Rect rectangle) { form.FormBorderStyle = FormBorderStyle.None; @@ -21,7 +25,7 @@ internal ScreenRectangle(Rect rectangle) form.Top = 0; form.Width = 1; form.Height = 1; - form.BackColor = Color.Red; + form.BackColor = this.Color; form.Opacity = 0.8; form.Visible = true; @@ -29,14 +33,17 @@ internal ScreenRectangle(Rect rectangle) int num1 = TestStack.White.WindowsAPI.NativeWindow.GetWindowLong(form.Handle, -20); TestStack.White.WindowsAPI.NativeWindow.SetWindowLong(form.Handle, -20, num1 | 0x80); + //Set position TestStack.White.WindowsAPI.NativeWindow.SetWindowPos(form.Handle, new IntPtr(-1), Convert.ToInt32(rectangle.X), Convert.ToInt32(rectangle.Y), Convert.ToInt32(rectangle.Width), Convert.ToInt32(rectangle.Height), 0x10); } - public void Show() + + internal void Show() { TestStack.White.WindowsAPI.NativeWindow.ShowWindow(form.Handle, 8); } - public void Hide() + + internal void Hide() { form.Hide(); } @@ -44,25 +51,28 @@ public void Hide() internal class FrameRectangle { - private ScreenRectangle leftRectangle; - private ScreenRectangle topRectangle; - private ScreenRectangle rightRectangle; - private ScreenRectangle bottomRectangle; + //Using 4 rectangles to display each border + private ScreenRectangle leftBorder; + private ScreenRectangle topBorder; + private ScreenRectangle rightBorder; + private ScreenRectangle bottomBorder; + private ScreenRectangle[] rectangles; private int width = 3; - public FrameRectangle(Rect boundingRectangle) + internal FrameRectangle(Rect boundingRectangle) { - leftRectangle = new ScreenRectangle(new Rect(boundingRectangle.X - width, boundingRectangle.Y - width, width, boundingRectangle.Height + 2*width)); - topRectangle = new ScreenRectangle(new Rect(boundingRectangle.X, boundingRectangle.Y - width, boundingRectangle.Width, width)); - rightRectangle = new ScreenRectangle(new Rect(boundingRectangle.X + boundingRectangle.Width, boundingRectangle.Y - width, width, boundingRectangle.Height + 2*width)); - bottomRectangle = new ScreenRectangle(new Rect(boundingRectangle.X, boundingRectangle.Y + boundingRectangle.Height, boundingRectangle.Width, width)); - rectangles = new ScreenRectangle[] { leftRectangle, topRectangle, rightRectangle, bottomRectangle }; + leftBorder = new ScreenRectangle(new Rect(boundingRectangle.X - width, boundingRectangle.Y - width, width, boundingRectangle.Height + 2*width)); + topBorder = new ScreenRectangle(new Rect(boundingRectangle.X, boundingRectangle.Y - width, boundingRectangle.Width, width)); + rightBorder = new ScreenRectangle(new Rect(boundingRectangle.X + boundingRectangle.Width, boundingRectangle.Y - width, width, boundingRectangle.Height + 2*width)); + bottomBorder = new ScreenRectangle(new Rect(boundingRectangle.X, boundingRectangle.Y + boundingRectangle.Height, boundingRectangle.Width, width)); + rectangles = new ScreenRectangle[] { leftBorder, topBorder, rightBorder, bottomBorder }; } - public void Highlight() + + internal void Highlight() { rectangles.ToList().ForEach(x => x.Show()); - Thread.Sleep(1000); + Thread.Sleep(CoreAppXmlConfiguration.Instance.HighlightTimeout); rectangles.ToList().ForEach(x => x.Hide()); } } diff --git a/src/TestStack.White/TestStack.White.csproj b/src/TestStack.White/TestStack.White.csproj index d001a9a5..8f3054b3 100644 --- a/src/TestStack.White/TestStack.White.csproj +++ b/src/TestStack.White/TestStack.White.csproj @@ -92,6 +92,7 @@ + diff --git a/src/TestStack.White/UIItems/UIItem.cs b/src/TestStack.White/UIItems/UIItem.cs index c3a86cdb..488b8d63 100644 --- a/src/TestStack.White/UIItems/UIItem.cs +++ b/src/TestStack.White/UIItems/UIItem.cs @@ -428,7 +428,7 @@ public virtual void RaiseClickEvent() } /// - /// Highlight UIItem with the red frame for 1 second + /// Highlight UIItem with red frame /// public void DrawHighlight() { diff --git a/src/TestStack.White/WindowsAPI/NativeWindow.cs b/src/TestStack.White/WindowsAPI/NativeWindow.cs index 4f8a96a8..94933557 100644 --- a/src/TestStack.White/WindowsAPI/NativeWindow.cs +++ b/src/TestStack.White/WindowsAPI/NativeWindow.cs @@ -46,7 +46,6 @@ public virtual COLORREF TextColor } } - //Native methods needed for highlighting UIItems [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] internal static extern bool SetWindowPos(IntPtr hWnd, IntPtr hwndAfter, int x, int y, int width, int height, int flags); [return: MarshalAs(UnmanagedType.Bool)] From 9dbc756737d793d3501478bc9bc93b2745a9bd95 Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Sun, 5 Jan 2014 06:42:44 -0800 Subject: [PATCH 03/16] Remove unused directive. --- src/TestStack.White/UIItems/UIItem.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/TestStack.White/UIItems/UIItem.cs b/src/TestStack.White/UIItems/UIItem.cs index 488b8d63..ddfeb1f4 100644 --- a/src/TestStack.White/UIItems/UIItem.cs +++ b/src/TestStack.White/UIItems/UIItem.cs @@ -20,7 +20,6 @@ using TestStack.White.WindowsAPI; using Action = TestStack.White.UIItems.Actions.Action; using Point = System.Windows.Point; -using System.Runtime.InteropServices; using System.Windows.Forms; namespace TestStack.White.UIItems From 4d6b92c3f58b34c575d2f9f30f4296ff4022233a Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Sun, 5 Jan 2014 07:38:36 -0800 Subject: [PATCH 04/16] Made all methods virtual. --- src/TestStack.White/Drawing/ScreenRectangle.cs | 6 +++--- src/TestStack.White/UIItems/UIItem.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/TestStack.White/Drawing/ScreenRectangle.cs b/src/TestStack.White/Drawing/ScreenRectangle.cs index f702a0b3..0ad96a6f 100644 --- a/src/TestStack.White/Drawing/ScreenRectangle.cs +++ b/src/TestStack.White/Drawing/ScreenRectangle.cs @@ -38,12 +38,12 @@ internal ScreenRectangle(Rect rectangle) Convert.ToInt32(rectangle.Width), Convert.ToInt32(rectangle.Height), 0x10); } - internal void Show() + internal virtual void Show() { TestStack.White.WindowsAPI.NativeWindow.ShowWindow(form.Handle, 8); } - internal void Hide() + internal virtual void Hide() { form.Hide(); } @@ -69,7 +69,7 @@ internal FrameRectangle(Rect boundingRectangle) rectangles = new ScreenRectangle[] { leftBorder, topBorder, rightBorder, bottomBorder }; } - internal void Highlight() + internal virtual void Highlight() { rectangles.ToList().ForEach(x => x.Show()); Thread.Sleep(CoreAppXmlConfiguration.Instance.HighlightTimeout); diff --git a/src/TestStack.White/UIItems/UIItem.cs b/src/TestStack.White/UIItems/UIItem.cs index ddfeb1f4..b4c45795 100644 --- a/src/TestStack.White/UIItems/UIItem.cs +++ b/src/TestStack.White/UIItems/UIItem.cs @@ -429,7 +429,7 @@ public virtual void RaiseClickEvent() /// /// Highlight UIItem with red frame /// - public void DrawHighlight() + public virtual void DrawHighlight() { Rect rectangle = this.AutomationElement.Current.BoundingRectangle; From 0413bf2aa5c9aa5abd5995ba34a3fed1733ca97f Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Tue, 7 Jan 2014 05:22:11 -0800 Subject: [PATCH 05/16] Add DrawHighlight to IUIItem. --- src/TestStack.White/UIItems/IUIItem.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/TestStack.White/UIItems/IUIItem.cs b/src/TestStack.White/UIItems/IUIItem.cs index 73b3edee..d1632e21 100644 --- a/src/TestStack.White/UIItems/IUIItem.cs +++ b/src/TestStack.White/UIItems/IUIItem.cs @@ -94,5 +94,7 @@ public interface IUIItem : ActionListener AutomationElement GetElement(SearchCriteria searchCriteria); void Enter(string value); + + void DrawHighlight(); } } \ No newline at end of file From 2761ad20b032605d38b1b6fab6e46ff7d50183fa Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Wed, 8 Jan 2014 02:16:30 -0800 Subject: [PATCH 06/16] Small improvement. --- src/TestStack.White/Drawing/ScreenRectangle.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TestStack.White/Drawing/ScreenRectangle.cs b/src/TestStack.White/Drawing/ScreenRectangle.cs index 0ad96a6f..2e6d4e37 100644 --- a/src/TestStack.White/Drawing/ScreenRectangle.cs +++ b/src/TestStack.White/Drawing/ScreenRectangle.cs @@ -27,7 +27,7 @@ internal ScreenRectangle(Rect rectangle) form.Height = 1; form.BackColor = this.Color; form.Opacity = 0.8; - form.Visible = true; + form.Visible = false; //Set popup style int num1 = TestStack.White.WindowsAPI.NativeWindow.GetWindowLong(form.Handle, -20); From 03b3e7464aa9951cd63319ef7aa7053a997e9e05 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Sun, 9 Feb 2014 14:19:00 +0000 Subject: [PATCH 07/16] Hopefully fixing issue #165 --- .../UIItems/WindowItems/Win32Window.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/TestStack.White/UIItems/WindowItems/Win32Window.cs b/src/TestStack.White/UIItems/WindowItems/Win32Window.cs index 406b2807..feb8d73a 100644 --- a/src/TestStack.White/UIItems/WindowItems/Win32Window.cs +++ b/src/TestStack.White/UIItems/WindowItems/Win32Window.cs @@ -1,5 +1,8 @@ +using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Windows.Automation; +using TestStack.White.AutomationElementSearch; using TestStack.White.Factory; using TestStack.White.Sessions; using TestStack.White.UIItems.Finders; @@ -36,6 +39,16 @@ public override Window ModalWindow(string title, InitializeOption option) WindowSession.ModalWindowSession(option)); } + public override List ModalWindows() + { + var descendants = new AutomationElementFinder(automationElement) + .Children(new AutomationSearchConditionFactory().GetWindowSearchConditions(automationElement.Current.ProcessId).ToArray()); + + return descendants + .Select(descendant => ChildWindowFactory.Create(descendant, InitializeOption.NoCache, WindowSession.ModalWindowSession(InitializeOption.NoCache))) + .ToList(); + } + public override Window ModalWindow(SearchCriteria searchCriteria, InitializeOption option) { return windowFactory.ModalWindow(searchCriteria, option, WindowSession.ModalWindowSession(option)); From 92d304929e2c48881c68049b5058759c330028e7 Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Sun, 16 Feb 2014 06:51:11 -0800 Subject: [PATCH 08/16] Moved highlighting to different thread --- src/TestStack.White/UIItems/UIItem.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/TestStack.White/UIItems/UIItem.cs b/src/TestStack.White/UIItems/UIItem.cs index b4c45795..14f09fb0 100644 --- a/src/TestStack.White/UIItems/UIItem.cs +++ b/src/TestStack.White/UIItems/UIItem.cs @@ -431,12 +431,15 @@ public virtual void RaiseClickEvent() /// public virtual void DrawHighlight() { - Rect rectangle = this.AutomationElement.Current.BoundingRectangle; + new Thread(() => + { + Rect rectangle = this.AutomationElement.Current.BoundingRectangle; - if (rectangle != Rect.Empty) - { - new Drawing.FrameRectangle(rectangle).Highlight(); - } + if (rectangle != Rect.Empty) + { + new Drawing.FrameRectangle(rectangle).Highlight(); + } + }).Start(); } } } \ No newline at end of file From 2f90e38df6d88f70950d175e88753c710e74b4dc Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Sun, 5 Jan 2014 01:51:14 -0800 Subject: [PATCH 09/16] Add UIItem hightlighting. Conflicts: src/TestStack.White/WindowsAPI/NativeWindow.cs --- .../Drawing/ScreenRectangle.cs | 69 +++++++++++++++++++ src/TestStack.White/UIItems/UIItem.cs | 15 ++++ .../WindowsAPI/NativeWindow.cs | 14 ++++ 3 files changed, 98 insertions(+) create mode 100644 src/TestStack.White/Drawing/ScreenRectangle.cs diff --git a/src/TestStack.White/Drawing/ScreenRectangle.cs b/src/TestStack.White/Drawing/ScreenRectangle.cs new file mode 100644 index 00000000..0255fe8e --- /dev/null +++ b/src/TestStack.White/Drawing/ScreenRectangle.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows; +using System.Windows.Forms; + +namespace TestStack.White.Drawing +{ + internal class ScreenRectangle + { + Form form = new Form(); + internal ScreenRectangle(Rect rectangle) + { + form.FormBorderStyle = FormBorderStyle.None; + form.ShowInTaskbar = false; + form.TopMost = true; + form.Left = 0; + form.Top = 0; + form.Width = 1; + form.Height = 1; + form.BackColor = Color.Red; + form.Opacity = 0.8; + form.Visible = true; + + //Set popup style + int num1 = TestStack.White.WindowsAPI.NativeWindow.GetWindowLong(form.Handle, -20); + TestStack.White.WindowsAPI.NativeWindow.SetWindowLong(form.Handle, -20, num1 | 0x80); + + TestStack.White.WindowsAPI.NativeWindow.SetWindowPos(form.Handle, new IntPtr(-1), Convert.ToInt32(rectangle.X), Convert.ToInt32(rectangle.Y), + Convert.ToInt32(rectangle.Width), Convert.ToInt32(rectangle.Height), 0x10); + } + public void Show() + { + TestStack.White.WindowsAPI.NativeWindow.ShowWindow(form.Handle, 8); + } + public void Hide() + { + form.Hide(); + } + } + + internal class FrameRectangle + { + private ScreenRectangle leftRectangle; + private ScreenRectangle topRectangle; + private ScreenRectangle rightRectangle; + private ScreenRectangle bottomRectangle; + private ScreenRectangle[] rectangles; + private int width = 3; + + public FrameRectangle(Rect boundingRectangle) + { + leftRectangle = new ScreenRectangle(new Rect(boundingRectangle.X - width, boundingRectangle.Y - width, width, boundingRectangle.Height + 2*width)); + topRectangle = new ScreenRectangle(new Rect(boundingRectangle.X, boundingRectangle.Y - width, boundingRectangle.Width, width)); + rightRectangle = new ScreenRectangle(new Rect(boundingRectangle.X + boundingRectangle.Width, boundingRectangle.Y - width, width, boundingRectangle.Height + 2*width)); + bottomRectangle = new ScreenRectangle(new Rect(boundingRectangle.X, boundingRectangle.Y + boundingRectangle.Height, boundingRectangle.Width, width)); + rectangles = new ScreenRectangle[] { leftRectangle, topRectangle, rightRectangle, bottomRectangle }; + } + public void Highlight() + { + rectangles.ToList().ForEach(x => x.Show()); + Thread.Sleep(1000); + rectangles.ToList().ForEach(x => x.Hide()); + } + } +} diff --git a/src/TestStack.White/UIItems/UIItem.cs b/src/TestStack.White/UIItems/UIItem.cs index 36efd431..02c96beb 100644 --- a/src/TestStack.White/UIItems/UIItem.cs +++ b/src/TestStack.White/UIItems/UIItem.cs @@ -20,6 +20,8 @@ using TestStack.White.WindowsAPI; using Action = TestStack.White.UIItems.Actions.Action; using Point = System.Windows.Point; +using System.Runtime.InteropServices; +using System.Windows.Forms; namespace TestStack.White.UIItems { @@ -424,5 +426,18 @@ public virtual void RaiseClickEvent() var invokePattern = (InvokePattern)Pattern(InvokePattern.Pattern); if (invokePattern != null) invokePattern.Invoke(); } + + /// + /// Highlight UIItem with the red frame for 1 second + /// + public void DrawHighlight() + { + Rect rectangle = this.AutomationElement.Current.BoundingRectangle; + + if (rectangle != Rect.Empty) + { + new Drawing.FrameRectangle(rectangle).Highlight(); + } + } } } \ No newline at end of file diff --git a/src/TestStack.White/WindowsAPI/NativeWindow.cs b/src/TestStack.White/WindowsAPI/NativeWindow.cs index acf44b78..a2b855c2 100644 --- a/src/TestStack.White/WindowsAPI/NativeWindow.cs +++ b/src/TestStack.White/WindowsAPI/NativeWindow.cs @@ -88,5 +88,19 @@ public virtual void PostCloseMessage() { PostMessage(handle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); } + + //Native methods needed for highlighting UIItems + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + internal static extern bool SetWindowPos(IntPtr hWnd, IntPtr hwndAfter, int x, int y, int width, int height, int flags); + [return: MarshalAs(UnmanagedType.Bool)] + + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + internal static extern int GetWindowLong(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); } } \ No newline at end of file From 1e25f92254f194a436cfb18bb90429c151b8ab76 Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Sun, 5 Jan 2014 06:39:11 -0800 Subject: [PATCH 10/16] Add HighlightTimeout to configuration Conflicts: src/TestStack.White/WindowsAPI/NativeWindow.cs --- .../Configuration/CoreAppXmlConfiguration.cs | 7 ++++ .../Configuration/CoreConfiguration.cs | 1 + .../Drawing/ScreenRectangle.cs | 42 ++++++++++++------- src/TestStack.White/TestStack.White.csproj | 1 + src/TestStack.White/UIItems/UIItem.cs | 2 +- .../WindowsAPI/NativeWindow.cs | 2 +- 6 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/TestStack.White/Configuration/CoreAppXmlConfiguration.cs b/src/TestStack.White/Configuration/CoreAppXmlConfiguration.cs index d69d45d5..738b3d50 100644 --- a/src/TestStack.White/Configuration/CoreAppXmlConfiguration.cs +++ b/src/TestStack.White/Configuration/CoreAppXmlConfiguration.cs @@ -26,6 +26,7 @@ static CoreAppXmlConfiguration() DefaultValues.Add("PopupTimeout", 5000); DefaultValues.Add("TooltipWaitTime", 3000); DefaultValues.Add("SuggestionListTimeout", 3000); + DefaultValues.Add("HighlightTimeout", 1000); DefaultValues.Add("DefaultDateFormat", DateFormat.CultureDefault.ToString()); DefaultValues.Add("DragStepCount", 1); DefaultValues.Add("InProc", false); @@ -108,6 +109,12 @@ public virtual int SuggestionListTimeout set { SetUsedValue("SuggestionListTimeout", value); } } + public virtual int HighlightTimeout + { + get { return Convert.ToInt32(UsedValues["HighlightTimeout"]); } + set { SetUsedValue("HighlightTimeout", value); } + } + public virtual DateFormat DefaultDateFormat { get { return DateFormat.Parse(UsedValues["DefaultDateFormat"]); } diff --git a/src/TestStack.White/Configuration/CoreConfiguration.cs b/src/TestStack.White/Configuration/CoreConfiguration.cs index 17d99e11..0b29c2d1 100644 --- a/src/TestStack.White/Configuration/CoreConfiguration.cs +++ b/src/TestStack.White/Configuration/CoreConfiguration.cs @@ -23,6 +23,7 @@ public interface ICoreConfiguration int PopupTimeout { get; set; } int TooltipWaitTime { get; set; } int SuggestionListTimeout { get; set; } + int HighlightTimeout { get; set; } DateFormat DefaultDateFormat { get; set; } int DragStepCount { get; set; } bool InProc { get; set; } diff --git a/src/TestStack.White/Drawing/ScreenRectangle.cs b/src/TestStack.White/Drawing/ScreenRectangle.cs index 0255fe8e..f702a0b3 100644 --- a/src/TestStack.White/Drawing/ScreenRectangle.cs +++ b/src/TestStack.White/Drawing/ScreenRectangle.cs @@ -6,12 +6,16 @@ using System.Threading; using System.Windows; using System.Windows.Forms; +using TestStack.White.Configuration; namespace TestStack.White.Drawing { internal class ScreenRectangle { - Form form = new Form(); + private Form form = new Form(); + //TODO: Think about making color configurable + private Color Color = Color.Red; + internal ScreenRectangle(Rect rectangle) { form.FormBorderStyle = FormBorderStyle.None; @@ -21,7 +25,7 @@ internal ScreenRectangle(Rect rectangle) form.Top = 0; form.Width = 1; form.Height = 1; - form.BackColor = Color.Red; + form.BackColor = this.Color; form.Opacity = 0.8; form.Visible = true; @@ -29,14 +33,17 @@ internal ScreenRectangle(Rect rectangle) int num1 = TestStack.White.WindowsAPI.NativeWindow.GetWindowLong(form.Handle, -20); TestStack.White.WindowsAPI.NativeWindow.SetWindowLong(form.Handle, -20, num1 | 0x80); + //Set position TestStack.White.WindowsAPI.NativeWindow.SetWindowPos(form.Handle, new IntPtr(-1), Convert.ToInt32(rectangle.X), Convert.ToInt32(rectangle.Y), Convert.ToInt32(rectangle.Width), Convert.ToInt32(rectangle.Height), 0x10); } - public void Show() + + internal void Show() { TestStack.White.WindowsAPI.NativeWindow.ShowWindow(form.Handle, 8); } - public void Hide() + + internal void Hide() { form.Hide(); } @@ -44,25 +51,28 @@ public void Hide() internal class FrameRectangle { - private ScreenRectangle leftRectangle; - private ScreenRectangle topRectangle; - private ScreenRectangle rightRectangle; - private ScreenRectangle bottomRectangle; + //Using 4 rectangles to display each border + private ScreenRectangle leftBorder; + private ScreenRectangle topBorder; + private ScreenRectangle rightBorder; + private ScreenRectangle bottomBorder; + private ScreenRectangle[] rectangles; private int width = 3; - public FrameRectangle(Rect boundingRectangle) + internal FrameRectangle(Rect boundingRectangle) { - leftRectangle = new ScreenRectangle(new Rect(boundingRectangle.X - width, boundingRectangle.Y - width, width, boundingRectangle.Height + 2*width)); - topRectangle = new ScreenRectangle(new Rect(boundingRectangle.X, boundingRectangle.Y - width, boundingRectangle.Width, width)); - rightRectangle = new ScreenRectangle(new Rect(boundingRectangle.X + boundingRectangle.Width, boundingRectangle.Y - width, width, boundingRectangle.Height + 2*width)); - bottomRectangle = new ScreenRectangle(new Rect(boundingRectangle.X, boundingRectangle.Y + boundingRectangle.Height, boundingRectangle.Width, width)); - rectangles = new ScreenRectangle[] { leftRectangle, topRectangle, rightRectangle, bottomRectangle }; + leftBorder = new ScreenRectangle(new Rect(boundingRectangle.X - width, boundingRectangle.Y - width, width, boundingRectangle.Height + 2*width)); + topBorder = new ScreenRectangle(new Rect(boundingRectangle.X, boundingRectangle.Y - width, boundingRectangle.Width, width)); + rightBorder = new ScreenRectangle(new Rect(boundingRectangle.X + boundingRectangle.Width, boundingRectangle.Y - width, width, boundingRectangle.Height + 2*width)); + bottomBorder = new ScreenRectangle(new Rect(boundingRectangle.X, boundingRectangle.Y + boundingRectangle.Height, boundingRectangle.Width, width)); + rectangles = new ScreenRectangle[] { leftBorder, topBorder, rightBorder, bottomBorder }; } - public void Highlight() + + internal void Highlight() { rectangles.ToList().ForEach(x => x.Show()); - Thread.Sleep(1000); + Thread.Sleep(CoreAppXmlConfiguration.Instance.HighlightTimeout); rectangles.ToList().ForEach(x => x.Hide()); } } diff --git a/src/TestStack.White/TestStack.White.csproj b/src/TestStack.White/TestStack.White.csproj index 1e47ec8f..8180c03b 100644 --- a/src/TestStack.White/TestStack.White.csproj +++ b/src/TestStack.White/TestStack.White.csproj @@ -94,6 +94,7 @@ + diff --git a/src/TestStack.White/UIItems/UIItem.cs b/src/TestStack.White/UIItems/UIItem.cs index 02c96beb..4f163331 100644 --- a/src/TestStack.White/UIItems/UIItem.cs +++ b/src/TestStack.White/UIItems/UIItem.cs @@ -428,7 +428,7 @@ public virtual void RaiseClickEvent() } /// - /// Highlight UIItem with the red frame for 1 second + /// Highlight UIItem with red frame /// public void DrawHighlight() { diff --git a/src/TestStack.White/WindowsAPI/NativeWindow.cs b/src/TestStack.White/WindowsAPI/NativeWindow.cs index a2b855c2..2d90b88c 100644 --- a/src/TestStack.White/WindowsAPI/NativeWindow.cs +++ b/src/TestStack.White/WindowsAPI/NativeWindow.cs @@ -83,7 +83,7 @@ public virtual COLORREF TextColor return GetTextColor(GetDC(handle)); } } - + public virtual void PostCloseMessage() { PostMessage(handle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); From ac051f2e00193d67df2bb6a5b3eeee3edba4cf76 Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Sun, 5 Jan 2014 06:42:44 -0800 Subject: [PATCH 11/16] Remove unused directive. --- src/TestStack.White/UIItems/UIItem.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/TestStack.White/UIItems/UIItem.cs b/src/TestStack.White/UIItems/UIItem.cs index 4f163331..318f16d5 100644 --- a/src/TestStack.White/UIItems/UIItem.cs +++ b/src/TestStack.White/UIItems/UIItem.cs @@ -20,7 +20,6 @@ using TestStack.White.WindowsAPI; using Action = TestStack.White.UIItems.Actions.Action; using Point = System.Windows.Point; -using System.Runtime.InteropServices; using System.Windows.Forms; namespace TestStack.White.UIItems From 5a9700b6817dc1652e138989e6a0aece276af149 Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Sun, 5 Jan 2014 07:38:36 -0800 Subject: [PATCH 12/16] Made all methods virtual. --- src/TestStack.White/Drawing/ScreenRectangle.cs | 6 +++--- src/TestStack.White/UIItems/UIItem.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/TestStack.White/Drawing/ScreenRectangle.cs b/src/TestStack.White/Drawing/ScreenRectangle.cs index f702a0b3..0ad96a6f 100644 --- a/src/TestStack.White/Drawing/ScreenRectangle.cs +++ b/src/TestStack.White/Drawing/ScreenRectangle.cs @@ -38,12 +38,12 @@ internal ScreenRectangle(Rect rectangle) Convert.ToInt32(rectangle.Width), Convert.ToInt32(rectangle.Height), 0x10); } - internal void Show() + internal virtual void Show() { TestStack.White.WindowsAPI.NativeWindow.ShowWindow(form.Handle, 8); } - internal void Hide() + internal virtual void Hide() { form.Hide(); } @@ -69,7 +69,7 @@ internal FrameRectangle(Rect boundingRectangle) rectangles = new ScreenRectangle[] { leftBorder, topBorder, rightBorder, bottomBorder }; } - internal void Highlight() + internal virtual void Highlight() { rectangles.ToList().ForEach(x => x.Show()); Thread.Sleep(CoreAppXmlConfiguration.Instance.HighlightTimeout); diff --git a/src/TestStack.White/UIItems/UIItem.cs b/src/TestStack.White/UIItems/UIItem.cs index 318f16d5..ce855e28 100644 --- a/src/TestStack.White/UIItems/UIItem.cs +++ b/src/TestStack.White/UIItems/UIItem.cs @@ -429,7 +429,7 @@ public virtual void RaiseClickEvent() /// /// Highlight UIItem with red frame /// - public void DrawHighlight() + public virtual void DrawHighlight() { Rect rectangle = this.AutomationElement.Current.BoundingRectangle; From 95534f4d32550e4b148dc578fb639b56dc46a720 Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Tue, 7 Jan 2014 05:22:11 -0800 Subject: [PATCH 13/16] Add DrawHighlight to IUIItem. --- src/TestStack.White/UIItems/IUIItem.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/TestStack.White/UIItems/IUIItem.cs b/src/TestStack.White/UIItems/IUIItem.cs index 73b3edee..d1632e21 100644 --- a/src/TestStack.White/UIItems/IUIItem.cs +++ b/src/TestStack.White/UIItems/IUIItem.cs @@ -94,5 +94,7 @@ public interface IUIItem : ActionListener AutomationElement GetElement(SearchCriteria searchCriteria); void Enter(string value); + + void DrawHighlight(); } } \ No newline at end of file From 51399ac375964d3a285899d1724601dd9120e80d Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Wed, 8 Jan 2014 02:16:30 -0800 Subject: [PATCH 14/16] Small improvement. --- src/TestStack.White/Drawing/ScreenRectangle.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TestStack.White/Drawing/ScreenRectangle.cs b/src/TestStack.White/Drawing/ScreenRectangle.cs index 0ad96a6f..2e6d4e37 100644 --- a/src/TestStack.White/Drawing/ScreenRectangle.cs +++ b/src/TestStack.White/Drawing/ScreenRectangle.cs @@ -27,7 +27,7 @@ internal ScreenRectangle(Rect rectangle) form.Height = 1; form.BackColor = this.Color; form.Opacity = 0.8; - form.Visible = true; + form.Visible = false; //Set popup style int num1 = TestStack.White.WindowsAPI.NativeWindow.GetWindowLong(form.Handle, -20); From abb15d2850767b5fa9ecc8affdc451ed768b4f89 Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Sun, 16 Feb 2014 06:51:11 -0800 Subject: [PATCH 15/16] Moved highlighting to different thread --- src/TestStack.White/UIItems/UIItem.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/TestStack.White/UIItems/UIItem.cs b/src/TestStack.White/UIItems/UIItem.cs index ce855e28..ec4619ae 100644 --- a/src/TestStack.White/UIItems/UIItem.cs +++ b/src/TestStack.White/UIItems/UIItem.cs @@ -431,12 +431,15 @@ public virtual void RaiseClickEvent() /// public virtual void DrawHighlight() { - Rect rectangle = this.AutomationElement.Current.BoundingRectangle; + new Thread(() => + { + Rect rectangle = this.AutomationElement.Current.BoundingRectangle; - if (rectangle != Rect.Empty) - { - new Drawing.FrameRectangle(rectangle).Highlight(); - } + if (rectangle != Rect.Empty) + { + new Drawing.FrameRectangle(rectangle).Highlight(); + } + }).Start(); } } } \ No newline at end of file From afb3550348baae68dec0c470a1641d10e17ab15a Mon Sep 17 00:00:00 2001 From: ilya-murzinov Date: Mon, 2 Jun 2014 18:32:39 +0400 Subject: [PATCH 16/16] fix & removed starting highlighting in another thread --- src/TestStack.White/UIItems/UIItem.cs | 13 +++++-------- src/TestStack.White/WindowsAPI/NativeWindow.cs | 4 +--- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/TestStack.White/UIItems/UIItem.cs b/src/TestStack.White/UIItems/UIItem.cs index ec4619ae..5f589131 100644 --- a/src/TestStack.White/UIItems/UIItem.cs +++ b/src/TestStack.White/UIItems/UIItem.cs @@ -431,15 +431,12 @@ public virtual void RaiseClickEvent() /// public virtual void DrawHighlight() { - new Thread(() => - { - Rect rectangle = this.AutomationElement.Current.BoundingRectangle; + Rect rectangle = AutomationElement.Current.BoundingRectangle; - if (rectangle != Rect.Empty) - { - new Drawing.FrameRectangle(rectangle).Highlight(); - } - }).Start(); + if (rectangle != Rect.Empty) + { + new Drawing.FrameRectangle(rectangle).Highlight(); + } } } } \ No newline at end of file diff --git a/src/TestStack.White/WindowsAPI/NativeWindow.cs b/src/TestStack.White/WindowsAPI/NativeWindow.cs index 81a6b2e0..99900014 100644 --- a/src/TestStack.White/WindowsAPI/NativeWindow.cs +++ b/src/TestStack.White/WindowsAPI/NativeWindow.cs @@ -96,13 +96,11 @@ public virtual void PostCloseMessage() [DllImport("user32.dll", CharSet = CharSet.Auto)] internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); [DllImport("user32.dll", CharSet = CharSet.Auto)] internal static extern int GetWindowLong(IntPtr hWnd, int nIndex); - - [DllImport("user32.dll", CharSet = CharSet.Auto)] - internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); } } \ No newline at end of file