Skip to content

Commit d7a5ad5

Browse files
committed
Added new utility: Measure 1.0.
1 parent 11ff58f commit d7a5ad5

File tree

11 files changed

+570
-1
lines changed

11 files changed

+570
-1
lines changed

Measure/App.config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<configuration>
3+
<startup>
4+
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
5+
</startup>
6+
</configuration>

Measure/Measure.csproj

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{C32135A3-AFBB-4A3D-8AC6-B07CF94BBCBD}</ProjectGuid>
8+
<OutputType>WinExe</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>Measure</RootNamespace>
11+
<AssemblyName>Measure</AssemblyName>
12+
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17+
<PlatformTarget>AnyCPU</PlatformTarget>
18+
<DebugSymbols>true</DebugSymbols>
19+
<DebugType>full</DebugType>
20+
<Optimize>false</Optimize>
21+
<OutputPath>bin\Debug\</OutputPath>
22+
<DefineConstants>DEBUG;TRACE</DefineConstants>
23+
<ErrorReport>prompt</ErrorReport>
24+
<WarningLevel>4</WarningLevel>
25+
</PropertyGroup>
26+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27+
<PlatformTarget>AnyCPU</PlatformTarget>
28+
<DebugType>pdbonly</DebugType>
29+
<Optimize>true</Optimize>
30+
<OutputPath>bin\Release\</OutputPath>
31+
<DefineConstants>TRACE</DefineConstants>
32+
<ErrorReport>prompt</ErrorReport>
33+
<WarningLevel>4</WarningLevel>
34+
</PropertyGroup>
35+
<ItemGroup>
36+
<Reference Include="System" />
37+
<Reference Include="System.Core" />
38+
<Reference Include="System.Xml.Linq" />
39+
<Reference Include="System.Data.DataSetExtensions" />
40+
<Reference Include="Microsoft.CSharp" />
41+
<Reference Include="System.Data" />
42+
<Reference Include="System.Deployment" />
43+
<Reference Include="System.Drawing" />
44+
<Reference Include="System.Net.Http" />
45+
<Reference Include="System.Windows.Forms" />
46+
<Reference Include="System.Xml" />
47+
</ItemGroup>
48+
<ItemGroup>
49+
<Compile Include="Program.cs" />
50+
<Compile Include="Properties\AssemblyInfo.cs" />
51+
<Compile Include="Overlay.cs">
52+
<SubType>Form</SubType>
53+
</Compile>
54+
<Compile Include="Properties\Strings.Designer.cs">
55+
<AutoGen>True</AutoGen>
56+
<DesignTime>True</DesignTime>
57+
<DependentUpon>Strings.resx</DependentUpon>
58+
</Compile>
59+
<EmbeddedResource Include="Properties\Strings.resx">
60+
<Generator>ResXFileCodeGenerator</Generator>
61+
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
62+
<SubType>Designer</SubType>
63+
</EmbeddedResource>
64+
<None Include="Properties\Settings.settings">
65+
<Generator>SettingsSingleFileGenerator</Generator>
66+
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
67+
</None>
68+
<Compile Include="Properties\Settings.Designer.cs">
69+
<AutoGen>True</AutoGen>
70+
<DependentUpon>Settings.settings</DependentUpon>
71+
<DesignTimeSharedInput>True</DesignTimeSharedInput>
72+
</Compile>
73+
</ItemGroup>
74+
<ItemGroup>
75+
<None Include="App.config" />
76+
</ItemGroup>
77+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
78+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
79+
Other similar extension points exist, see Microsoft.Common.targets.
80+
<Target Name="BeforeBuild">
81+
</Target>
82+
<Target Name="AfterBuild">
83+
</Target>
84+
-->
85+
</Project>

Measure/Overlay.cs

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
using System;
2+
using System.Drawing;
3+
using System.Windows.Forms;
4+
5+
namespace Measure
6+
{
7+
class Overlay : Form
8+
{
9+
Point start;
10+
Point end;
11+
bool drawing;
12+
13+
Pen linePen = new Pen(new SolidBrush(Color.FromArgb(255, Color.Magenta)), 1);
14+
Font Segoe = new Font("Segoe UI", 11, FontStyle.Regular);
15+
16+
Bitmap screenshot = null;
17+
18+
public Overlay()
19+
{
20+
this.WindowState = FormWindowState.Maximized;
21+
this.FormBorderStyle = FormBorderStyle.None;
22+
this.BackColor = Color.Black;
23+
this.DoubleBuffered = true;
24+
25+
this.MouseDown += Overlay_MouseDown;
26+
this.MouseUp += Overlay_MouseUp;
27+
this.MouseMove += Overlay_MouseMove;
28+
this.Paint += Overlay_Paint;
29+
this.KeyUp += Overlay_KeyUp;
30+
31+
}
32+
33+
private void InitializeComponent()
34+
{
35+
this.Name = "Measure";
36+
this.ShowInTaskbar = false;
37+
this.ResumeLayout(false);
38+
}
39+
40+
/// <summary>
41+
/// Set start point as we initially click
42+
/// </summary>
43+
private void Overlay_MouseDown(object sender, MouseEventArgs e)
44+
{
45+
start = e.Location;
46+
drawing = true;
47+
}
48+
49+
/// <summary>
50+
/// Stop drawing as we release the mouse.
51+
/// </summary>
52+
private void Overlay_MouseUp(object sender, MouseEventArgs e)
53+
{
54+
drawing = false;
55+
}
56+
57+
/// <summary>
58+
/// If we're drawing and moving the mouse, we set the end point to the current cursor location.
59+
/// </summary>
60+
private void Overlay_MouseMove(object sender, MouseEventArgs e)
61+
{
62+
if (drawing)
63+
{
64+
end = e.Location;
65+
// Cause active area of form to be redrawn
66+
this.Invalidate();
67+
}
68+
}
69+
70+
/// <summary>
71+
/// Draw
72+
/// </summary>
73+
/// <param name="sender"></param>
74+
/// <param name="e"></param>
75+
private void Overlay_Paint(object sender, PaintEventArgs e)
76+
{
77+
// Vertical line
78+
e.Graphics.DrawLine(linePen, start.X, start.Y, start.X, end.Y);
79+
80+
// Horizontal line
81+
e.Graphics.DrawLine(linePen, start.X, end.Y, end.X, end.Y);
82+
83+
// Diagonal line
84+
e.Graphics.DrawLine(linePen, start.X, start.Y, end.X, end.Y);
85+
86+
// Boxes to show end points
87+
e.Graphics.FillPolygon(Brushes.LimeGreen, PointToBox(start));
88+
e.Graphics.FillPolygon(Brushes.LimeGreen, PointToBox(end));
89+
90+
// Text coordinates of start- and endpoints.
91+
e.Graphics.DrawString(SimpleCoords(start), Segoe, Brushes.White, start);
92+
e.Graphics.DrawString(SimpleCoords(end), Segoe, Brushes.White, end);
93+
94+
// Line lengths
95+
// Width
96+
int dx = end.X - start.X;
97+
e.Graphics.DrawString(Math.Abs(dx) + "px", Segoe, Brushes.White, start.X + dx / 2, end.Y);
98+
99+
// Height
100+
int dy = end.Y - start.Y;
101+
e.Graphics.DrawString(Math.Abs(dy) + "px", Segoe, Brushes.White, start.X, start.Y + dy / 2);
102+
103+
// Hypotenuse length
104+
double hyp = Math.Round(Math.Sqrt(dx * dx + dy * dy), 0, MidpointRounding.AwayFromZero);
105+
e.Graphics.DrawString(hyp + "px", Segoe, Brushes.White, start.X + dx / 2, start.Y + dy / 2);
106+
107+
}
108+
109+
/// <summary>
110+
/// Capture the escape or Q keys to exit.
111+
/// </summary>
112+
private void Overlay_KeyUp(object sender, KeyEventArgs e)
113+
{
114+
if (e.KeyCode == Keys.Escape || e.KeyCode == Keys.Q)
115+
{
116+
this.DialogResult = DialogResult.OK;
117+
this.Close();
118+
}
119+
}
120+
121+
/// <summary>
122+
/// Convert a single point into a 5x5 pixel box
123+
/// </summary>
124+
/// <param name="point">Point to centre box on.</param>
125+
/// <returns>An array of points making a 5x5 rectangle centred on a specified point.</returns>
126+
private Point[] PointToBox(Point point)
127+
{
128+
return new Point[] {
129+
new Point(point.X - 2, point.Y - 2 ),
130+
new Point(point.X + 2, point.Y - 2 ),
131+
new Point(point.X + 2, point.Y + 2 ),
132+
new Point(point.X - 2, point.Y + 2 )
133+
};
134+
}
135+
136+
/// <summary>
137+
/// Override the background painting to fake a translucent form background.
138+
/// Draw instructions at this point to avoid redrawing every frame.
139+
/// </summary>
140+
protected override void OnPaintBackground(PaintEventArgs e)
141+
{
142+
// Take screenshot the first time. Won't update the screen, but otherwise it fades to black every frame as we take successively darker screenshots.
143+
if (screenshot == null)
144+
{
145+
using (Image image = new Bitmap(this.Width, this.Height))
146+
{
147+
using (Graphics Surface = Graphics.FromImage(image))
148+
{
149+
var BackgroundBrush = new SolidBrush(Color.FromArgb(128, Color.Black));
150+
var DarkerBrush = new SolidBrush(Color.FromArgb(192, Color.Black));
151+
152+
Surface.CopyFromScreen(0, 0, 0, 0, this.Size);
153+
Surface.FillRectangle(BackgroundBrush, this.DisplayRectangle);
154+
155+
// Measure and draw instructions. Draw a darker rectangle behind them.
156+
Size TextSize = ExpandSize(Size.Round(e.Graphics.MeasureString(Properties.Strings.Instructions, Segoe)), 5);
157+
Point TextOrigin = Point.Round(new PointF(this.Width / 2 - TextSize.Width / 2, this.Height - TextSize.Height - 10));
158+
var TextBox = new Rectangle(TextOrigin, TextSize);
159+
Surface.FillRectangle(DarkerBrush, TextBox);
160+
Surface.DrawString(Properties.Strings.Instructions, Segoe, Brushes.White, TextBox);
161+
162+
}
163+
screenshot = new Bitmap(image);
164+
}
165+
}
166+
e.Graphics.DrawImage(screenshot, 0, 0);
167+
}
168+
169+
/// <summary>
170+
/// Get shorter version of the coordinates of a Point (or PointF).
171+
/// </summary>
172+
/// <param name="point">Point to return coords of.</param>
173+
/// <returns>Coordinates in the format "X,Y".</returns>
174+
public string SimpleCoords(PointF point)
175+
{
176+
return point.X + "," + point.Y;
177+
}
178+
179+
/// <summary>
180+
/// Expand a given size by a given amount.
181+
/// </summary>
182+
/// <param name="size">Size to base our new size on.</param>
183+
/// <param name="expandBy">Amount to change dimensions by.</param>
184+
public Size ExpandSize(Size size, int expandBy)
185+
{
186+
return new Size(size.Width + expandBy, size.Height + expandBy);
187+
}
188+
189+
}
190+
}

Measure/Program.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using System.Windows.Forms;
6+
7+
namespace Measure
8+
{
9+
static class Program
10+
{
11+
/// <summary>
12+
/// The main entry point for the application.
13+
/// </summary>
14+
[STAThread]
15+
static void Main()
16+
{
17+
Application.EnableVisualStyles();
18+
Application.SetCompatibleTextRenderingDefault(false);
19+
Application.Run(new Overlay());
20+
}
21+
}
22+
}

Measure/Properties/AssemblyInfo.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("Measure")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("")]
12+
[assembly: AssemblyProduct("Measure")]
13+
[assembly: AssemblyCopyright("Copyright © 2019")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("c32135a3-afbb-4a3d-8ac6-b07cf94bbcbd")]
24+
25+
26+
[assembly: AssemblyVersion("1.0.*")]

Measure/Properties/Settings.Designer.cs

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version='1.0' encoding='utf-8'?>
2+
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
3+
<Profiles>
4+
<Profile Name="(Default)" />
5+
</Profiles>
6+
<Settings />
7+
</SettingsFile>

0 commit comments

Comments
 (0)