【问题标题】:Calculate new ScrollPercent - after ViewSize changed计算新的 ScrollPercent - ViewSize 更改后
【发布时间】:2018-01-14 13:09:41
【问题描述】:

首先,基本上我相信我只需要帮助弄清楚如何计算它,数学并不是我的强项。

仅供参考,MS-Word 很可能与解决我的问题无关,我基本上只是提到它,以便您了解我所处的环境,但我相信对于不了解 MS 的人来说,它也应该可以解决-单词。

我的问题是 Word 具有属性 VerticalPercentScrolled,这是一个 integer

这并不像我需要的那样准确,考虑一个包含 300 页的 Word 文档,并且滚动条的 integer 只能在 0 到 100(百分比)之间,因此例如 300 页文档的 25% 是范围相当大。

我现在已经阅读了正确的值,借助 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);

这就像一个魅力。

现在我的问题是,如果我的文档在我存储 oldValue 期间变得更大/更小并且想要重新应用它,我的 oldValue 需要调整。

我可以读取以下值(至少是我目前发现的值):

  1. ScrollPattern.VerticalScrollPercentProperty
  2. ScrollPattern.VerticalViewSizeProperty

我也可以去寻找它自己的滚动条并读取以下值:

  1. RangeValuePattern.LargeChangeProperty
  2. RangeValuePattern.MaximumProperty
  3. RangeValuePattern.MinimumProperty
  4. RangeValuePattern.SmallChangeProperty
  5. 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 才能让它工作。

所以我的问题是,我如何根据 oldValue 计算新的 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 是唯一得到更新的值,它比 at

scrollBarValue      1054

【问题讨论】:

  • 你确定scrollPercent的新值应该是2.32...,我想应该是18.339627642。如果是 2.32,你是怎么得到这个值的?
  • @RobAnthony 我滚动到与最初完全相同的位置,这就是我得到的,并且尝试将其设置为硬编码应该发生的计算并且它工作正常。
  • 我无法理解您在示例中给出的数字。 ScrollPercent、ScrollBarMaximum 和 ScrollBarValue 之间的联系很容易计算出来,即 ScrollPercent = ScrollBarValue / ScrollBarMaximum。这适用于两组数字。它还将 2.32 值连接到 1054 和 45279,但如果您完成了 12803 大小的文档的 64%,那么您将完成 45279 大小的文档的 18%,而不是 2.32%
  • @RobAnthony 我相信你没有考虑到当 ViewSize 相对较小并且滚动拇指相当大时滚动值不是拇指的顶部我认为它是底部.在那里你会得到不同的结果。我相信当您将滚动条最大值与大变化进行比较时可以看出这一点,大变化远大于滚动最大值。

标签: c# ms-word ui-automation white-framework


【解决方案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)

【讨论】:

  • “总高度”是多少?我可以假设它是scrollbarMaximum吗?
  • 我刚刚编辑了我的答案以使用您问题中的术语和名称。刚刚做了一些计算,看起来“总高度”对应于(scrollBarMaximum - 1)
  • 这似乎与@RobAnthony 使用的方法相同(请参阅下面的问题 cmets),因为您的计算也会导致 18.34。这是不正确的,新的滚动百分比应该是2.3278413357480452。这就是我使用的64,8648648648648*(12803-1)/(45279-1)
  • P.S.以这种方式计算时,scrollPercentNew 应该在更改之间保持相同的scrollBarValue - 但是,也许我误解了你。为什么是 2.3278413357480452?
  • 这是我manually将位置移动到之前的位置时得到的新值,这就是原因。
猜你喜欢
  • 2012-11-24
  • 1970-01-01
  • 1970-01-01
  • 2020-09-25
  • 2019-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多