Подтвердить что ты не робот

Вычислить новый ScrollPercent - после изменения ViewSize

Прежде всего, в основном, я считаю, что мне просто нужна помощь в выяснении того, как вычислить его, математика на самом деле не моя сильная сторона.

FYI, MS-Word, скорее всего, не имеет отношения к решению моей проблемы, я просто упоминаю об этом, поэтому вы знаете контекст, в котором я участвую, но я считаю, что он должен быть разрешен также для людей, которые не знают о MS- Слово.

У меня проблема, что Word имеет свойство VerticalPercentScrolled, которое является integer.

Что не так точно, как мне нужно, рассмотрите документ Word с 300 страницами, а полоса прокрутки может иметь только integer от 0 до 100 (в процентах), так что, например, 25 процентов из 300 страниц документа довольно большой диапазон.

Теперь я ушел и прочитал правильное значение с помощью библиотеки UI Automation - TestStack.White - и может успешно установить его на свое старое значение, если произойдет некоторая ненастраиваемая прокрутка.

Вот так:

var hWnd = (IntPtr)WordUtils.GetHwnd();
var processId = Process.GetCurrentProcess().Id;

var uiApp = TestStack.White.Application.Attach((int)processId);
var uiWindow = uiApp.GetWindow(WindowHandling.GetWindowText(hWnd), InitializeOption.NoCache);

var wf = (IUIItemContainer)uiWindow.Get(SearchCriteria.ByClassName("_WwF"));
var wbs= wf.GetMultiple(SearchCriteria.ByClassName("_WwB"));
if (wbs.Length != 1)
    return;

var wb= (IUIItemContainer)wbs.First();
var wgs = wb.GetMultiple(SearchCriteria.ByClassName("_WwG"));
if (wgs.Length != 1)
    return;

var wg = wgs.First();
var element = wg.AutomationElement;

var oldVerticalPercent = (double)element.GetCurrentPropertyValue(ScrollPattern.VerticalScrollPercentProperty);

с этим кодом я получаю процентное значение let say 9.442248572683356 вместо 9.

В reset значение я использую следующий код:

object scrollPattern;
if (element.TryGetCurrentPattern(ScrollPattern.Pattern, out scrollPattern))
    ((ScrollPattern)scrollPattern).SetScrollPercent(ScrollPattern.NoScroll, oldVerticalPercent);

Это работает как шарм.

Теперь моя проблема в том, что, если мой документ становится все больше/меньше за время, когда я сохранил oldValue и хочу его повторно применить, мне нужно настроить мою oldValue.

Я могу прочитать следующие значения (по крайней мере, те, что я нашел до сих пор):

  • ScrollPattern.VerticalScrollPercentProperty
  • ScrollPattern.VerticalViewSizeProperty

Я также могу пойти и искать собственную полосу прокрутки и прочитать следующие значения:

  • RangeValuePattern.LargeChangeProperty
  • RangeValuePattern.MaximumProperty
  • RangeValuePattern.MinimumProperty
  • RangeValuePattern.SmallChangeProperty
  • RangeValuePattern.ValueProperty

Чтобы найти полосу прокрутки, я использую следующий код:

var hWnd = (IntPtr)WordUtils.GetHwnd();
var processId = Process.GetCurrentProcess().Id;

var uiApp = Ts.Application.Attach((int)processId);
var uiWindow = uiApp.GetWindow(WindowHandling.GetWindowText(hWnd), InitializeOption.NoCache);

var wf = (IUIItemContainer)uiWindow.Get(SearchCriteria.ByClassName("_WwF"));
var wbs = wf.GetMultiple(SearchCriteria.ByClassName("_WwB"));
if (wbs.Length != 1)
    return;

var wb = (IUIItemContainer)wbs.First();
var wgs= wb.GetMultiple(SearchCriteria.ByClassName("_WwG"));
if (wgs.Length != 1)
    return;

var nUiScrollBars = wgs.GetMultiple(SearchCriteria.ByClassName("NUIScrollbar"));
if (scrollBar.Length != 1)
    return;

var nUiScrollBar = (IUIItemContainer)nUiScrollBars.First();
var nUiHwndElements = nUiScrollBar.GetMultiple(SearchCriteria.ByClassName("NetUIHWNDElement"));
if (nUiHwndElements.Length != 1)
    return;

var nUiHwndElement = (IUIItemContainer)nUiHwndElements.First();
var netUiScrollBar = nUiHwndElement.GetElement(SearchCriteria.ByClassName("NetUIScrollBar"));

var scrollBarValue = (double)netUiScrollBar.GetCurrentPropertyValue(RangeValuePattern.ValueProperty);

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

Мне нужно установить ScrollPattern.VerticalScrollPercentProperty, чтобы он работал.

Итак, мой вопрос: как вычислить новый ScrollPattern.VerticalScrollPercentProperty на основе oldValue, где документ может сокращаться или увеличиваться в размере между ними?

Edit:

Вот сценарий:

scrollPercent       64.86486486486487
scrollViewSize      74.394463667820062
scrollBarLargeChange    37197
scrollBarMaximum        12803
scrollBarMinimum        0
scrollBarSmallChange    1
scrollBarValue      8304

После вставки 5 новых страниц

scrollPercent       87.890366182251867 <-- undesired scrolling occured (see desired values below)
scrollViewSize      9.442248572683356
scrollBarLargeChange    4721
scrollBarMaximum        45279
scrollBarMinimum        0
scrollBarSmallChange    1
scrollBarValue      39795 <-- undesired scrolling occured (see desired values below)

И как сказано, мне нужно настроить scrollPercent - после вставки этих страниц - так, чтобы он снова находился в старой позиции.

Я могу сказать вам, что в этом сценарии тестов мне понадобится новое значение

scrollPercent       2.3278413357480452

после изменения его на желаемый процентное значение, значение scrollBarValue является единственным значением, которое обновляется, и оно меньше, чем при

scrollBarValue      1054
4b9b3361

Ответ 1

Итак, похоже, что ваш scrollPercent вычисляется следующим образом:

scrollPercent = 100.0 * scrollBarValue / (scrollBarMaximum - 1);

Итак, математика должна работать так (предполагая деление с плавающей запятой):

scrollPercentOld = 100.0 * scrollBarValueOld / (scrollBarMaximumOld - 1)
scrollPercentNew = 100.0 * scrollBarValueOld / (scrollBarMaximumNew - 1)

Из этого вы имеете:

scrollBarValueOld = scrollPercentOld * (scrollBarMaximumOld - 1) / 100.0
scrollBarValueOld = scrollPercentNew * (scrollBarMaximumNew - 1) / 100.0

Приравнивая два, вы получаете:

scrollPercentOld * (scrollBarMaximumOld - 1) = scrollPercentNew * (scrollBarMaximumNew - 1)

И наконец:

scrollPercentNew = scrollPercentOld * (scrollBarMaximumOld - 1) / (scrollBarMaximumNew - 1)