У меня есть некоторый рабочий код. Я думаю, что у меня достаточно, что это может быть полезно кому-то другому.
Я нашел способ использовать библиотеку UIAutomation вместо библиотеки Microsoft.VisualBasic. Существовал много проб и ошибок, но это гораздо «slicker», чем мои первые несколько попыток с использованием библиотеки VisualBasic.
Я использовал событие StructureChanged, чтобы обнаружить окно справки, появившееся в предыдущей итерации этого доказательства концепции. Мне удалось успешно обнаружить, что появилось окно справки, но я столкнулся с ошибками, пытаясь обработать внешний вид окна справки. У меня все еще есть обработчик событий в моем приложении, но по какой-то причине окно справки не появляется сейчас, я попытался заставить недействительные данные в одно из полей проверить обработку окна справки, а окно справки не появилось. Для меня это не проблема, так как окно справки вызывало у меня проблемы, но я чувствовал, что это нужно упомянуть, поскольку этот пост спрашивал, как я могу обнаружить появление окна справки.
Некоторые ресурсы я использовал:
http://msdn.microsoft.com/en-us/library/ms747327%28v=vs.110%29.aspx
https://www.universalthread.com/ViewPageArticle.aspx?ID=199
http://msdn.microsoft.com/en-us/library/ms750582%28v=vs.110%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/dd318521%28v=vs.85%29.aspx
private void IncidentGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if ((e.RowIndex < 0) || (e.ColumnIndex < 0))
return;
// Grab the data object that populated the row
Incident incident = (Incident)IncidentGridView.Rows[e.RowIndex].DataBoundItem;
// Create a property condition with the element's type
PropertyCondition typeCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window);
// Create a property condition with the element's name
PropertyCondition nameCondition = new PropertyCondition(AutomationElement.NameProperty, "Incident");
// Create the conjunction condition
AndCondition andCondition = new AndCondition(typeCondition, nameCondition);
// Ask the Desktop to find the element within its children with the given condition
_mainWindow = AutomationElement.RootElement.FindFirst(TreeScope.Children, andCondition);
#region Register Automation Events
//AutomationEventHandler handler = new AutomationEventHandler(OnWindowOpened);
//Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, _mainWindow, TreeScope.Element, handler);
Automation.AddStructureChangedEventHandler(_mainWindow, TreeScope.Children, new StructureChangedEventHandler(OnStructureChanged));
#endregion
// Wait for the application
Thread.Sleep(2000);
// Write the incident to the Incident window
PropertyCondition idCondition = new PropertyCondition(AutomationElement.AutomationIdProperty, "3279");
AutomationElement reportedDate = _mainWindow.FindFirst(TreeScope.Descendants, idCondition);
InsertTextUsingUIAutomation(reportedDate, incident.ReportedDate);
PropertyCondition idCondition2 = new PropertyCondition(AutomationElement.AutomationIdProperty, "4256");
AutomationElement reportedTime = _mainWindow.FindFirst(TreeScope.Descendants, idCondition2);
InsertTextUsingUIAutomation(reportedTime, incident.ReportedTime);
PropertyCondition idCondition4 = new PropertyCondition(AutomationElement.AutomationIdProperty, "7256");
AutomationElement status = _mainWindow.FindFirst(TreeScope.Descendants, idCondition4);
InsertTextUsingUIAutomation(status, "WAR");
PropertyCondition idCondition5 = new PropertyCondition(AutomationElement.AutomationIdProperty, "5404");
AutomationElement natureOfCall = _mainWindow.FindFirst(TreeScope.Descendants, idCondition5);
InsertTextUsingUIAutomation(natureOfCall, "TRAF WARN");
PropertyCondition idCondition11 = new PropertyCondition(AutomationElement.AutomationIdProperty, "4935");
AutomationElement location = _mainWindow.FindFirst(TreeScope.Descendants, idCondition11);
InsertTextUsingUIAutomation(location, incident.Location);
PropertyCondition idCondition12 = new PropertyCondition(AutomationElement.AutomationIdProperty, "2876");
AutomationElement city = _mainWindow.FindFirst(TreeScope.Descendants, idCondition12);
InsertTextUsingUIAutomation(city, incident.City);
PropertyCondition idCondition15 = new PropertyCondition(AutomationElement.AutomationIdProperty, "5693");
AutomationElement officer = _mainWindow.FindFirst(TreeScope.Descendants, idCondition15);
InsertTextUsingUIAutomation(officer, incident.Officer);
PropertyCondition idCondition19 = new PropertyCondition(AutomationElement.AutomationIdProperty, "4023");
AutomationElement fromDate = _mainWindow.FindFirst(TreeScope.Descendants, idCondition19);
InsertTextUsingUIAutomation(fromDate, incident.FromDate);
PropertyCondition idCondition20 = new PropertyCondition(AutomationElement.AutomationIdProperty, "4042");
AutomationElement fromTime = _mainWindow.FindFirst(TreeScope.Descendants, idCondition20);
InsertTextUsingUIAutomation(fromTime, incident.FromTime);
PropertyCondition idCondition21 = new PropertyCondition(AutomationElement.AutomationIdProperty, "7556");
AutomationElement toDate = _mainWindow.FindFirst(TreeScope.Descendants, idCondition21);
InsertTextUsingUIAutomation(toDate, incident.ToDate);
PropertyCondition idCondition22 = new PropertyCondition(AutomationElement.AutomationIdProperty, "7576");
AutomationElement toTime = _mainWindow.FindFirst(TreeScope.Descendants, idCondition22);
InsertTextUsingUIAutomation(toTime, incident.ToTime);
PropertyCondition idCondition30 = new PropertyCondition(AutomationElement.AutomationIdProperty, "2001");
AutomationElement remarks = _mainWindow.FindFirst(TreeScope.Descendants, idCondition30);
InsertTextUsingUIAutomation(remarks, incident.Remarks);
MessageBox.Show("Incident was transferred.");
}
Вот обработчик события для STRUC tureChangedEvent:
private void OnStructureChanged(object sender, StructureChangedEventArgs e)
{
AutomationElement element = sender as AutomationElement;
if (e.StructureChangeType == StructureChangeType.ChildAdded)
{
Object windowPattern;
if (false == element.TryGetCurrentPattern(WindowPattern.Pattern, out windowPattern))
return;
if (element.Current.Name == "Help")
{
// How do we want to handle this???
MessageBox.Show("Waiting 30 seconds to allow user to resolve data issue.");
Thread.Sleep(30000);
}
}
}
SetWinEventHook(). У этого есть умение превращаться в готическую ошибку. По крайней мере, рассмотрите приличную библиотеку автоматизации пользовательского интерфейса, поэтому вам не придется ее взламывать, моделируя нажатия клавиш. –
Ханс, я сначала попытался использовать UIAutomationClient, но не смог выполнить то, что мне нужно, из-за большего количества проблем с системой назначения. Здесь есть устаревшее приложение VB6/VBA, которое делает это, его нужно обновить по нескольким причинам ... Мой партнер и я решили попытаться улучшить решение и избежать использования VBA. После испытаний и сбоев мы снова используем Microsoft.VisualBasic.Interation.AppActivate(), в основном имитирующий код в устаревшем приложении, но мы по-прежнему намерены улучшить функциональность/производительность. Унаследованное приложение действительно что-то другое. – CDR12