Windows에서 세로 마우스 민감도 만 조정할 수 있습니까?


2

저는 몇 년 동안 싼 Logitech M215 무선 마우스를 사용했습니다. 그것은 여전히 ​​완벽하게 작동합니다.

내 노트북의 경우 몇 가지 추가 마우스 - Logitech -을 구입하여 동일한 성능을 기대합니다. 문제 : 수직 감도는 두 가지 모두에있어 어색하다. x 축의 감도는 좋지만 y 축의 감도는 느리므로 감도는 느립니다. (이 문제는 내 데스크톱 PC에서 반복됩니다.)

알아 Windows에서 포인터 속도를 조정하는 방법 ,하지만 나는 두 축 - y 축 만 축척 할 필요가 없습니다. 저기있다. Ubuntu에서이 작업을 수행하는 방법 , 나는 많은 질문을 던져 본질적으로 내가 지금 묻고있는 질문을 무조건 요구하고있다. 이 질문 심지어 여기에서 물었다 , 그러나 코멘트는 어떤 도움이 아니었다.

누구든지 Windows 8.1에서이 작업을 수행 할 수있는 방법을 알고 있습니까? 어떤 레지스트리 변경 / 소프트웨어를 도울 수있는 다운로드를하는 데 익숙합니다.


이것은 교체 / 환불이 아니라면 최소한 기술 지원에 연락해야하는 결함과 비슷합니다. 왜이 문제를 해결하려고합니까? 수직 민감도를 높이는 방법을 찾더라도 하드웨어 문제가있는 경우 해당 축에서 많은 해상도를 잃어 버릴 수 있습니다 (이전에 수직 감도를 어떻게 든 떨어 뜨린 것과 같은 소프트웨어 / 설정 문제인 경우 기술 지원을 통해 올바른 옵션을 찾을 수 있습니다).
Fire Lancer

답변:


2

나는 M310을 가지고 있으며 같은 문제를 다루고있다. 일부 사람들은 압축 공기로 렌즈를 청소하여 성공을 거두었습니다. 나를 위해, 실제로, 그건 내 마우스 패드였습니다 ... 패드를 90 도로 돌려보고 효과가 있는지 확인하십시오.


코멘트 주셔서 감사합니다! 하지만 모든면에서 일관되게 발생합니다. 특정 텍스처에 개선점이 없습니다. 내가 집에 도착했을 때 나는 압축 공기 아이디어를 시험해 볼 것이다. 그리고 그것이 좋은 것이라면 나는 새롭게 할 것이다!
JMTusk_16

압축 공기가 나를 위해 일했습니다. 감사!
Chad Carisch

0

Logitech Mice 용 Razer Synapse와 유사한 소프트웨어가 있습니까? 거기에서 사용자 지정 감도 설정을 찾을 수 있습니다.


내가 아는 특정 마이스에 대한 맞춤 소프트웨어가 없습니다. Logitech은 고급 제품을 위해이 제품을 생산합니다.
JMTusk_16

0

다음은 장치 당 기준으로 감도를 높이고 감도를 낮출 수있는 코드입니다 (하나의 마우스 감도는 낮추지 만 다른 감도는 떨어지지 않음).
블로킹을 위해 RawInput (속도를 위해 C # DLL에 구현 됨)과 SetWindowsHookEx (순수 AHK로 구현 됨)를 사용합니다.

최근에는이 방법을 사용하기 만 했으므로 개선 할 수있는 문제와 사안이있을 수 있습니다. 나는 실을 가지고있다. 이리 내 노력을 자세히 설명하는 AHK 포럼에 - 거기에 더 많은 최신 또는 기능이 풍부한 버전이있을 수 있습니다.

C # 코드
새로운 클래스 라이브러리 프로젝트를 시작하고, NuGet을 통해 SharpDX.RawInput에 대한 참조를 추가하십시오. DLL은 MouseDelta.dll이라고해야하며 같은 폴더에 있어야합니다.
빌드 할 때 두 개의 SharpDX DLL을 빌드 폴더에 침투시켜야합니다. 스크립트에도 이러한 파일이 필요할 것입니다.

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과 상호 작용할 수 있습니다.
동일한 폴더 또는 AHK Lib 폴더에 CLR.ahk로 저장하십시오.

; ==========================================================
;                  .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 : ""
}

수퍼 유저에 오신 것을 환영합니다. 게시물에 가장 중요한 정보를 포함 시키십시오. 흥미로운 자료로만 링크를 제공하십시오. 그것에 대해 더 자세히 읽어보십시오. 이리 .
styrofoam fly

답안에 스크립트를 포함시켜야합니다.
DavidPostill

답변에 필요한 모든 코드가 추가되었습니다.
Clive Galway

0

나는이 비슷한 상황에 대한 해결책을 제시하고자한다. 수직적 감도와 수평 감도 사이에는 상당한 불균형이있었습니다.

마지막으로, 나는 "마우스 속성"에서 "포인터 정밀도 향상"과 균형을 되찾았습니다.

그것은 아주 불분명했다. 많은 시간을 보내고 행운을 빌어 해결책을 찾았으니 여기에서 설명하고 싶습니다.


때로는 처음에 전원을 켜고 나중에 끌 필요가있는 것처럼 보입니다.
Leonid Dworzanski

이런 식으로 일을 계속합니다. 믿기지 않을 정도로 이상합니다.
Leonid Dworzanski

이 패치는 더 잘 작동합니다. donewmouseaccel.blogspot.ru/2010/03/...
Leonid Dworzanski

0

완벽하지는 않지만 여기에는 도움이되는 옵션이 있습니다. 그것은 원래 사용자 인 Nextron에 의해 제공되었습니다. https://autohotkey.com/board/topic/13531-adjusting-mouse-sensitivity-via-hotkey/ .

이 스크립트는 Windows에서 X 및 Y 감도를 독립적으로 수정할 수있는 여지를 제공하며 모든 마우스 및 모든 Windows 버전에서 작동합니다. 정수 배수의 감도를 사용해야한다는 점에서 완벽하지는 않으며 마우스 움직임 펄스를 곱하여 작동합니다.

  1. autohotkey를 설치하십시오.
  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 운동을 두 배로 늘리지 만 X 운동에는 영향을주지 않지만, MouseAccelerator(2, 1) 수평 운동을 세배로하고 수직 운동을 두 배로한다.
  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)
        }
    
    }
    
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.