Я обнаружил, установив контрольные точки, что при первом вводе текста в текстовом поле WPF читает общедоступное свойство SystemParameters.MouseVanish
, которое вызывает SystemParametersInfo(SPI_GETMOUSEVANISH, ...)
, чтобы получить настройку исчезновения мыши. Последующие вызовы SystemParameters.MouseVanish
используют кэшированное значение.
Два возможных решения:
- Доступ к
SystemParameters.MouseVanish
, затем использование отражения для перезаписи кэшированного результата, чтобы последующие вызовы возвращали ложь.
- Позвоните в 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();
});
});
}