如何以编程方式在 Windows 中全局隐藏/显示鼠标光标?

问题描述 投票:0回答:2

在某些应用程序中,例如记事本,当您开始键入时,鼠标光标会消失。然后只要您移动鼠标,光标就会重新出现。这很棒,因为很多时候,鼠标光标会妨碍打字,尤其是在使用大的倒置光标时。

但是,这在大多数现代应用程序中不起作用;仅那些使用常见 Windows 控件(例如文本区域控件)的控件。

我想创建一个在后台运行的应用程序,它全局监听任何按键,无论哪个应用程序位于前台,并隐藏鼠标指针,直到鼠标再次物理移动。

我尝试过到处搜索,但每个解决方案要么根本不执行任何操作,要么仅在光标位于测试应用程序窗口上方时隐藏光标(不适用于所有窗口)。我尝试了 ChatGPT,它提供了无法工作的损坏的解决方案。我已经尝试过 AutoHotkey、C#、C++ 中的“解决方案”,但没有成功。

我不在乎用什么编程语言,只要能实现这个就行。请不要发布仅隐藏应用程序本身光标的解决方案。当按下任何键盘按键时,无论哪个应用程序具有焦点,也无论光标位于何处,光标都必须消失。移动鼠标后,光标应重新出现在上次存在的位置(不应传送到其他地方)。

windows.h 的 HideCursor() 函数不起作用。 CreateCursor/SetSystemCursor 不起作用。以管理员身份运行脚本/应用程序不起作用。

我当前的解决方案是简单地将光标移动距当前位置约100px。这通常可以让它不再妨碍打字,但有时它会悬停在弹出的其他东西上,所以这不是最佳解决方案。

非常感谢您的任何工作建议。

windows mouse mouse-cursor
2个回答
1
投票

如果您不介意失去点击功能,一个可能的解决方案是创建一个小的透明窗口并使用

SetWindowPos
将其设置为最顶层模式。

然后,将光标隐藏在其中(或将形状更改为透明像素)。

使用

GetCursorPos
获取光标位置,然后进行循环不断更新窗口位置以匹配光标位置。

通过此设置,光标不会离开隐藏它的区域。

注意:不要忘记将窗口大小的一半添加到鼠标位置,使其位于中心。


0
投票

我相信这个 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

© www.soinside.com 2019 - 2024. All rights reserved.