Skip to content

Commit d77b3af

Browse files
committed
Merge pull request #188 from ilya-murzinov/Issue144
Issue144: Add DrawHighlight method to UIItem
2 parents 03e879b + afb3550 commit d77b3af

File tree

7 files changed

+119
-1
lines changed

7 files changed

+119
-1
lines changed

src/TestStack.White/Configuration/CoreAppXmlConfiguration.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ static CoreAppXmlConfiguration()
2626
DefaultValues.Add("PopupTimeout", 5000);
2727
DefaultValues.Add("TooltipWaitTime", 3000);
2828
DefaultValues.Add("SuggestionListTimeout", 3000);
29+
DefaultValues.Add("HighlightTimeout", 1000);
2930
DefaultValues.Add("DefaultDateFormat", DateFormat.CultureDefault.ToString());
3031
DefaultValues.Add("DragStepCount", 1);
3132
DefaultValues.Add("InProc", false);
@@ -108,6 +109,12 @@ public virtual int SuggestionListTimeout
108109
set { SetUsedValue("SuggestionListTimeout", value); }
109110
}
110111

112+
public virtual int HighlightTimeout
113+
{
114+
get { return Convert.ToInt32(UsedValues["HighlightTimeout"]); }
115+
set { SetUsedValue("HighlightTimeout", value); }
116+
}
117+
111118
public virtual DateFormat DefaultDateFormat
112119
{
113120
get { return DateFormat.Parse(UsedValues["DefaultDateFormat"]); }

src/TestStack.White/Configuration/CoreConfiguration.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public interface ICoreConfiguration
2323
int PopupTimeout { get; set; }
2424
int TooltipWaitTime { get; set; }
2525
int SuggestionListTimeout { get; set; }
26+
int HighlightTimeout { get; set; }
2627
DateFormat DefaultDateFormat { get; set; }
2728
int DragStepCount { get; set; }
2829
bool InProc { get; set; }
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Drawing;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading;
7+
using System.Windows;
8+
using System.Windows.Forms;
9+
using TestStack.White.Configuration;
10+
11+
namespace TestStack.White.Drawing
12+
{
13+
internal class ScreenRectangle
14+
{
15+
private Form form = new Form();
16+
//TODO: Think about making color configurable
17+
private Color Color = Color.Red;
18+
19+
internal ScreenRectangle(Rect rectangle)
20+
{
21+
form.FormBorderStyle = FormBorderStyle.None;
22+
form.ShowInTaskbar = false;
23+
form.TopMost = true;
24+
form.Left = 0;
25+
form.Top = 0;
26+
form.Width = 1;
27+
form.Height = 1;
28+
form.BackColor = this.Color;
29+
form.Opacity = 0.8;
30+
form.Visible = false;
31+
32+
//Set popup style
33+
int num1 = TestStack.White.WindowsAPI.NativeWindow.GetWindowLong(form.Handle, -20);
34+
TestStack.White.WindowsAPI.NativeWindow.SetWindowLong(form.Handle, -20, num1 | 0x80);
35+
36+
//Set position
37+
TestStack.White.WindowsAPI.NativeWindow.SetWindowPos(form.Handle, new IntPtr(-1), Convert.ToInt32(rectangle.X), Convert.ToInt32(rectangle.Y),
38+
Convert.ToInt32(rectangle.Width), Convert.ToInt32(rectangle.Height), 0x10);
39+
}
40+
41+
internal virtual void Show()
42+
{
43+
TestStack.White.WindowsAPI.NativeWindow.ShowWindow(form.Handle, 8);
44+
}
45+
46+
internal virtual void Hide()
47+
{
48+
form.Hide();
49+
}
50+
}
51+
52+
internal class FrameRectangle
53+
{
54+
//Using 4 rectangles to display each border
55+
private ScreenRectangle leftBorder;
56+
private ScreenRectangle topBorder;
57+
private ScreenRectangle rightBorder;
58+
private ScreenRectangle bottomBorder;
59+
60+
private ScreenRectangle[] rectangles;
61+
private int width = 3;
62+
63+
internal FrameRectangle(Rect boundingRectangle)
64+
{
65+
leftBorder = new ScreenRectangle(new Rect(boundingRectangle.X - width, boundingRectangle.Y - width, width, boundingRectangle.Height + 2*width));
66+
topBorder = new ScreenRectangle(new Rect(boundingRectangle.X, boundingRectangle.Y - width, boundingRectangle.Width, width));
67+
rightBorder = new ScreenRectangle(new Rect(boundingRectangle.X + boundingRectangle.Width, boundingRectangle.Y - width, width, boundingRectangle.Height + 2*width));
68+
bottomBorder = new ScreenRectangle(new Rect(boundingRectangle.X, boundingRectangle.Y + boundingRectangle.Height, boundingRectangle.Width, width));
69+
rectangles = new ScreenRectangle[] { leftBorder, topBorder, rightBorder, bottomBorder };
70+
}
71+
72+
internal virtual void Highlight()
73+
{
74+
rectangles.ToList().ForEach(x => x.Show());
75+
Thread.Sleep(CoreAppXmlConfiguration.Instance.HighlightTimeout);
76+
rectangles.ToList().ForEach(x => x.Hide());
77+
}
78+
}
79+
}

src/TestStack.White/TestStack.White.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
<Compile Include="Configuration\ConfigurationExtensions.cs" />
9595
<Compile Include="Configuration\WhiteDefaultLogger.cs" />
9696
<Compile Include="Configuration\WhiteDefaultLoggerFactory.cs" />
97+
<Compile Include="Drawing\ScreenRectangle.cs" />
9798
<Compile Include="InputDevices\Input64.cs" />
9899
<Compile Include="InputDevices\SystemMetric.cs" />
99100
<Compile Include="Interceptors\IWhiteInterceptor.cs" />

src/TestStack.White/UIItems/IUIItem.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,5 +94,7 @@ public interface IUIItem : ActionListener
9494
AutomationElement GetElement(SearchCriteria searchCriteria);
9595

9696
void Enter(string value);
97+
98+
void DrawHighlight();
9799
}
98100
}

src/TestStack.White/UIItems/UIItem.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using TestStack.White.WindowsAPI;
2121
using Action = TestStack.White.UIItems.Actions.Action;
2222
using Point = System.Windows.Point;
23+
using System.Windows.Forms;
2324

2425
namespace TestStack.White.UIItems
2526
{
@@ -424,5 +425,18 @@ public virtual void RaiseClickEvent()
424425
var invokePattern = (InvokePattern)Pattern(InvokePattern.Pattern);
425426
if (invokePattern != null) invokePattern.Invoke();
426427
}
428+
429+
/// <summary>
430+
/// Highlight UIItem with red frame
431+
/// </summary>
432+
public virtual void DrawHighlight()
433+
{
434+
Rect rectangle = AutomationElement.Current.BoundingRectangle;
435+
436+
if (rectangle != Rect.Empty)
437+
{
438+
new Drawing.FrameRectangle(rectangle).Highlight();
439+
}
440+
}
427441
}
428442
}

src/TestStack.White/WindowsAPI/NativeWindow.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,24 @@ public virtual COLORREF TextColor
8383
return GetTextColor(GetDC(handle));
8484
}
8585
}
86-
86+
8787
public virtual void PostCloseMessage()
8888
{
8989
PostMessage(handle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
9090
}
91+
92+
//Native methods needed for highlighting UIItems
93+
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
94+
internal static extern bool SetWindowPos(IntPtr hWnd, IntPtr hwndAfter, int x, int y, int width, int height, int flags);
95+
[return: MarshalAs(UnmanagedType.Bool)]
96+
97+
[DllImport("user32.dll", CharSet = CharSet.Auto)]
98+
internal static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
99+
100+
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
101+
internal static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
102+
103+
[DllImport("user32.dll", CharSet = CharSet.Auto)]
104+
internal static extern int GetWindowLong(IntPtr hWnd, int nIndex);
91105
}
92106
}

0 commit comments

Comments
 (0)