This is the day 2 I am using the PowerToys following the post. ⏮️ Day 1: Shortcut Guide ⏸️ Day 3: Registry Preview ⏭️
📝Description
The Screen Ruler is a measurement tool that you can measure the elements on your screen with pixels / centimeters / millimeters.


📢Name
In the codebase, this utility was initially called “Measure Tool”:
private void ModuleButton_Click(object sender, RoutedEventArgs e)
{
switch ((ModuleType)selectedModuleBtn.Tag)
{
case ModuleType.MeasureTool: // 👈Launch Screen Ruler
case //...
}
}
I personally think this is a very smart move! The comparison is straightforward:
Measure Tool:- ❌ Broad term
- ❌ Unclear what it measures
- ❌ Unclear what the tool is
- Screen Ruler:
- ✅ Screen: Provides context
- ✅ Ruler: Clearly indicates the tool and its purpose - measuring length 📏
By renaming it to “Screen Ruler,” the tool’s functionality becomes immediately clear to users, enhancing usability and user experience.
This reminds me of Uncle Bob’s book Clean Code > Chapter 2 Meaningful Names > Section 2.2 where he suggests we should use intention-revealing names. I think this rule not only applies to programming but also marketing. This is an example of Good Name Gives Good Product.
⌨️Shortcut
⊞
+Ctrl
+Shift
+M
Remark
Hum… A shortcut requires 2 hands 🤣…
🖱️Code
Screen Capture
The utility captures the screen in 2 modes:
- live(real-time update)
- static(single frame)
There is a background std::thread
continuously capturing the screen using the DirectX api:
//src\modules\MeasureTool\MeasureToolCore\ScreenCapturing.cpp
std::thread StartCapturingThread(DxgiAPI* dxgiAPI,
const CommonState& commonState,
Serialized<MeasureToolState>& state,
HWND window,
MonitorInfo monitor)
{
return SpawnLoggedThread({});
}
Edge Detection
The core idea is to find where a color changes significantly in each direction (left, right, up, down) from a starting point. Here’s how it works:
1️⃣ Starting Point
const uint32_t startPixel = texture.GetPixel(x, y);
Let’s say you click on a red square on a white background and if you click at (3,2)
- a red pixel in the middle.
⬜⬜⬜⬜⬜⬜⬜ ⬜⬜🟥🟥🟥⬜⬜ ⬜⬜🟥🟥🟥⬜⬜ ⬜⬜🟥🟥🟥⬜⬜ ⬜⬜⬜⬜⬜⬜⬜
NoteNote that in Computer Graphics , the coordinate starts with
0
-index. Also the origin(0,0)
is the top left corner.
2️⃣ Find Edge
The FindEdge
template function searches in one direction at a time:
template<bool PerChannel,
bool IsX,
bool Increment>
inline long FindEdge(/*...*/)
PerChannel
: Whether to check RGB channels separately or togetherIsX
: Search horizontally (true) or vertically (false)Increment
: Search forward/right/down (true) or backward/left/up (false)
3️⃣ Search Right
Suppose we gonna search right (IsX=true, Increment=true
):
⬜⬜⬜⬜⬜⬜⬜
⬜⬜🟥🟥🟥⬜⬜
⬜⬜🟥❌🟥⬜⬜ Start at (3,2)
⬜⬜🟥🟥🟥⬜⬜
⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜ ⬜⬜🟥🟥🟥⬜⬜ ⬜⬜🟥🟥❌⬜⬜ Check: (4,2) - still red ⬜⬜🟥🟥🟥⬜⬜ ⬜⬜⬜⬜⬜⬜⬜
⬜⬜⬜⬜⬜⬜⬜ ⬜⬜🟥🟥🟥⬜⬜ ⬜⬜🟥🟥🟥✖️⬜ Check: (5,2) - white! Stop! ⬜⬜🟥🟥🟥⬜⬜ ⬜⬜⬜⬜⬜⬜⬜
while (true) {
// Move to next pixel
if constexpr (Increment) {
if (++x == maxDim)
break;
}
// Check if color changed
const uint32_t nextPixel = texture.GetPixel(x, y);
if (!texture.PixelsClose<PerChannel>(startPixel, nextPixel, tolerance)) {
return oldX; // Return last position of similar color
}
}
4️⃣ Complete Detection
The DetectEdges
function calls FindEdge
in all 4 directions:
RECT DetectEdges(/*...*/) {
return RECT{
.left = FindEdge</*left*/>,
.top = FindEdge</*up*/>,
.right = FindEdge</*right*/>,
.bottom = FindEdge</*down*/>
};
}
5️⃣Result
⬜⬜⬜⬜⬜⬜⬜ After clicking (3,2):
⬜⬜🟥🟥🟥⬜⬜ left is x=2
(last red pixel)
⬜⬜🟥🟥🟥⬜⬜ right is x=4
(last red pixel)
⬜⬜🟥🟥🟥⬜⬜ top = y=1
(last red pixel)
⬜⬜⬜⬜⬜⬜⬜ bottom = y=3
(last red pixel)