【问题标题】:AutoComplete textbox and "Hide Pointer While Typing" in windowsWindows 中的自动完成文本框和“键入时隐藏指针”
【发布时间】:2010-12-16 15:09:44
【问题描述】:

应用程序如何禁用“键入时隐藏指针”选项?我遇到了光标隐藏的问题,并且在不按转义键或失去窗口焦点的情况下无法将其取回。该应用程序是用 C# 编写的并使用 WPF。不需要特定技术的答案,因为它很可能使用任何技术。

以下是场景:用户可以输入一个文本框,然后一个自动完成列表显示在该框下方。但是,一旦用户开始输入,他/她就不能再从下拉列表中选择一个项目,因为没有鼠标光标。

我注意到 Firefox 没有这种行为。例如,在地址栏中输入 URL 时,鼠标光标永远不会消失。我在其他地方也看到过这种行为,所以我知道这一定是可能的。

非常感谢任何帮助!

【问题讨论】:

    标签: c# wpf user-interface autocomplete mouse


    【解决方案1】:

    看起来像 win api 函数 SystemParametersInfo 会做你需要的;控制指针消失功能的参数是:

    SPI_GETMOUSEVANISH 和 SPI_SETMOUSEVANISH

    鼠标消失可访问性 已为 Windows Me 添加了功能 和 Windows XP。此功能隐藏 用户键入时的指针。这 当用户重新出现鼠标指针 移动鼠标。此功能保持 指针遮挡文本 例如,在电子邮件中输入 或其他文件。

    查看SystemParametersInfo Function msdn 上的描述以获取更多信息

    【讨论】:

      【解决方案2】:

      我通过设置断点发现,当您第一次在文本框中键入时,WPF 会读取公共SystemParameters.MouseVanish 属性,该属性调用SystemParametersInfo(SPI_GETMOUSEVANISH, ...) 以获取鼠标消失设置。对SystemParameters.MouseVanish 的后续调用使用缓存的值。

      两种可能的解决方案:

      1. 访问SystemParameters.MouseVanish,然后使用反射覆盖缓存结果,以便后续调用返回false。
      2. 调用 Win32 的 SystemParametersInfo(SPI_SETMOUSEVANISH, ...) 关闭消失(不通知),然后访问 SystemParameters.MouseVanish,然后调用 SystemParametersInfo(SPI_SETMOUSEVANISH, ...) 将其设置回之前的值(不通知)

      这些都可以在用户开始在文本框中输入之前的任何时间完成。

      以下是反射解决方案的外观:

      void LocallyDisableMouseVanish()
      {
        if(SystemParameters.MouseVanish)
          foreach(var field in typeof(SystemParameters).GetFields(BindingFlags.NonPublic | BindingFlags.Static)
            if(field.Name.Contains("mouseVanish"))
              field.SetValue(null, false);
      }
      

      对于一般目的,这样做一次就足够了,但用户可能会在您的应用运行时更改设置,这将导致 MouseVanish 值在下次访问时重新加载。如果您想防范这种情况,请使用 HwndSource.AddHook 挂钩 WM_SETTINGCHANGE 并安排回调以重新应用修复:

      const int WM_SETTINGCHANGE = 26;
      
      public void AddSettingChangeHook()
      {
        _settingChangeWatcher = new HwndSource(new HwndSourceParameters("WM_SETTINGSCHANGE watcher"));
        _settingChangeWatcher.AddHook((IntPtr hwnd, IntPtr msg, IntPtr wParam, IntPtr lParam, ref bool handled) =>
        {
          if((int)msg == WM_SETTINGCHANGE)
            Dispatcher.Invoke(DispatcherPriority.Input, new Action(() =>
            {
              LocallyDisableMousePointerVanish();
            });
        });
      }
      

      【讨论】:

      • 这里有很好的信息。谢谢你。但是,设置 SystemParameters.MouseVanish 会覆盖系统范围的值还是应用程序级别的值?
      • 它实际上低于应用程序级别。通过反射设置的SystemParameters.MouseVanish 的缓存值是基于每个AppDomain 的。因此,如果您有一个包含多个 AppDomain 的应用程序,则一个 AppDomain 可以将 MouseVanish 缓存为 true,而另一个 AppDomain 可以将 MouseVanish 缓存为 false(如果您已通过反射设置它)。当然,一个典型的应用程序只有一个 AppDomain,所以在这种情况下,它将处于应用程序级别。要在系统级别更改它需要调用SystemParametersInfo(SPI_SETMOUSEVANISH, ...)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-14
      • 1970-01-01
      • 2015-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多