1

我正在尝试遍历 WinForms 表单 (Windows CE) 的控件并检索/匹配它们的文本内容和名称(即Name分配给 WinFormsControl对象的属性)。

我在不同的进程中执行此操作,因此是 WinAPI。

为了遍历和检索文本,我编写了以下代码。TextPresent用于DescendantControls遍历和Text检索文本。我相当有信心遍历代码已经正常工作 - 如果没有,请告诉我。但是,返回的所有控件都具有空文本。

代码可以按如下方式使用:

var foregroundWindow = new WinCEControl(GetForegroundWindow()); // working properly
Assert.That("The Window Title", foregroundWindow.Text); // working properly
Assert.That(manorMenu.TextPresent("Text to find")); // not working although /
    // "Text to find" is a value within the control tree of the window.

至于名字,我什至不知道如何找回它。到目前为止,我的搜索没有成功。

public class WinCEControl
{
    [DllImport("coredll.dll", SetLastError = true)]
    private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);

    [DllImport("coredll.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
    private static extern bool SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);

    private const int WM_GETTEXT = 0x000D;
    private const uint GW_CHILD = 5;
    private const uint GW_HWNDLAST = 1;
    private const uint GW_HWNDNEXT = 2;

    public WinCEControl(IntPtr handle)
    {
        this.Handle = handle;
    }

    public IntPtr Handle { get; private set; }

    public string Text
    {
        get
        {
            var stringBuilder = new StringBuilder(256);
            SendMessage(this.Handle, WM_GETTEXT, stringBuilder.Capacity, stringBuilder);
            return stringBuilder.ToString();
        }
    }

    public IEnumerable<WinCEControl> Children()
    {
        var childHandle = GetWindow(Handle, GW_CHILD);

        if (childHandle == IntPtr.Zero)
        {
            yield break;
        }

        var lastHandle = GetWindow(childHandle, GW_HWNDLAST);

        while (childHandle != lastHandle)
        {
            yield return new WinCEWindow(childHandle);

            childHandle = GetWindow(childHandle, GW_HWNDNEXT);
        }

        yield return new WinCEWindow(lastHandle);
    }

    public IEnumerable<WinCEControl> DescendantControls()
    {
        var nodes = new Queue<WinCEControl>(new[] { this });
        while (nodes.Any())
        {
            var node = nodes.Dequeue();

            if (node != this)
            {
                yield return node;
            }

            foreach (var n in node.Children()) nodes.Enqueue(n);
        }
    }

    public bool TextPresent(string text)
    {
        foreach (var descendantControl in DescendantControls())
        {
            if (descendantControl.Text == text)
            {
                return true;
            }
        }

        return false;
    }
}

我的目标是能够针对 CE 设备上正在运行的应用程序执行 UI 测试。如果有一个可靠的 C# 库来实现在 Windows CE 上工作的相同功能,我很乐意听到。

更新:正如我在评论中提到的,我未能找到用于在 Win CE 上自动化外部 WinForms 进程的库或框架。我尝试了“simple-wince-gui-automation”,它也无法检索文本。

4

0 回答 0