Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate new ScrollPercent - after ViewSize changed

First of all, basically I believe I just need help in figuring out how to calculate it, math isnt really my strong side.

FYI, the MS-Word is most likely not relevant to solve my problem, I basically just mention it so you know the context I am in, but I believe it should be solvable also for people who have no knowledge about MS-Word.

I have the problem that Word has the property VerticalPercentScrolled which is an integer.

Which isnt as accurate as I need it to be, consider a Word Document with 300 pages and the scrollbar can only have a integer between 0 - 100 (percent), so for example 25 percent of a 300 page document is a rather big range.

I have now gone and read the correct value, with the help of UI Automation library - TestStack.White - and can successfully set it to its old value, if some un-desired scrolling happens.

Like this:

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);

with this code I get a percent value of lets say 9.442248572683356 instead of 9.

To reset the value I use the following code:

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

This works like a charm.

Now my problem is what if my document gets larger/smaller during the time I stored the oldValue and want to reapply it, my oldValue needs to be adjusted.

I can read the following values (at least those I found so far):

  1. ScrollPattern.VerticalScrollPercentProperty
  2. ScrollPattern.VerticalViewSizeProperty

I can also go and look for the scrollbar it self and read the following values:

  1. RangeValuePattern.LargeChangeProperty
  2. RangeValuePattern.MaximumProperty
  3. RangeValuePattern.MinimumProperty
  4. RangeValuePattern.SmallChangeProperty
  5. RangeValuePattern.ValueProperty

To look for the scrollbar, I use the following code:

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);

You may ask yourself, why I dont set the RangeValuePattern.ValueProperty when I am able to access it, the problem there is that Word doesnt update the document when I change this property, the scroll thumb does move but the document doesnt move an inch.

I have to set the ScrollPattern.VerticalScrollPercentProperty for it to work.

So my question, is how do I calculate the new ScrollPattern.VerticalScrollPercentProperty based on the oldValue, where the document could shrink or grow in size in between?

Edit:

Here is a testscenario:

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

After inserting 5 new pages

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)

And as said, I need to adjust the scrollPercent - after inserting those pages - so that it is again on the old position.

I can tell you that in this testscenario, I would need the new value to be

scrollPercent       2.3278413357480452

after changing it to the desired percentValue the scrollBarValue is the only value getting updated and it is than at

scrollBarValue      1054
like image 310
Rand Random Avatar asked Aug 07 '17 09:08

Rand Random


1 Answers

So, it looks like your scrollPercent is calculated like this:

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

So the math should work out like this (assuming floating-point division):

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

From that, you have:

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

When you equate the two, you get:

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

And then finally:

scrollPercentNew = scrollPercentOld * (scrollBarMaximumOld - 1) / (scrollBarMaximumNew - 1)
like image 144
Filip Milovanović Avatar answered Oct 18 '22 18:10

Filip Milovanović