计算新的 ScrollPercent - 在 ViewSize 改变之后
Calculate new ScrollPercent - after ViewSize changed
首先,基本上我认为我只是需要帮助弄清楚如何计算它,数学并不是我的强项。
仅供参考,MS-Word 很可能与解决我的问题无关,我基本上只是提到它所以你知道我所处的上下文,但我相信对于不了解的人来说它也应该是可以解决的MS-Word.
我的问题是 Word 有 属性 VerticalPercentScrolled
,它是 integer
.
这并不像我需要的那样准确,考虑一个 300 页的 Word 文档,滚动条的 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);
使用此代码我得到一个百分比值让我们说 9.442248572683356
而不是 9
.
要重置值,我使用以下代码:
object scrollPattern;
if (element.TryGetCurrentPattern(ScrollPattern.Pattern, out scrollPattern))
((ScrollPattern)scrollPattern).SetScrollPercent(ScrollPattern.NoScroll, oldVerticalPercent);
这很有魅力。
现在我的问题是,如果我的文档在我存储旧值并想重新应用期间得到 larger/smaller 怎么办,我的旧值需要调整。
我可以读取以下值(至少我目前找到的值):
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
,文档的大小可能会在两者之间缩小或增大?
编辑:
这是一个测试场景:
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
将其更改为所需的 percentValue 后,scrollBarValue 是唯一更新的值,它比
scrollBarValue 1054
所以,看起来你的 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)
首先,基本上我认为我只是需要帮助弄清楚如何计算它,数学并不是我的强项。
仅供参考,MS-Word 很可能与解决我的问题无关,我基本上只是提到它所以你知道我所处的上下文,但我相信对于不了解的人来说它也应该是可以解决的MS-Word.
我的问题是 Word 有 属性 VerticalPercentScrolled
,它是 integer
.
这并不像我需要的那样准确,考虑一个 300 页的 Word 文档,滚动条的 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);
使用此代码我得到一个百分比值让我们说 9.442248572683356
而不是 9
.
要重置值,我使用以下代码:
object scrollPattern;
if (element.TryGetCurrentPattern(ScrollPattern.Pattern, out scrollPattern))
((ScrollPattern)scrollPattern).SetScrollPercent(ScrollPattern.NoScroll, oldVerticalPercent);
这很有魅力。
现在我的问题是,如果我的文档在我存储旧值并想重新应用期间得到 larger/smaller 怎么办,我的旧值需要调整。
我可以读取以下值(至少我目前找到的值):
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
,文档的大小可能会在两者之间缩小或增大?
编辑:
这是一个测试场景:
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
将其更改为所需的 percentValue 后,scrollBarValue 是唯一更新的值,它比
scrollBarValue 1054
所以,看起来你的 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)