Я пытаюсь автоматизировать последовательность пользовательских входов в скомпилированное приложение на С# с использованием Win32 API. У меня нет исходного кода для приложения, которое я пытаюсь контролировать, и он работает, пока я пытаюсь его контролировать. В моем коде у меня есть одна кнопка, которая при щелчке должна сделать последовательность из трех входов для приложения, которое я пытаюсь контролировать:
- Выберите элемент в дереве
- Нажмите кнопку
- Нажмите другую кнопку
Как это работает, кнопка на шаге 2 выполняет действие в зависимости от элемента, выбранного в дереве на шаге 1. Я могу получить щелчки на кнопках, чтобы работать нормально, просто отправив сообщение, но я не могу понять как выбрать элемент TreeView, который я хочу. TreeView статичен, поэтому элементы и макет никогда не будут меняться. Он имеет следующий макет:
-itemsA
-itemsB
--itemB1
-itemsC
Если itemB1 - это элемент, который необходимо выбрать, чтобы кнопка нажала на шаги 2 и 3, чтобы работать. По умолчанию ItemsB сбрасывается, поэтому, вероятно, мне нужно его расширить, прежде чем я могу выбрать ItemB1? Вот мой код. Я очень ценю любую помощь!
//Find Window API
[DllImport("User32.dll")]
public static extern Int32 FindWindow(String lpClassName, String lpWindowName);
//Find WindowEx API
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
//Send Message API
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(int hWnd, int msg, int wParam, IntPtr lParam);
private const int BN_CLICKED = 245;
//Method called by button click
public static void Start()
{
int hwnd = 0;
int prod = 0;
IntPtr hwndChild = IntPtr.Zero;
IntPtr treeChild = IntPtr.Zero;
IntPtr prodChild = IntPtr.Zero;
hwnd = FindWindow(null, "Application");
if (hwnd > 0)
{
//Get Handle for TreeView, THIS IS WHERE I AM STUCK!!
treeChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "AfxMDIFrame80", null);
treeChild = FindWindowEx((IntPtr)treeChild, IntPtr.Zero, "AfxMDIFrame80", null);
treeChild = FindWindowEx((IntPtr)treeChild, IntPtr.Zero, "SysTreeView32", null);
//Need to Add code to select item in TreeView ???
//Click First Button
hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, "AfxMDIFrame80", null);
hwndChild = FindWindowEx((IntPtr)hwndChild, IntPtr.Zero, "AfxMDIFrame80", null);
hwndChild = FindWindowEx((IntPtr)hwndChild, IntPtr.Zero, "#32770", null);
IntPtr scanBtn = FindWindowEx((IntPtr)hwndChild, IntPtr.Zero, "Button", "&Scan");
SendMessage((int)scanBtn, BN_CLICKED, 0, IntPtr.Zero);
//Click Second Button
prod = FindWindow("#32770", "Product: WPC");
prodChild = FindWindowEx((IntPtr)prod, IntPtr.Zero, "Button", "&Collect");
SendMessage((int)prodChild, BN_CLICKED, 0, IntPtr.Zero);
}
}//END Start
Ганс,
Можете ли вы привести мне пример того, как я это сделаю? Проблема, с которой я действительно сталкиваюсь, - это найти дескриптор элемента treeview, который я хочу выбрать. Если я использую Spy ++ для поиска текущего дескриптора и жесткого кода в моем методе, он отлично работает, например:
SendMessage((int)treeChild, TV_SELECTITEM, TVGN_CARET, (IntPtr)0x092DCB30);
Если я использую SendMessage и отправлю TVGN_ROOT в TreeView Handle, он вернет IntPtr с дескриптом элемента, который будет выбран в древовидной структуре, или как это работает? Я также экспериментирую с AutoIt, но я надеялся сохранить весь свой код в одном приложении.