在 Windows 中配置鼠标的去抖时间

在 Windows 中配置鼠标的去抖时间

我的鼠标坏了,我懒得买一个新的。问题出在左键单击按钮上。一个简单的物理单击会导致 Windows 中多次单击。鼠标中已经有一个防抖电路来防止这种行为,但它不再有效。我如何在软件中增加防抖时间?或者换句话说,如果鼠标单击之间的时间小于 0.1 秒,我如何告诉 Windows 忽略多次鼠标单击。

答案1

免费(开源)工具自动热键允许用户编写与键盘和鼠标交互的自定义​​脚本。特别是,一位用户编写了一个名为“有故障的鼠标“(修复了 Wayback Machine 的链接) 可“设置鼠标的最小双击速度(防止单击被视为双击)”。它通过忽略间隔太近的多次点击来实现此目的。

安装 AutoHotkey 并加载脚本后,我自己的去抖动问题似乎已得到解决。

您可能需要调整DoubleClick_Min脚本顶部的参数,该参数决定鼠标事件之间的最短时间,以被视为两次独立的点击:我发现默认值会导致合法的双击被视为反弹。75然而, 的值似乎对我来说很合适。


编辑 2021-02-18:Buggy Mouse 链接已失效。不过,另一个用户DoubleClick_Min尽管变量被重命名,但 as 发布了指向看似等效代码的新链接DoubleClickMin_ms。它被完整地复制到此处,以防止将来腐烂。

/*
** Buggy-Mouse.ahk - Fix a buggy mouse. Stop it from double-clicking when you try to single-click.
**
**      NOTE: Please use this URL when linking to Buggy Mouse: r.secsrv.net/AutoHotkey/Scripts/Buggy-Mouse
**
**   Updated: Thu, Nov 1, 2012 --- 11/1/12, 10:19:19am EDT
**  Location: r.secsrv.net/AutoHotkey/Scripts/Buggy-Mouse
**
**  Keywords: mouse double clicks when I click once
**  Keywords: mouse double clicks when I single click
**  Keywords: mouse double clicks on its own
**  Keywords: mouse double clicks with one click
**  Keywords: mouse double clicks on single click
**  Keywords: mouse double clicks on one click
**  Keywords: mouse double-clicking when you single-click
**  Keywords: set mouse minimum double click speed
**  Keywords: debounce mouse
**
**    Author: JSLover - r.secsrv.net/JSLover - r.secsrv.net/JSLoverAHK
**
**      NOTE: Please use AutoHotkey 1.1+ (AutoHotkey_L) for this script!
**              AutoHotkey.com
**              L.AutoHotkey.net
**
**      NOTE: Compiled version available here: r.secsrv.net/AutoHotkey/Scripts/Buggy-Mouse.exe
**
*/
#SingleInstance force
OnExit, OnExit

;// **************************** Settings ****************************

;// Minimum double-click time. Any lower & it will be blocked (as being inhumanly fast).
DoubleClickMin_ms:=90

;// *** DISABLED *** ;// Minimum click after mouse-up time. Any lower & it will be blocked (as being inhumanly fast).
;// *** DISABLED *** ClickAfterMouseUpMin_ms:=100

;// **************************** /Settings ****************************

;// **************************** Advanded Settings ****************************

;// Enable logging if you need to report a bug.
;// Default (Disabled): Log=0
Log=0

;// Enable debugging if you want to see blocked/allowed clicks.
;// Default (Disabled): Debug=0
Debug=0

;// Enable this if you only want to see blocked clicks (when debugging is enabled).
;// Default (Enabled): Debug_OnlyBlocked=1
;// Note: Requires Debug (above) to be enabled (or no debugging will happen at all)
Debug_OnlyBlocked=1

;// **************************** /Advanded Settings ****************************

Gosub, OnStartup

;// *** Build Tray Menu ***

Text_ClicksBlocked=Clicks Blocked
Text_Debug=Debug
Text_Debug_OnlyBlocked=Debug (only blocked)

Menu, Tray, Add, %Text_ClicksBlocked%, BuggyMouse_MenuSelect_ClicksBlocked
    Text_ClicksBlocked_MenuCurrent:=Text_ClicksBlocked
    Menu, Tray, Default, %Text_ClicksBlocked%
Menu, Tray, Add, %Text_Debug%, BuggyMouse_MenuSelect_Debug
Menu, Tray, Add, %Text_Debug_OnlyBlocked%, BuggyMouse_MenuSelect_Debug_OnlyBlocked
    Menu, Tray, Disable, %Text_Debug_OnlyBlocked%

Menu, Tray, MainWindow
Menu, Tray, NoStandard
Menu, Tray, Add
Menu, Tray, Standard

;// *** /Build Tray Menu ***

;// BuggyMouse_Debug:=1
;// BuggyMouse_Debug_OnlyBlocked:=1
if (Debug) {
    Gosub, BuggyMouse_MenuSelect_Debug
}

if (Debug_OnlyBlocked) {
    Gosub, BuggyMouse_MenuSelect_Debug_OnlyBlocked
}
return

OnStartup:
logdir=%A_ScriptDir%
logfilename=%A_ScriptName%.log
logfile=%logdir%\%logfilename%

time:=time()
logmsg=
(LTrim
    %A_ScriptName%   Started`t`t%time%
    `  Status`t`tUpDn`t  Key`t`t`tReason`t`t`t`tWindow`n
)
log(logmsg)
return

OnExit:
time:=time()
logmsg=
(LTrim
    %A_ScriptName%    Exited`t`t%time%`n`n
)
log(logmsg)
ExitApp

*LButton::
*MButton::
*RButton::

A_ThisHotkey_VarSafe:=Hotkey_MakeVarSafe(A_ThisHotkey, "*")
A_ThisHotkey_NoModifiers:=Hotkey_RemoveModifiers(A_ThisHotkey)
;// A_ThisHotkey_Modifiers:=Hotkey_GetModifiers(A_ThisHotkey)
A_ThisHotkey_KeyName:=Hotkey_GetKeyName(A_ThisHotkey)

log_key:="Down`t" A_ThisHotkey "`t"
Critical
di++

TimeSinceLastMouseDown:=A_TickCount-LastMouseDown_ts

;// TimeSinceLastMouseUp:=A_TickCount-LastMouseUp_ts

DoubleClickTooFast:=TimeSinceLastMouseDown<=DoubleClickMin_ms

;// *** DISABLED *** ClickAfterMouseUpTooSoon:=(ClickAfterMouseUpMin_ms!="" && TimeSinceLastMouseUp<=ClickAfterMouseUpMin_ms)
;// if ((A_ThisHotkey==LastMouseDown && DoubleClickTooFast) || ClickAfterMouseUpTooSoon) {
if (A_ThisHotkey==LastMouseDown && (DoubleClickTooFast || ClickAfterMouseUpTooSoon)) {
;// if (A_TimeSincePriorHotkey<=DoubleClickMin_ms) {
    reason:=DoubleClickTooFast ? "DoubleClickTooFast" "(" TimeSinceLastMouseDown ")" "(" DoubleClickMin_ms ")"
            : ClickAfterMouseUpTooSoon ? "ClickAfterMouseUpTooSoon" "(" TimeSinceLastMouseUp ")" "(" ClickAfterMouseUpMin_ms ")"
            : "Unknown"
    msg=`nblocked (%reason%)
    blockeddown:=1
    BlockedCount_Down++
    BlockedCount_%A_ThisHotkey_VarSafe%++
    Gosub, BuggyMouse_UpdateStatus_ClicksBlocked

    log_action:="BLOCKED`t"
} else {
    reason:=""
    Send, {Blind}{%A_ThisHotkey_KeyName% DownTemp}
    msg=`nSent, {Blind}{%A_ThisHotkey_KeyName% DownTemp}`n`n
    (LTrim C
        if (%A_ThisHotkey%==%LastMouseDown% && (%DoubleClickTooFast% || %ClickAfterMouseUpTooSoon%))
    )

    log_action:="`tallowed"
}
    BuggyMouse_DebugMsg_down=%di%: %A_ThisHotkey%(%TimeSinceLastMouseDown%)%LastMouseDown%%msg%
    msg=
    Gosub, BuggyMouse_Debug
LastMouseDown:=A_ThisHotkey
LastMouseDown_ts:=A_TickCount

wininfo:=WinGetInfo("a")
log(log_action "`t`t" log_key "`t`t" reason "`t`t`t`t`t" wininfo "`n")
return

*LButton up::
*MButton up::
*RButton up::

A_ThisHotkey_VarSafe:=Hotkey_MakeVarSafe(A_ThisHotkey, "*")
A_ThisHotkey_NoModifiers:=Hotkey_RemoveModifiers(A_ThisHotkey)
;// A_ThisHotkey_Modifiers:=Hotkey_GetModifiers(A_ThisHotkey)
A_ThisHotkey_KeyName:=Hotkey_GetKeyName(A_ThisHotkey)

log_key:=" Up `t" A_ThisHotkey
Critical
ui++
TimeSinceLastMouseUp:=A_TickCount-LastMouseUp_ts
;// if (A_ThisHotkey=A_PriorHotkey && A_TimeSincePriorHotkey<=DoubleClickMin_ms) {
;// if (A_ThisHotkey=LastMouseUp && A_TimeSincePriorHotkey<=DoubleClickMin_ms) {
if (blockeddown) {
    msg=`nblocked
    blockedup:=1
    BlockedCount_Up++
    BlockedCount_%A_ThisHotkey_VarSafe%++
    Gosub, BuggyMouse_UpdateStatus_ClicksBlocked

    log_action:="BLOCKED`t"
} else {
    Send, {Blind}{%A_ThisHotkey_KeyName% up}
    msg=`nSent, {Blind}{%A_ThisHotkey_KeyName% up}
    log_action:="`tallowed"
}
;// if (BuggyMouse_Debug) {
    BuggyMouse_DebugMsg_up=%ui%: %A_ThisHotkey%(%TimeSinceLastMouseUp%)%LastMouseUp%%msg%
    msg=
    Gosub, BuggyMouse_Debug
;// }
blockeddown=
blockedup=
LastMouseUp:=A_ThisHotkey
LastMouseUp_ts:=A_TickCount

wininfo:=WinGetInfo("a")
log(log_action "`t`t" log_key "`t`t" reason "`t`t`t`t`t" wininfo "`n")
return

BuggyMouse_Debug_ShowLastMsg:
;// BuggyMouse_Debug_ShowLastMsg=1
BuggyMouse_Debug:
CoordMode, Tooltip
if (A_ThisLabel="BuggyMouse_Debug_ShowLastMsg"
        || (BuggyMouse_Debug && (!BuggyMouse_Debug_OnlyBlocked
            || (BuggyMouse_Debug_OnlyBlocked && (blockeddown||blockedup))))) {
    Tooltip, %BuggyMouse_DebugMsg_down%`n`n%BuggyMouse_DebugMsg_up%, 819, 619
} else {
    Tooltip
}
return

BuggyMouse_UpdateStatus_ClicksBlocked:
BlockedCount_Total:=BlockedCount_Down+BlockedCount_Up
Text_ClicksBlocked_MenuNew=%Text_ClicksBlocked%: %BlockedCount_Total%
Menu, Tray, Rename, %Text_ClicksBlocked_MenuCurrent%, %Text_ClicksBlocked_MenuNew%
Text_ClicksBlocked_MenuCurrent:=Text_ClicksBlocked_MenuNew
Menu, Tray, Tip, %Text_ClicksBlocked_MenuCurrent% - %A_ScriptName%
return

BuggyMouse_MenuSelect_ClicksBlocked:
msgbox, 64, ,
(LTrim C
    %Text_ClicksBlocked_MenuCurrent%

    Down(%BlockedCount_Down%)
    Up(%BlockedCount_Up%)

    LButton(%BlockedCount_LButton%)
    MButton(%BlockedCount_MButton%)
    RButton(%BlockedCount_RButton%)

    LButton up(%BlockedCount_LButton_up%)
    MButton up(%BlockedCount_MButton_up%)
    RButton up(%BlockedCount_RButton_up%)
)
return

BuggyMouse_MenuSelect_Debug:
BuggyMouse_Debug:=!BuggyMouse_Debug
Menu, Tray, ToggleCheck, %Text_Debug%
Menu, Tray, ToggleEnable, %Text_Debug_OnlyBlocked%
Tooltip
return

BuggyMouse_MenuSelect_Debug_OnlyBlocked:
BuggyMouse_Debug_OnlyBlocked:=!BuggyMouse_Debug_OnlyBlocked
Menu, Tray, ToggleCheck, %Text_Debug_OnlyBlocked%
Tooltip
return

Hotkey_MakeVarSafe(p_hotkey, p_ignorechars="") {
    replace:=p_hotkey

    StringReplace, replace, replace, $, % !InStr(p_ignorechars, "$") ? "KH_":""
    StringReplace, replace, replace, ~, % !InStr(p_ignorechars, "~") ? "PT_":""
    StringReplace, replace, replace, *, % !InStr(p_ignorechars, "*") ? "WC_":""

    StringReplace, replace, replace, <^>!, AltGr_
    StringReplace, replace, replace, <, L, a
    StringReplace, replace, replace, >, R, a
    StringReplace, replace, replace, &, and

    StringReplace, replace, replace, ^, Ctrl_, a
    StringReplace, replace, replace, +, Shift_, a
    StringReplace, replace, replace, #, Win_, a
    StringReplace, replace, replace, !, Alt_, a

    replace:=RegExReplace(replace, "i)[^a-z0-9_]", "_")

    p_hotkey:=replace

    return p_hotkey
}

Hotkey_GetModifiers(p_hotkey) {
    return RegExReplace(p_hotkey, "i)[\w\s]+$")
}

Hotkey_RemoveModifiers(p_hotkey) {
    return RegExReplace(p_hotkey, "i)^[^a-z0-9_]+")
}

Hotkey_GetKeyName(p_hotkey) {

    p_hotkey:=Hotkey_RemoveModifiers(p_hotkey)

    ;// Get string before 1st space...(removes "up" or "down" from name of key)
    Loop, Parse, p_hotkey, " "
    {
        p_hotkey:=A_LoopField
        break
    }

    return p_hotkey
}

log(p_msg, p_file="") {
    Global Log, logfile
    if (!Log) {
        return
    }
    if (p_file="") {
        p_file:=logfile
    }
    FileAppend, %p_msg%, %p_file%
}

time() {
    FormatTime, time, L1033, ddd, MMM d, yyyy --- M/d/yy h:mm:sstt
    return time
}

WinGetInfo(p_win, ByRef r_win_title="", ByRef r_win_class="") {
    WinGetTitle, win_title, %p_win%
    WinGetClass, win_class, %p_win%

    r_win_title:=(win_title ? win_title:"<no-title-info>")
    r_win_class:=(win_class ? win_class:"<no-class-info>")

    ;// wininfo:=(win_title ? win_title:"<no-title-info>") " - " (win_class ? win_class:"<no-class-info>")
    wininfo:=(win_class ? win_class:"<no-class-info>") ": " (win_title ? win_title:"<no-title-info>")
    return wininfo
}

;// #ScrollLock::log("*** PROBLEM ***`n")
^+#!F8::Gosub, BuggyMouse_Debug_ShowLastMsg
^+#!F9::Suspend
^+#!F12::ExitApp

/* ;// **************************** Changelog / Version History ****************************
**
**   Created: Fri, Apr 11, 2008 --- 4/11/08, 11:19:19am
**  Modified: Sat, Apr 12, 2008 --- 4/12/08, 5:38:19am
**  Modified: Sun, Jul 10, 2011 --- 7/10/11, 3:19:19am EDT
**      * Added blocking of "mouse down too soon after last mouse up"
**  Modified: Wed, Jul 20, 2011 --- 7/20/11, 1:19:19pm EDT
**  Modified: Thu, Aug 25, 2011 --- 8/25/11, 1:19:19am EDT
**      * Temporarily disabled "mouse down too soon after last mouse up" blocking, until I get it working.
**  Modified: Thu, Aug 25, 2011 --- 8/25/11, 2:38:19am EDT
**      * Updated Keywords for search engines
**  Modified: Sat, Aug 27, 2011 --- 8/27/11, 7:19:19am EDT
**      * Added Logging
**  Modified: Sat, Aug 27, 2011 --- 8/27/11, 2:38:19pm EDT
**      * Added Window Info to log
**  Modified: Sun, May 13, 2012 --- 5/13/12, 7:19:19pm EDT
**      * Added support for blocking mouse clicks while holding down keyboard keys
**  Modified: Mon, May 14, 2012 --- 5/14/12, 10:19:19am EDT
**      * Updated Hotkey_MakeVarSafe()
**  Modified: Tue, May 15, 2012 --- 5/15/12, 7:19:19am EDT
**      * Hotkey_MakeVarSafe(): Fixed error msg/incompatibility with AutoHotkey < 1.1
**  Modified: Thu, Nov 1, 2012 --- 11/1/12, 10:19:19am EDT
**      * Made Debugging default to Off
**      * Added "Debug" & "Debug_OnlyBlocked" to Settings section, for easier toggling of the default state
**
*/ ;// **************************** /Changelog / Version History ****************************

答案2

抱歉,我无法发表评论,但我想补充 daviddg 的回答。搜索 AutoHotkey 网站的脚本部分没有找到任何关于“Buggy Mouse”的内容。不过,我在这篇文章中找到了脚本: http://www.autohotkey.com/board/topic/82509-software-fix-for-double-clicking-mouse

脚本来源为:

LButton::
If (A_TimeSincePriorHotkey < 100) ;hyperclick
Return
sendinput {LButton down}
KeyWait, LButton
sendinput {LButton up}
Return

相关内容