在某些应用程序中,例如记事本,当您开始键入时,鼠标光标会消失。然后只要您移动鼠标,光标就会重新出现。这很棒,因为很多时候,鼠标光标会妨碍打字,尤其是在使用大的倒置光标时。
但是,这在大多数现代应用程序中不起作用;仅那些使用常见 Windows 控件(例如文本区域控件)的控件。
我想创建一个在后台运行的应用程序,它全局监听任何按键,无论哪个应用程序位于前台,并隐藏鼠标指针,直到鼠标再次物理移动。
我尝试过到处搜索,但每个解决方案要么根本不执行任何操作,要么仅在光标位于测试应用程序窗口上方时隐藏光标(不适用于所有窗口)。我尝试了 ChatGPT,它提供了无法工作的损坏的解决方案。我已经尝试过 AutoHotkey、C#、C++ 中的“解决方案”,但没有成功。
我不在乎用什么编程语言,只要能实现这个就行。请不要发布仅隐藏应用程序本身光标的解决方案。当按下任何键盘按键时,无论哪个应用程序具有焦点,也无论光标位于何处,光标都必须消失。移动鼠标后,光标应重新出现在上次存在的位置(不应传送到其他地方)。
windows.h 的 HideCursor() 函数不起作用。 CreateCursor/SetSystemCursor 不起作用。以管理员身份运行脚本/应用程序不起作用。
我当前的解决方案是简单地将光标移动距当前位置约100px。这通常可以让它不再妨碍打字,但有时它会悬停在弹出的其他东西上,所以这不是最佳解决方案。
非常感谢您的任何工作建议。
如果您不介意失去点击功能,一个可能的解决方案是创建一个小的透明窗口并使用
SetWindowPos
将其设置为最顶层模式。
然后,将光标隐藏在其中(或将形状更改为透明像素)。
使用
GetCursorPos
获取光标位置,然后进行循环不断更新窗口位置以匹配光标位置。
通过此设置,光标不会离开隐藏它的区域。
注意:不要忘记将窗口大小的一半添加到鼠标位置,使其位于中心。
我相信这个 AHK v2 脚本完全符合您的描述。除了媒体键和宏键等非标准键之外,我找不到不会触发光标隐藏的键盘键:
InstallKeybdHook
CoordMode("mouse", "screen")
OnExit (*) => SystemCursor("Show") ; Ensure the cursor is made visible when the script exits
oldX := 0
oldY := 0
loop {
if(A_TimeIdlePhysical < 25)
;A keyboard key has been pressed, hide cursor
SystemCursor("Hide")
MouseGetPos(&newX, &newY)
if (oldX != newX or oldY != newY)
;Mouse have changed position, show cursor
SystemCursor("Show")
oldX := newX
oldY := newY
Sleep(1)
}
SystemCursor(cmd) ; cmd = "Show|Hide|Toggle|Reload"
{
static visible := true, c := Map()
static sys_cursors := [32512, 32513, 32514, 32515, 32516, 32642
, 32643, 32644, 32645, 32646, 32648, 32649, 32650]
if (cmd = "Reload" or !c.Count) ; Reload when requested or at first call.
{
for i, id in sys_cursors
{
h_cursor := DllCall("LoadCursor", "Ptr", 0, "Ptr", id)
h_default := DllCall("CopyImage", "Ptr", h_cursor, "UInt", 2
, "Int", 0, "Int", 0, "UInt", 0)
h_blank := DllCall("CreateCursor", "Ptr", 0, "Int", 0, "Int", 0
, "Int", 32, "Int", 32
, "Ptr", Buffer(32 * 4, 0xFF)
, "Ptr", Buffer(32 * 4, 0))
c[id] := { default: h_default, blank: h_blank }
}
}
switch cmd
{
case "Show": visible := true
case "Hide": visible := false
case "Toggle": visible := !visible
default: return
}
for id, handles in c
{
h_cursor := DllCall("CopyImage"
, "Ptr", visible ? handles.default : handles.blank
, "UInt", 2, "Int", 0, "Int", 0, "UInt", 0)
DllCall("SetSystemCursor", "Ptr", h_cursor, "UInt", id)
}
}
“SystemCursor”函数可能让它看起来很吓人,但它只是从官方 DllCall 文档中批量复制的:https://www.autohotkey.com/docs/v2/lib/DllCall.htm