web-dev-qa-db-ja.com

Windowsでマウスの垂直感度のみを調整するにはどうすればよいですか?

私は何年もの間、安いLogitechM215ワイヤレスマウスを持っていました。それでも完全に機能します。

私のラップトップ用に、同じパフォーマンスを期待して、Logitechのマウスを2つ追加購入しました。問題:垂直方向の感度は両方で厄介です。 x軸に沿った感度は素晴らしいですが、y軸に沿った感度は私がそれらを使用するのが嫌いなほど遅いです。 (この問題はデスクトップPCでも繰り返されます。)

私は知っています Windowsでポインタ速度を調整する方法 、しかし私は両方の軸をスケーリングするつもりはありません-y軸だけです。 どうやらUbuntuでこれを行う方法 があり、私は今尋ねているのと本質的に同じ質問をする多くのフォーラムを精査しましたが、役に立ちませんでした。この質問 ここでも尋ねられました 、しかしコメントは何の助けにもなりませんでした。

誰かがWindows8.1内でこれを行う方法を知っていますか?レジストリを変更したり、役立つソフトウェアをダウンロードしたりすることに慣れています。

2
JMTusk_16

私はM310を持っていて、同じ問題に取り組んできました。圧縮空気でレンズを掃除することで成功した人もいます。しかし、私にとっては、実際には私のマウスパッドでした...パッドを90度回転させて、効果があるかどうかを確認します。

2
jason

これは完璧ではないオプションですが、役に立ちます。これは元々、ユーザーNextronによって https://autohotkey.com/board/topic/13531-adjusting-mouse-sensitivevity-via-hotkey/ で提供されていました。

このスクリプトは、WindowsでXとYの感度を個別に変更する余裕を与え、すべてのマウスとすべてのバージョンのWindowsで機能します。感度の整数倍を使用する必要があるという点で完全ではなく、マウスの動きのパルスを乗算することによって動作します。

  1. 自動ホットキーをインストールします。
  2. 以下のautohotkeyスクリプトを変更します。 new MouseAccelerator(0, 1)と表示されている場合は、それをnew MouseAccelerator (<amount to multiply X sensitivity by> - 1, <amount to multiply Y sensitivity by> - 1)に変更します。例えば。 MouseAccelerator(0, 1)はYの動きを2倍にしますが、Xの動きには影響しません。MouseAccelerator(2, 1)は水平方向の動きを3倍にし、垂直方向の動きを2倍にします。
  3. 変更したスクリプトを実行します。ヒット F12 シャットダウンしたいとき。

    ;The SendInput DllCall is specifically 32-bit. So check for the correct bitness of AutoHotkey and if not, try to run the right one.
    If (A_PtrSize=8){
        SplitPath, A_AhkPath,,Dir
        Run %Dir%\AutoHotkeyU32.exe %A_ScriptFullPath%
        ExitApp
    }
    
    ;Call below to accelerate the mouse input. The first two parameters are the integer factors of artificial amplification added on top of the physical input.
    ;The first is for horizontal/x-axis movement, the second for vertical/y-axis movement.
    new MouseAccelerator(0, 1)
    
    F12::ExitApp
    
    
    ; Gets called when mouse moves or stops
    ; x and y are DELTA moves (Amount moved since last message), NOT coordinates.
    MouseAcceleratorEvent(x := 0, y := 0, accelerationx := 2, accelerationy := 2){
        static MouseAcceleratorPaused
        If !(MouseAcceleratorPaused){
            MouseAcceleratorPaused:=true
            VarSetCapacity( MouseInput, 28, 0 )
            NumPut( x * accelerationx, MouseInput, 4, "Int" ) ; dx
            NumPut( y * accelerationy, MouseInput, 8, "Int" ) ; dy
            NumPut( 0x0001, MouseInput, 16, "UInt" ) ; MOUSEEVENTF_MOVE = 0x0001
            DllCall("SendInput", "UInt", 1, "UInt", &MouseInput, "Int", 28 )
            sleep,-1
            MouseAcceleratorPaused:=false
        }
    }
    
    ; ================================== LIBRARY ========================================
    ; Instantiate this class and pass it a func name or a Function Object
    ; The specified function will be called with the delta move for the X and Y axes
    ; Normally, there is no windows message "mouse stopped", so one is simulated.
    ; After 10ms of no mouse movement, the callback is called with 0 for X and Y
    ; https://autohotkey.com/boards/viewtopic.php?f=19&t=10159
    Class MouseAccelerator {
        __New(accelerationx:=2, accelerationy:=2, callback:="MouseAcceleratorEvent"){
            static DevSize := 8 + A_PtrSize
            static RIDEV_INPUTSINK := 0x00000100
    
            this.TimeoutFn := this.TimeoutFunc.Bind(this)
    
            this.Callback := callback
            this.Accelerationx := accelerationx
            this.Accelerationy := accelerationy
            ; Register mouse for WM_INPUT messages.
            VarSetCapacity(RAWINPUTDEVICE, DevSize)
            NumPut(1, RAWINPUTDEVICE, 0, "UShort")
            NumPut(2, RAWINPUTDEVICE, 2, "UShort")
            NumPut(RIDEV_INPUTSINK, RAWINPUTDEVICE, 4, "Uint")
            ; WM_INPUT needs a hwnd to route to, so get the hwnd of the AHK Gui.
            ; It doesn't matter if the GUI is showing, it still exists
            Gui +hwndhwnd
            NumPut(hwnd, RAWINPUTDEVICE, 8, "Uint")
    
            this.RAWINPUTDEVICE := RAWINPUTDEVICE
            DllCall("RegisterRawInputDevices", "Ptr", &RAWINPUTDEVICE, "UInt", 1, "UInt", DevSize )
            fn := this.MouseMoved.Bind(this)
            OnMessage(0x00FF, fn)
        }
    
        __Delete(){
            static RIDEV_REMOVE := 0x00000001
            static DevSize := 8 + A_PtrSize
            RAWINPUTDEVICE := this.RAWINPUTDEVICE
            NumPut(RIDEV_REMOVE, RAWINPUTDEVICE, 4, "Uint")
            DllCall("RegisterRawInputDevices", "Ptr", &RAWINPUTDEVICE, "UInt", 1, "UInt", DevSize )
        }
    
        ; Called when the mouse moved.
        ; Messages tend to contain small (+/- 1) movements, and happen frequently (~20ms)
        MouseMoved(wParam, lParam){
            ; RawInput statics
            static DeviceSize := 2 * A_PtrSize, iSize := 0, sz := 0, offsets := {x: (20+A_PtrSize*2), y: (24+A_PtrSize*2)}, uRawInput
    
            static axes := {x: 1, y: 2}
    
            ; Find size of rawinput data - only needs to be run the first time.
            if (!iSize){
                r := DllCall("GetRawInputData", "UInt", lParam, "UInt", 0x10000003, "Ptr", 0, "UInt*", iSize, "UInt", 8 + (A_PtrSize * 2))
                VarSetCapacity(uRawInput, iSize)
            }
            sz := iSize ; param gets overwritten with # of bytes output, so preserve iSize
            ; Get RawInput data
            r := DllCall("GetRawInputData", "UInt", lParam, "UInt", 0x10000003, "Ptr", &uRawInput, "UInt*", sz, "UInt", 8 + (A_PtrSize * 2))
    
            x := NumGet(&uRawInput, offsets.x, "Int")
            y := NumGet(&uRawInput, offsets.y, "Int")
    
            this.Callback.(x, y, this.Accelerationx, this.Accelerationy)
    
            ; There is no message for "Stopped", so simulate one
            fn := this.TimeoutFn
            SetTimer, % fn, -10
        }
    
        TimeoutFunc(){
            this.Callback.(0, 0)
        }
    
    }
    
1
Jsulliva83

これは、デバイスごとに感度を上げたり下げたりすることができるコードです(1つのマウスの感度を下げることはできますが、別のマウスには影響を与えません)。
ブロッキングにはRawInput(C#DLLで実装)とSetWindowsHookEx(純粋なAHKで実装))を使用します。

この方法が機能するようになったのはごく最近のことなので、問題や改善できることがあるかもしれません。私の取り組みを詳しく説明しているスレッド ここ がAHKフォーラムにあります-そこにはもっと最新のバージョンや機能豊富なバージョンがあるかもしれません。

C#コード
新しいクラスライブラリプロジェクトを開始し、NuGetを介してSharpDX.RawInputへの参照を追加しますDLLはMouseDelta.dllと呼ばれ、同じフォルダーにある必要があります。
ビルドすると、2つのSharpDXDLLがビルドフォルダーに吐き出されるはずです。スクリプトにもこれらが必要です。

using System;
using System.Windows.Forms;
using SharpDX.Multimedia;
using SharpDX.RawInput;
using System.Threading;
using System.Collections.Generic;

public class MouseDelta
{
    private readonly Thread messagePump;

    public dynamic relativeMoveCallback;
    public dynamic wheelCallback;

    static private Dictionary<IntPtr, string> seenMice = new Dictionary<IntPtr, string>();
    static private string subscribedMouse = null;

    private AutoResetEvent messagePumpRunning = new AutoResetEvent(false);

    public MouseDelta()
    {
        // start message pump in its own thread  
        messagePump = new Thread(RunMessagePump) { Name = "ManualMessagePump" };
        messagePump.Start();
        messagePumpRunning.WaitOne();
    }

    public void SubscribeRelativeMove(dynamic callback, string mouseId = null)
    {
        SetSubscribedMouse(mouseId);
        relativeMoveCallback = callback;
    }

    public void SubscribeWheel(dynamic callback, string mouseId = null)
    {
        SetSubscribedMouse(mouseId);
        wheelCallback = callback;
    }

    private void SetSubscribedMouse(string mouseId)
    {
        if (mouseId != null)
        {
            subscribedMouse = mouseId == "0" ? null : mouseId;
        }
    }

    // the message pump thread  
    private void RunMessagePump()
    {
        // Create control to handle windows messages   
        MessageHandler messageHandler = new MessageHandler();

        // Register for RawInput mouse messages
        Device.RegisterDevice(UsagePage.Generic, UsageId.GenericMouse, DeviceFlags.InputSink, messageHandler.Handle);
        Device.MouseInput += ProcessMouseInput;

        messagePumpRunning.Set();
        Application.Run();
    }

    private void ProcessMouseInput(object sender, MouseInputEventArgs args)
    {
        //Console.WriteLine(string.Format("(x,y):({0},{1}) Buttons: {2} State: {3} Wheel: {4}\r\n", args.X, args.Y, args.ButtonFlags, args.Mode, args.WheelDelta));
        // Handle mouse filtering
        if (!seenMice.ContainsKey(args.Device))
        {
            DeviceInfo info = null;
            var devices = Device.GetDevices();
            foreach (var dev in devices)
            {
                if (dev.Handle == args.Device)
                {
                    info = dev;
                    break;
                }
            }
            if (info == null)
                return;
            string item = info.DeviceName;
            item = item.Substring(4);

            string[] split = item.Split('#');

            //string id_01 = split[0];    // ACPI (Class code)
            string id_02 = split[1];    // PNP0303 (SubClass code)
                                        //string id_03 = split[2];    // 3&13c0b0c5&0 (Protocol code)

            seenMice.Add(args.Device, id_02);
        }

        if (subscribedMouse != null && subscribedMouse != seenMice[args.Device])
        {
            return;
        }

        // Fire appropriate Callback
        if (args.Mode == MouseMode.MoveRelative && relativeMoveCallback != null && (Math.Abs(args.X) + Math.Abs(args.Y) > 0))
        {
            relativeMoveCallback(args.X, args.Y, seenMice[args.Device]);
        }
        else if (args.WheelDelta != 0 && wheelCallback != null)
        {
            wheelCallback(args.WheelDelta / 120, seenMice[args.Device]);
        }
    }
}

// Useful SO post on handling messages - code for overriding WndProc
// https://stackoverflow.com/questions/2443867/message-pump-in-net-windows-service
// Although the above code is not quite complete. This blog post has the implementation for MessageData
// http://joe-bq-wang.iteye.com/blog/1882661

// However, by overriding WndProc, we have to process all messages, and then you do not get a SharpDX object..
// ... you just appear to get a raw WM_INPUT message

// For now, this seems to serve our purposes
internal class MessageHandler : NativeWindow
{
    public MessageHandler()
    {
        CreateHandle(new CreateParams());
    }
}

メインのAHKスクリプト(これを編集するだけで済みます)

; ================= USER SCRIPT ================
#SingleInstance force
#NoEnv
#include CLR.ahk
#include MouseDelta.ahk
OnExit, UnhookAndClose

GoSub, Hook

Gui, Add, Text, , Select Mouse:
mdw := new MouseDeltaWrapper("x+5 yp-3 w200")
mdw.SubscribeMove(Func("MoveEvent"))
mdw.SubscribeWheel(Func("WheelEvent"))
Gui, Show
return

^Esc::
UnhookAndClose:
GuiClose:
    GoSub, UnHook
    ExitApp

Hook:
    hHookMouse := SetWindowsHookEx(WH_MOUSE_LL  := 14, RegisterCallback("MouseMove", "Fast"))
    return

UnHook:
    UnhookWindowsHookEx(hHookMouse)
    return

MoveEvent(x, y, mouseId){
    Global mdw
    if (mdw.SelectedMouse == 0 || mdw.SelectedMouse == mouseId){
        DllCall("mouse_event",uint,1,int, x ,int, y,uint,0,int,0)
    }
}

WheelEvent(value, mouseId){
    ToolTip % "Wheel: " value ", ID: " mouseId
}

AHKラッパー
同じフォルダにMouseDelta.ahkとして保存

; ================= WRAPPER LIBRARY ================
class MouseDeltaWrapper {
    SeenMice := {}
    SelectedMouse := 0
    MoveCallback := 0

    __New(guiOptions := "", dllPath := "MouseDelta.dll"){
        this.Callback := callback

        Gui, +HwndHwnd
        this.GuiHwnd := Hwnd

        Gui, Add, DDL, % "hwndhDDL " guiOptions, Any||
        this.hDDL := hDDL

        fn := this._UserSelectedMouse.Bind(this)
        GuiControl, +g, % this.hDDL, % fn

        asm := CLR_LoadLibrary(dllPath)
        md := asm.CreateInstance("MouseDelta")

        md.SubscribeRelativeMove(this._MoveEvent.Bind(this))
        md.SubscribeWheel(this._WheelEvent.Bind(this))
        this.md := md

        this._UserSelectedMouse()
    }

    SubscribeMove(callback){
        this.MoveCallback := callback
    }

    SubscribeWheel(callback){
        this.WheelCallback := callback
    }

    _UserSelectedMouse(){
        GuiControlGet, mouseId, , % this.hDDL
        this.SelectedMouse := mouseId == "Any" ? 0 : mouseId
        if (this.MoveCallback != 0)
            this.md.SubscribeRelativeMove(this._MoveEvent.Bind(this), this.SelectedMouse)
        if (this.WheelCallback != 0)
            this.md.SubscribeWheel(this._WheelEvent.Bind(this), this.SelectedMouse)
    }

    _AddMouseToDDL(mouseId){
        GuiControl, , % this.hDDL, % mouseId
    }

    _UpdateMice(mouseId){
        if (!this.SeenMice.HasKey(mouseId)){
            this.SeenMice[mouseId] := 1
            this._AddMouseToDDL(mouseId)
        }
    }

    _MoveEvent(x, y, mouseId){
        this._UpdateMice(mouseId)
        if (this.MoveCallback != 0 && (this.SelectedMouse == 0 || this.SelectedMouse == mouseId)){
            this.MoveCallback.Call(x, y, mouseId)
        }
    }

    _WheelEvent(value, mouseId){
        this._UpdateMice(mouseId)
        if (this.WheelCallback != 0 && (this.SelectedMouse == 0 || this.SelectedMouse == mouseId)){
            this.WheelCallback.Call(value, mouseId)
        }
    }
}

MouseMove(nCode, wParam, lParam)
{
    Critical
    SetFormat, Integer, D
    If !nCode && (wParam = 0x200){
        ; Mouse movement - process
        if (NumGet(lParam+0, 12, "int")){
            ; if the LLMHF_INJECTED flag is set, this is "injected" input (Came from mouse_event)
            ; Let this input through
            Return CallNextHookEx(nCode, wParam, lParam)
        } else {
            ; Block the input
            Return 1
        }
    } else {
        ; Other mouse message - let through
        Return CallNextHookEx(nCode, wParam, lParam)
    }
}

SetWindowsHookEx(idHook, pfn)
{
    ;Return DllCall("SetWindowsHookEx", "int", idHook, "Uint", pfn, "Uint", DllCall("GetModuleHandle", "Uint", 0), "Uint", 0)
    ;The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process
    DllCall("SetWindowsHookEx", "int", idHook, "Uint", pfn, "Uint", 0, "Uint", 0)
}

UnhookWindowsHookEx(hHook)
{
    Return DllCall("UnhookWindowsHookEx", "Uint", hHook)
}

CallNextHookEx(nCode, wParam, lParam, hHook = 0)
{
    Return DllCall("CallNextHookEx", "Uint", hHook, "int", nCode, "Uint", wParam, "Uint", lParam)
}

CLRライブラリ-AHKがC#DLLと相互運用できるようにします。
これをCLR.ahkとして同じフォルダーまたはAHKLibフォルダーに保存します

; ==========================================================
;                  .NET Framework Interop
;      http://www.autohotkey.com/forum/topic26191.html
; ==========================================================
;
;   Author:     Lexikos
;   Version:    1.2
;   Requires:   AutoHotkey_L v1.0.96+
;
; Modified by evilC for compatibility with AHK_H as well as AHK_L
; "null" is a reserved Word in AHK_H, so did search & Replace from "null" to "_null"
CLR_LoadLibrary(AssemblyName, AppDomain=0)
{
    if !AppDomain
        AppDomain := CLR_GetDefaultDomain()
    e := ComObjError(0)
    Loop 1 {
        if Assembly := AppDomain.Load_2(AssemblyName)
            break
        static _null := ComObject(13,0)
        args := ComObjArray(0xC, 1),  args[0] := AssemblyName
        typeofAssembly := AppDomain.GetType().Assembly.GetType()
        if Assembly := typeofAssembly.InvokeMember_3("LoadWithPartialName", 0x158, _null, _null, args)
            break
        if Assembly := typeofAssembly.InvokeMember_3("LoadFrom", 0x158, _null, _null, args)
            break
    }
    ComObjError(e)
    return Assembly
}

CLR_CreateObject(Assembly, TypeName, Args*)
{
    if !(argCount := Args.MaxIndex())
        return Assembly.CreateInstance_2(TypeName, true)

    vargs := ComObjArray(0xC, argCount)
    Loop % argCount
        vargs[A_Index-1] := Args[A_Index]

    static Array_Empty := ComObjArray(0xC,0), _null := ComObject(13,0)

    return Assembly.CreateInstance_3(TypeName, true, 0, _null, vargs, _null, Array_Empty)
}

CLR_CompileC#(Code, References="", AppDomain=0, FileName="", CompilerOptions="")
{
    return CLR_CompileAssembly(Code, References, "System", "Microsoft.CSharp.CSharpCodeProvider", AppDomain, FileName, CompilerOptions)
}

CLR_CompileVB(Code, References="", AppDomain=0, FileName="", CompilerOptions="")
{
    return CLR_CompileAssembly(Code, References, "System", "Microsoft.VisualBasic.VBCodeProvider", AppDomain, FileName, CompilerOptions)
}

CLR_StartDomain(ByRef AppDomain, BaseDirectory="")
{
    static _null := ComObject(13,0)
    args := ComObjArray(0xC, 5), args[0] := "", args[2] := BaseDirectory, args[4] := ComObject(0xB,false)
    AppDomain := CLR_GetDefaultDomain().GetType().InvokeMember_3("CreateDomain", 0x158, _null, _null, args)
    return A_LastError >= 0
}

CLR_StopDomain(ByRef AppDomain)
{   ; ICorRuntimeHost::UnloadDomain
    DllCall("SetLastError", "uint", hr := DllCall(NumGet(NumGet(0+RtHst:=CLR_Start())+20*A_PtrSize), "ptr", RtHst, "ptr", ComObjValue(AppDomain))), AppDomain := ""
    return hr >= 0
}

; NOTE: IT IS NOT NECESSARY TO CALL THIS FUNCTION unless you need to load a specific version.
CLR_Start(Version="") ; returns ICorRuntimeHost*
{
    static RtHst := 0
    ; The simple method gives no control over versioning, and seems to load .NET v2 even when v4 is present:
    ; return RtHst ? RtHst : (RtHst:=COM_CreateObject("CLRMetaData.CorRuntimeHost","{CB2F6722-AB3A-11D2-9C40-00C04FA30A3E}"), DllCall(NumGet(NumGet(RtHst+0)+40),"uint",RtHst))
    if RtHst
        return RtHst
    EnvGet SystemRoot, SystemRoot
    if Version =
        Loop % SystemRoot "\Microsoft.NET\Framework" (A_PtrSize=8?"64":"") "\*", 2
            if (FileExist(A_LoopFileFullPath "\mscorlib.dll") && A_LoopFileName > Version)
                Version := A_LoopFileName
    if DllCall("mscoree\CorBindToRuntimeEx", "wstr", Version, "ptr", 0, "uint", 0
    , "ptr", CLR_GUID(CLSID_CorRuntimeHost, "{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}")
    , "ptr", CLR_GUID(IID_ICorRuntimeHost,  "{CB2F6722-AB3A-11D2-9C40-00C04FA30A3E}")
    , "ptr*", RtHst) >= 0
        DllCall(NumGet(NumGet(RtHst+0)+10*A_PtrSize), "ptr", RtHst) ; Start
    return RtHst
}

;
; INTERNAL FUNCTIONS
;

CLR_GetDefaultDomain()
{
    static defaultDomain := 0
    if !defaultDomain
    {   ; ICorRuntimeHost::GetDefaultDomain
        if DllCall(NumGet(NumGet(0+RtHst:=CLR_Start())+13*A_PtrSize), "ptr", RtHst, "ptr*", p:=0) >= 0
            defaultDomain := ComObject(p), ObjRelease(p)
    }
    return defaultDomain
}

CLR_CompileAssembly(Code, References, ProviderAssembly, ProviderType, AppDomain=0, FileName="", CompilerOptions="")
{
    if !AppDomain
        AppDomain := CLR_GetDefaultDomain()

    if !(asmProvider := CLR_LoadLibrary(ProviderAssembly, AppDomain))
    || !(codeProvider := asmProvider.CreateInstance(ProviderType))
    || !(codeCompiler := codeProvider.CreateCompiler())
        return 0

    if !(asmSystem := (ProviderAssembly="System") ? asmProvider : CLR_LoadLibrary("System", AppDomain))
        return 0

    ; Convert | delimited list of references into an array.
    StringSplit, Refs, References, |, %A_Space%%A_Tab%
    aRefs := ComObjArray(8, Refs0)
    Loop % Refs0
        aRefs[A_Index-1] := Refs%A_Index%

    ; Set parameters for compiler.
    prms := CLR_CreateObject(asmSystem, "System.CodeDom.Compiler.CompilerParameters", aRefs)
    , prms.OutputAssembly          := FileName
    , prms.GenerateInMemory        := FileName=""
    , prms.GenerateExecutable      := SubStr(FileName,-3)=".exe"
    , prms.CompilerOptions         := CompilerOptions
    , prms.IncludeDebugInformation := true

    ; Compile!
    compilerRes := codeCompiler.CompileAssemblyFromSource(prms, Code)

    if error_count := (errors := compilerRes.Errors).Count
    {
        error_text := ""
        Loop % error_count
            error_text .= ((e := errors.Item[A_Index-1]).IsWarning ? "Warning " : "Error ") . e.ErrorNumber " on line " e.Line ": " e.ErrorText "`n`n"
        MsgBox, 16, Compilation Failed, %error_text%
        return 0
    }
    ; Success. Return Assembly object or path.
    return compilerRes[FileName="" ? "CompiledAssembly" : "PathToAssembly"]
}

CLR_GUID(ByRef GUID, sGUID)
{
    VarSetCapacity(GUID, 16, 0)
    return DllCall("ole32\CLSIDFromString", "wstr", sGUID, "ptr", &GUID) >= 0 ? &GUID : ""
}
0
Clive Galway

Razer Synapseに似たLogitechマウス用のカスタムソフトウェアはありますか?そこにカスタム感度設定を見つけることができるかもしれません。

0
CammRobb

私はここに私の同様のケースの解決策を置きたいと思います。私は垂直方向と水平方向の感度の間にかなりの不均衡がありました。

最後に、「マウスのプロパティ」の「ポインタの精度を上げる」のチェックを外して、バランスを取り戻しました。

それはかなり不明確でした。私は多くの時間を費やして、ほとんど運が良かったので解決策を見つけたので、ここにそれを固定したいと思います。

0