babalae/better-genshin-impact · error · ArgumentOutOfRangeException
鼠标限制区域必须具有有效宽度和高度。
Error message
鼠标限制区域必须具有有效宽度和高度。
What it means
LocalCursorCapture.Capture clamps the OS cursor to a desktop region (the game's 'desktop clone' control). A region with zero or negative width/height is unusable as a clip rectangle and would leave the cursor trapped or unbounded, so the method throws ArgumentOutOfRangeException before touching ClipCursor. The check runs after the ObjectDisposedException guard, so it also implies the instance is still live.
Solutions
- Ensure the source window/control has non-zero size before invoking Capture.
- Guard the caller: if (bounds.Width <= 0 || bounds.Height <= 0) return/skip.
- Recompute bounds from the live capture region right before calling Capture.
Example fix
// before _cursorCapture.Capture(rect); // after if (rect.Width <= 0 || rect.Height <= 0) return; _cursorCapture.Capture(rect);
Defensive patterns
Strategy: validation
Validate before calling
if (bounds.Width <= 0 || bounds.Height <= 0) return; // skip invalid region _cursorCapture.Capture(bounds);
Type guard
static bool IsValidClipRect(Rectangle r) => r.Width > 0 && r.Height > 0;
Prevention
- Only call Capture once the source window has a real client rect.
- Recompute bounds from the live capture region each time.
- Guard against zero-size regions during window initialization.
When it happens
Trigger: Passing a Rectangle.Empty or default(Rectangle); a capture rect computed from a zero-size window; bounds derived from a monitor region that returned 0 before the window was laid out.
Common situations: Starting capture before the game window has a valid client rect; multi-monitor setups where the source window reports 0 size momentarily; DPI/scale math producing 0 dimensions.
Related errors
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/37dc7f5d8817a428.
Report an issue: GitHub.
Appendix: source
Thrown at BetterGenshinImpact/Core/Monitor/LocalCursorCapture.cs:34
private const int SmXVirtualScreen = 76;
private const int SmYVirtualScreen = 77;
private const int SmCxVirtualScreen = 78;
private const int SmCyVirtualScreen = 79;
private NativeRect _previousClipRect;
private Rectangle _appliedBounds;
private bool _hasPreviousClipRect;
private bool _isCaptureSessionActive;
private bool _isRestrictionApplied;
private bool _isDisposed;
private int _cursorHideCallCount;
internal void Capture(Rectangle bounds)
{
ObjectDisposedException.ThrowIf(_isDisposed, this);
if (bounds.Width <= 0 || bounds.Height <= 0)
{
throw new ArgumentOutOfRangeException(
nameof(bounds),
bounds,
"鼠标限制区域必须具有有效宽度和高度。");
}
if (!_isCaptureSessionActive)
{
var clipRectRead = NativeMethods.GetClipCursor(out _previousClipRect);
if (!clipRectRead)
{
logger.LogWarning(
"读取现有鼠标限制区域失败,Win32Error: {Win32Error}",
Marshal.GetLastWin32Error());
}
_hasPreviousClipRect =
clipRectRead && !IsVirtualDesktopBounds(_previousClipRect);
_isCaptureSessionActive = true;View on GitHub (pinned to a7cb36712d)