Автозаполнение текстового поля и «Скрыть указатель при наборе текста» в Windows - PullRequest
2 голосов
/ 14 ноября 2009

Как приложение «Скрыть указатель при наборе текста» может быть отключено приложением? У меня проблема с сокрытием курсора, и я не могу вернуть его обратно без нажатия клавиши escape или потери фокуса окна. Приложение было написано на C # и использует WPF. Ответ по конкретной технологии не требуется, поскольку он, вероятно, будет возможен при использовании любой технологии.

Вот сценарий: пользователь может ввести текстовое поле, и список автозаполнения отображается под окном. Однако, как только пользователь начинает печатать, он / она больше не может выбирать элемент из выпадающего списка, поскольку отсутствует курсор мыши.

Я заметил, что Firefox не имеет такого поведения. Например, при вводе URL-адреса в адресной строке курсор мыши никогда не исчезает. В других местах я видел такое поведение, поэтому знаю, что это возможно.

Любая помощь очень ценится!

Ответы [ 2 ]

3 голосов
/ 15 ноября 2009

Я обнаружил, установив контрольные точки, что при первом вводе текста в текстовом поле WPF читает общедоступное свойство SystemParameters.MouseVanish, которое вызывает SystemParametersInfo(SPI_GETMOUSEVANISH, ...), чтобы получить настройку исчезновения мыши. Последующие вызовы SystemParameters.MouseVanish используют кэшированное значение.

Два возможных решения:

  1. Доступ к SystemParameters.MouseVanish, затем использование отражения для перезаписи кэшированного результата, чтобы последующие вызовы возвращали ложь.
  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();
      });
  });
}
1 голос
/ 15 ноября 2009

Похоже, функция Win API SystemParametersInfo будет делать то, что вам нужно; Параметры для управления отсутствием указателя:

SPI_GETMOUSEVANISH и SPI_SETMOUSEVANISH

Мышь Vanish accessibility функция была добавлена ​​для Windows Me и Windows XP. Эта функция скрывает указатель, когда пользователь печатает. указатель мыши появляется снова, когда пользователь двигает мышь. Эта функция сохраняет указатель от затенения текста набирается, например, по электронной почте или другой документ.

проверка Функция SystemParametersInfo описание в msdn для получения дополнительной информации

...