mirror of
https://github.com/microsoft/PowerToys
synced 2025-08-22 18:17:19 +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>
115 lines
3.9 KiB
Markdown
115 lines
3.9 KiB
Markdown
# 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:
|
|
|
|
1. A background thread is created to run the crosshairs logic asynchronously:
|
|
```cpp
|
|
std::thread([=]() { InclusiveCrosshairsMain(hInstance, settings); }).detach();
|
|
```
|
|
|
|
2. The InclusiveCrosshairs instance is initialized and configured with user settings:
|
|
```cpp
|
|
InclusiveCrosshairs crosshairs;
|
|
InclusiveCrosshairs::instance = &crosshairs;
|
|
crosshairs.ApplySettings(settings, false);
|
|
crosshairs.MyRegisterClass(hInstance);
|
|
```
|
|
|
|
3. 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`)
|
|
|
|
### Activation Process
|
|
|
|
The activation process works as follows:
|
|
|
|
1. **Shortcut Detection**
|
|
- When the activation shortcut is pressed, the window procedure (`WndProc`) receives a custom message `WM_SWITCH_ACTIVATION_MODE`
|
|
|
|
2. **Toggle Drawing State**
|
|
```cpp
|
|
case WM_SWITCH_ACTIVATION_MODE:
|
|
if (instance->m_drawing)
|
|
{
|
|
instance->StopDrawing();
|
|
}
|
|
else
|
|
{
|
|
instance->StartDrawing();
|
|
}
|
|
break;
|
|
```
|
|
|
|
3. **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
|
|
|
|
```cpp
|
|
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);
|
|
}
|
|
```
|
|
|
|
4. **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
|
|
|
|
### Cursor Tracking
|
|
|
|
While active, the utility:
|
|
1. Uses a low-level mouse hook (`WH_MOUSE_LL`) to track cursor movement
|
|
2. Updates crosshair positions in real-time as the mouse moves
|
|
3. 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 every `WM_MOUSEMOVE` event
|
|
- This frequent update combined with the debugger's overhead or breakpoints can cause visual glitches or stutters
|