Обновление Палитры Внешних ссылок при помощи Microsoft UI Automation
В этой статье мы рассмотрим процедуру обновления Палитры Внешних Ссылок AutoCAD. Прежде, чем мы углубимся в детали, вот некоторая справочная информация о том, почему может потребоваться обновлять эту палитру.Палитра внешних ссылок AutoCAD превращается в расширенное стандартное окно (ESW) в том случае если установлен плагин Vault для AutoCAD. Поскольку статус возврата / получения файлов отображаются в Палитре Внешних Ссылок, необходимо обновление палитры для отображения текущего состояния в том случае, когда статус изменён извне при помощи клиента Vault.
В силу того, что нет никакого публичного API для этого, мы рассмотрим использование Microsoft UI Automation для имитации нажатия кнопки Обновить. Пожалуйста, обратите внимание, что подход, предложенный здесь не поддерживается Autodesk, а опирается на Win32 и UI Automation API. Если вы будете использовать этот подход, пожалуйста, проверить его более детально в своем приложении.
Чтобы нажать на кнопку Обновить в Microsoft UI Automation имеется все необходимое. К сожалению, природа кнопки Обновить в Палитре Внешних Ссылок AutoCAD такова, что это сделать затруднительно. Глядя на макет Палитры Внешних Ссылок палитре с помощью утилиты Spy ++, становится очевидным, что кнопка Обновить является частью панели инструментов внутри палитры. Кроме того, кнопка Обновить является раскрывающимся меню с вариантами Перезагрузить и Обновить. При использовании паттерна Invoke UI Automation невозможно симулировать нажатие кнопки мыши на кнопке Обновить.
Чтобы обойти это, мы можем прибегнуть к методу Win32 API SendInput для имитации щелчка мыши, а собрать необходимые материалы по этому методу с использованием Microsoft UI Automation API. Вот пример кода, который работает нормально в AutoCAD 2016. Для других версий AutoCAD вам возможно потребуется определить идентификатор элемента управления кнопки Обновить, при помощи утилиты Spy ++ и изменить соответствующим образом код.
- // Добавим ссылку на UIAutomationClient.dll
- // и UIAutomationTypes.dll
- using System.Windows.Automation;
- using System.Diagnostics;
- using System.Runtime.InteropServices;
- using Autodesk.AutoCAD.Runtime;
- using Autodesk.AutoCAD.EditorInput;
- using Autodesk.AutoCAD.DatabaseServices;
- using Autodesk.AutoCAD.ApplicationServices;
- // Основано на http://www.pinvoke.net
- // /default.aspx/user32/SendInput.html
- // /default.aspx/Structures/MOUSEINPUT.html
- // /default.aspx/user32/mouse_event.html
- [DllImport("user32.dll" , SetLastError = true )]
- static extern uint SendInput(uint nInputs,
- INPUT[] pInputs, int cbSize);
- [StructLayout(LayoutKind.Sequential)]
- internal struct MOUSEINPUT
- {
- public int dx;
- public int dy;
- public uint mouseData;
- public uint dwFlags;
- public uint time;
- public IntPtr dwExtraInfo;
- }
- [StructLayout(LayoutKind.Sequential)]
- internal struct INPUT
- {
- public int type;
- public MOUSEINPUT mi;
- public INPUT(uint flag)
- {
- type = 0; // Мышиный ввод
- mi.dx = 0;
- mi.dy = 0;
- mi.mouseData = 0;
- mi.time = 0;
- mi.dwExtraInfo = IntPtr.Zero;
- mi.dwFlags = flag;
- }
- }
- private const int MOUSEEVENTF_LEFTDOWN = 0x0002;
- private const int MOUSEEVENTF_LEFTUP = 0x0004;
- [CommandMethod("XRefPalRefresh" )]
- public void XRefPalRefresh()
- {
- Editor ed =
- Application.DocumentManager.MdiActiveDocument.Editor;
- try
- {
- System.Diagnostics.Process p
- = Process.GetCurrentProcess();
- AutomationElement acadAutoElem =
- AutomationElement.RootElement.FindFirst(
- TreeScope.Children,
- new PropertyCondition(
- AutomationElement.ProcessIdProperty, p.Id));
- // Идентификатор элемента управления кнопки Обновить
- // в AutoCAD 2016 полученный из Spy++
- string btnRefreshhexID = "000075FB" ;
- string btnRefreshdecimalID =
- System.Convert.ToInt32(btnRefreshhexID, 16)
- .ToString();
- AutomationElement refreshBtnAutoElem
- = acadAutoElem.FindFirst(
- TreeScope.Descendants,
- new PropertyCondition(
- AutomationElement.AutomationIdProperty,
- btnRefreshdecimalID));
- if (refreshBtnAutoElem == null)
- {
- ed.WriteMessage("Кнопка Обновить в
- Палитре Внешних Ссылок
- Не найдена !");
- return ;
- }
- // Использование шаблона UI's Invoke
- // Работает для обычных простых кнопок, но не работает
- // для кнопки Обновить в Палитре Внешних Ссылок
- //InvokePattern ipClickRefreshBtn =
- // (InvokePattern)refreshBtnAutoElem.GetCurrentPattern
- // (InvokePattern.Pattern);
- //ipClickRefreshBtn.Invoke();
- // Щелкаем по местоположению.
- System.Windows.Point point
- = refreshBtnAutoElem.GetClickablePoint();
- System.Windows.Forms.Cursor.Position
- = new System.Drawing.Point(
- (int )point.X, (int )point.Y);
- INPUT input1 = new INPUT(MOUSEEVENTF_LEFTDOWN);
- INPUT input2 = new INPUT(MOUSEEVENTF_LEFTUP);
- SendInput(2, new [] { input1, input2 },
- Marshal.SizeOf(typeof(INPUT)));
- }
- catch (System.Exception ex)
- {
- ed.WriteMessage(ex.Message);
- }
- }
Источник: http://adndevblog.typepad.com/autocad/2015/09/refreshing-external-references-palette-using-microsoft-ui-automation.html
Обсуждение: http://adn-cis.org/forum/index.php?topic=3124
Опубликовано 22.10.2015