Files
PowerToys/doc/devdocs/modules/screenruler.md
Niels Laute 05ba63beba [Screen Ruler] Add DIP as an extra measurement unit (#49588)
## Summary of the Pull Request

Adds display-independent pixels (DIP) to Screen Ruler's existing **Extra
units of measurement** setting. Physical pixels remain the primary
overlay value; selecting DIP adds a second, parenthesized measurement
that adjusts for Windows display scaling.

DIP values use the DPI of the monitor containing the measurement. This
also corrects the millimeter fallback conversion when physical monitor
dimensions are unavailable.


<img width="1079" height="81" alt="image"
src="https://github.com/user-attachments/assets/a34fe0a8-1dc1-4f1d-97c6-1a0dc37bf2e3"
/>

Before vs after:

<img width="921" height="617" alt="image"
src="https://github.com/user-attachments/assets/7b0ed0ce-7058-4f4f-b8ae-1fc3709e0ace"
/>


## PR Checklist

- [x] Closes #20304
- [x] Closes #46945
- [x] **Communication:** The scope was agreed before implementation
- [x] **Tests:** Added/updated and all focused tests pass
- [x] **Localization:** All end-user-facing strings can be localized
- [x] **Dev docs:** Added/updated
- [x] **New binaries:** Not applicable; no production binaries were
added
- [ ] **Documentation updated:** A public documentation PR has not been
filed

## Detailed Description of the Pull Request / Additional comments

- Preserves the existing persisted values for pixels, inches,
centimeters, and millimeters; DIP is appended as value `4`.
- Preserves the existing overlay behavior: pixels are always displayed,
with one optional extra unit on a second line.
- Preserves the existing clipboard behavior: pixel-only output has no
suffix, while a selected extra unit is copied by itself.
- Converts physical pixels to DIP using each overlay window's monitor
DPI.
- Corrects the 96-DPI millimeter fallback so 96 px equals 25.4 mm.
- Adds focused native conversion tests, settings compatibility tests,
and DIP clipboard UI coverage.
- Keeps guides, calibration, browser-relative units, and other
measurement modes out of scope.

## Validation Steps Performed

- Built `MeasureToolCore` for ARM64 Debug.
- Built `MeasureToolUI` for ARM64 Debug.
- Built PowerToys Settings for ARM64 Debug.
- Built and ran `MeasureToolCore.UnitTests`: 5 passed.
- Built and ran the Screen Ruler settings tests: 6 passed.
- Built `ScreenRuler.UITests`; local execution was not run because
WinAppDriver is not installed.
- Ran XAML Styler on the changed Settings page.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1a6361cf-d701-4a9b-b8e8-d5700c5ba140
2026-08-31 13:31:57 +02:00

4.0 KiB

Screen Ruler

Public overview - Microsoft Learn

All Issues
Bugs
Pull Requests

Overview

Screen Ruler (project name: MeasureTool or Measure 2) is a PowerToys module that allows users to measure distances and detect color boundaries on the screen. Measurements are always displayed in physical pixels and can optionally include display-independent pixels (DIP), inches, centimeters, or millimeters. The tool renders an overlay UI using DirectX and provides several measurement utilities.

Features

  • Bounce Utility: Measure a rectangular zone by dragging with a left click
  • Spacing Tool: Measure the length of a line with the same color with the same pixel value both horizontally and vertically
  • Horizontal Spacing: Measure the line with the same color in the horizontal direction
  • Vertical Spacing: Measure the line with the same color in the vertical direction

Architecture & Implementation

The Screen Ruler module consists of several components:

MeasureToolModuleInterface

  • Dllmain.cpp: Provides functionality to start and stop the Measure Tool process based on hotkey events, manage settings, and handle events.

MeasureToolUI

  • App.xaml.cs: Main entrance of the app. Initializes MeasureToolCore and activates a new main window.
  • MainWindow.xaml.cs: Sets properties and behaviors for the window, and handles user click interactions.
  • NativeMethods.cs: Interacts with the Windows API to manipulate window properties, such as positioning and sizing.
  • Settings.cs: Gets the default measure style from settings.

PowerToys.MeasureToolCore

  • PowerToys.MeasureToolCore: Handles initialization, state management, and starts the measure tool and bounds tool.
  • BGRATextureView.h: Manages and interacts with BGRA textures in a Direct3D 11 context.
  • Measurement.cpp: Defines a Measurement struct that represents a rectangular measurement area, including methods for converting and printing measurement details in various units.
  • Clipboard.cpp: Copies measurement data to the clipboard.
  • D2DState.cpp: Manages Direct2D rendering state and draws text boxes.
  • DxgiAPI.cpp: Creates and manages Direct3D and Direct2D devices.
  • EdgeDetection.cpp: Detects edges in a BGRA texture.
  • OverlayUI.cpp: Creates and manages overlay windows for tools like MeasureTool and BoundsTool.
  • BoundsToolOverlayUI.cpp: UI implementation for bounds feature. Handles mouse and touch events to draw measurement rectangles on the screen and display their pixels.
  • MeasureToolOverlayUI.cpp: UI implementation for measure feature. Draws measurement lines on the screen and displays their pixels.
  • ScreenCapturing.cpp: Continuously captures the screen, detects edges, and updates the measurement state for real-time drawing of measurement lines.
  • PerGlyphOpacityTextRender.cpp: Renders text with varying opacity on a Direct2D render target.

Building & Debugging

Building

  1. Open PowerToys.slnx in Visual Studio
  2. In the Solutions Configuration drop-down menu, select Release or Debug
  3. From the Build menu, choose Build Solution
  4. The executable app for Screen Ruler is named PowerToys.MeasureToolUI.exe

Debugging

  1. Right-click the project MeasureToolUI and click 'Set as Startup Project'
  2. Right-click the project MeasureToolUI and click 'Debug'

Known Issues

There are several open bugs for the Screen Ruler module, most of which are related to crashing issues. These can be found in the PowerToys issues list.