{"record":{"id":"37dc7f5d8817a428","repo":"babalae/better-genshin-impact","slug":"error-37dc7f","errorCode":null,"errorMessage":"鼠标限制区域必须具有有效宽度和高度。","messagePattern":"鼠标限制区域必须具有有效宽度和高度。","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"BetterGenshinImpact/Core/Monitor/LocalCursorCapture.cs","lineNumber":34,"sourceCode":"    private const int SmXVirtualScreen = 76;\n    private const int SmYVirtualScreen = 77;\n    private const int SmCxVirtualScreen = 78;\n    private const int SmCyVirtualScreen = 79;\n\n    private NativeRect _previousClipRect;\n    private Rectangle _appliedBounds;\n    private bool _hasPreviousClipRect;\n    private bool _isCaptureSessionActive;\n    private bool _isRestrictionApplied;\n    private bool _isDisposed;\n    private int _cursorHideCallCount;\n\n    internal void Capture(Rectangle bounds)\n    {\n        ObjectDisposedException.ThrowIf(_isDisposed, this);\n        if (bounds.Width <= 0 || bounds.Height <= 0)\n        {\n            throw new ArgumentOutOfRangeException(\n                nameof(bounds),\n                bounds,\n                \"鼠标限制区域必须具有有效宽度和高度。\");\n        }\n\n        if (!_isCaptureSessionActive)\n        {\n            var clipRectRead = NativeMethods.GetClipCursor(out _previousClipRect);\n            if (!clipRectRead)\n            {\n                logger.LogWarning(\n                    \"读取现有鼠标限制区域失败，Win32Error: {Win32Error}\",\n                    Marshal.GetLastWin32Error());\n            }\n\n            _hasPreviousClipRect =\n                clipRectRead && !IsVirtualDesktopBounds(_previousClipRect);\n            _isCaptureSessionActive = true;","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/babalae/better-genshin-impact/blob/a7cb36712dcb409be610257d877fcea3597e9d6b/BetterGenshinImpact/Core/Monitor/LocalCursorCapture.cs#L16-L52","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n_cursorCapture.Capture(rect);\n\n// after\nif (rect.Width <= 0 || rect.Height <= 0) return;\n_cursorCapture.Capture(rect);","handlingStrategy":"validation","validationCode":"if (bounds.Width <= 0 || bounds.Height <= 0) return; // skip invalid region\n_cursorCapture.Capture(bounds);","typeGuard":"static bool IsValidClipRect(Rectangle r) => r.Width > 0 && r.Height > 0;","tryCatchPattern":null,"preventionTips":["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."],"tags":["mouse","win32","clipcursor","argument-validation","monitor"],"backgroundTag":null,"analyzedSha":"a7cb36712dcb409be610257d877fcea3597e9d6b","analyzedAt":"2026-08-13T16:44:57.548Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}