mirror of
https://github.com/microsoft/PowerToys
synced 2025-08-22 10:07:37 +00:00
## Summary of the Pull Request Accumulated information from internal transition about the modules development, and reworked it to be added in dev docs. Also the dev docs intself was restructured to be more organized. New pages was verified by transition team. ## PR Checklist - [x] **Dev docs:** Added/updated --------- Co-authored-by: Zhaopeng Wang (from Dev Box) <zhaopengwang@microsoft.com> Co-authored-by: Hao Liu <liuhao3418@gmail.com> Co-authored-by: Peiyao Zhao <105847726+zhaopy536@users.noreply.github.com> Co-authored-by: Mengyuan <162882040+chenmy77@users.noreply.github.com> Co-authored-by: zhaopeng wang <33367956+wang563681252@users.noreply.github.com> Co-authored-by: Jaylyn Barbee <51131738+Jaylyn-Barbee@users.noreply.github.com>
3.9 KiB
3.9 KiB
Mouse Pointer Crosshairs
Mouse Pointer Crosshairs is a utility that displays horizontal and vertical lines that intersect at the mouse cursor position, making it easier to track the cursor location on screen.
Implementation
Mouse Pointer Crosshairs runs within the PowerToys Runner process and draws crosshair lines that follow the cursor in real-time.
Key Files
src/modules/MouseUtils/MousePointerCrosshairs/InclusiveCrosshairs.cpp
- Contains the main implementation- Key function:
WndProc
- Handles window messages and mouse events
Enabling Process
When the utility is enabled:
-
A background thread is created to run the crosshairs logic asynchronously:
std::thread([=]() { InclusiveCrosshairsMain(hInstance, settings); }).detach();
-
The InclusiveCrosshairs instance is initialized and configured with user settings:
InclusiveCrosshairs crosshairs; InclusiveCrosshairs::instance = &crosshairs; crosshairs.ApplySettings(settings, false); crosshairs.MyRegisterClass(hInstance);
-
The utility:
- Creates the crosshairs visuals using Windows Composition API inside
CreateInclusiveCrosshairs()
- Handles the
WM_CREATE
message to initialize the Windows Composition API (Compositor, visuals, and target) - Creates a transparent, layered window for drawing the crosshairs with specific extended window styles (e.g.,
WS_EX_LAYERED
,WS_EX_TRANSPARENT
)
- Creates the crosshairs visuals using Windows Composition API inside
Activation Process
The activation process works as follows:
-
Shortcut Detection
- When the activation shortcut is pressed, the window procedure (
WndProc
) receives a custom messageWM_SWITCH_ACTIVATION_MODE
- When the activation shortcut is pressed, the window procedure (
-
Toggle Drawing State
case WM_SWITCH_ACTIVATION_MODE: if (instance->m_drawing) { instance->StopDrawing(); } else { instance->StartDrawing(); } break;
-
Start Drawing Function
- The
StartDrawing()
function is called to:- Log the start of drawing
- Update the crosshairs position
- Check if the cursor should be auto-hidden, and set a timer for auto-hide if enabled
- Show the crosshairs window if the cursor is visible
- Set a low-level mouse hook to track mouse movements asynchronously
void InclusiveCrosshairs::StartDrawing() { Logger::info("Start drawing crosshairs."); UpdateCrosshairsPosition(); m_hiddenCursor = false; if (m_crosshairs_auto_hide) { CURSORINFO cursorInfo{}; cursorInfo.cbSize = sizeof(cursorInfo); if (GetCursorInfo(&cursorInfo)) { m_hiddenCursor = !(cursorInfo.flags & CURSOR_SHOWING); } SetAutoHideTimer(); } if (!m_hiddenCursor) { ShowWindow(m_hwnd, SW_SHOWNOACTIVATE); } m_drawing = true; m_mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, m_hinstance, 0); }
- The
-
Stop Drawing Function
- The
StopDrawing()
function is called to:- Remove the mouse hook
- Kill the auto-hide timer
- Hide the crosshairs window
- Log the stop of drawing
- The
Cursor Tracking
While active, the utility:
- Uses a low-level mouse hook (
WH_MOUSE_LL
) to track cursor movement - Updates crosshair positions in real-time as the mouse moves
- Supports auto-hiding functionality when the cursor is inactive for a specified period
Debugging
To debug Mouse Pointer Crosshairs:
- Attach to the PowerToys Runner process directly
- Set breakpoints in the
InclusiveCrosshairs.cpp
file - Be aware that during debugging, moving the mouse may cause unexpected or "strange" visual behavior because:
- The mouse hook (
MouseHookProc
) updates the crosshairs position on everyWM_MOUSEMOVE
event - This frequent update combined with the debugger's overhead or breakpoints can cause visual glitches or stutters
- The mouse hook (