Как отследить изменение размеров окна документа

Автор Тема: Как отследить изменение размеров окна документа  (Прочитано 7815 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн olvolАвтор темы

  • ADN OPEN
  • Сообщений: 6
  • Карма: 0
Подскажите, как отследить изменение размеров окна документа (т.е. той области, где рисуем)? Подписался на отслеживание сис.переменной screensize, но это событие срабатывает только при переключении вида модели (например, с вида СВЕРХУ на вид СЛЕВА). Окна с приветом не появляется вообще. Мне необходимо постоянно отслеживать размер окна. Пните в какую сторону нужно катиться.

Код - C# [Выбрать]
  1.     public class MyCommands
  2.     {
  3.         private Editor edt = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
  4.         [CommandMethod("auto2d")]
  5.         public void auto2d()
  6.         {
  7.             Autodesk.AutoCAD.ApplicationServices.Application.SystemVariableChanged += new Autodesk.AutoCAD.ApplicationServices.SystemVariableChangedEventHandler(scrSizeChange);
  8.         }
  9.  
  10.         public void scrSizeChange (object sender,
  11.             Autodesk.AutoCAD.ApplicationServices.SystemVariableChangedEventArgs e)
  12.         {
  13.             if (e.Name == "SCREENSIZE")
  14.                 System.Windows.MessageBox.Show("HELLO");
  15.  
  16.             edt.WriteMessage("NEW SCREENSIZE:"+Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("SCREENSIZE").ToString());
  17.         }
  18.     }
« Последнее редактирование: 19-11-2015, 23:09:42 от Александр Ривилис »

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Document.ViewChanged...

Оффлайн olvolАвтор темы

  • ADN OPEN
  • Сообщений: 6
  • Карма: 0
ну как бы да, но не совсем то. Это событие срабатывает при любом изменении вида ( при том же переключении видов вид СВЕРХУ->вид СЛЕВА). Мне бы отфильтровать только изменение размеров окна. Можно, конечно, проверять изменился ли вид до и после события ViewChanged, но может есть способ проще?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
olvol
Приветствую на форуме!
но может есть способ проще
Проще точно нет. Есть сложнее, но однозначно будут попадать только события изменения положения/размеров окна.
Пример чуть позже покажу.

P.S.: Прочитай у меня в подписи как следует форматировать код на форуме.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение olvol 19-02-2016, 23:16:28

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Вот два метода (первые, которые пришли в голову), которые позволяют отследить изменение размеров окна документа:
Код - C# [Выбрать]
  1. using System;
  2. using System.Collections.Generic;
  3. using Autodesk.AutoCAD.Runtime;
  4. using Autodesk.AutoCAD.ApplicationServices;
  5. using Autodesk.AutoCAD.EditorInput;
  6. // Нужно для Метода 1
  7. using Autodesk.AutoCAD.Internal.Reactors;
  8.  
  9. // Для Метода 1
  10. [assembly: ExtensionApplication(typeof(Rivilis.WinUtils1))]
  11. // Для Метода 2
  12. //[assembly: ExtensionApplication(typeof(Rivilis.WinUtils2))]
  13.  
  14.  
  15. namespace Rivilis
  16. {
  17.   /// <summary>
  18.   /// Для работы по Методу 1 (используется недокументированный
  19.   /// класс Autodesk.AutoCAD.Internal.Reactors.ApplicationEventManager)
  20.   /// </summary>
  21.   public class WinUtils1 : IExtensionApplication
  22.   {
  23.     ApplicationEventManager eventMngr = ApplicationEventManager.Instance();
  24.  
  25.     void IExtensionApplication.Initialize()
  26.     {
  27.       eventMngr.ApplicationDocumentFrameChanged += eventMngr_ApplicationDocumentFrameChanged;
  28.     }
  29.     void IExtensionApplication.Terminate()
  30.     {
  31.       try {
  32.         eventMngr.ApplicationDocumentFrameChanged -= eventMngr_ApplicationDocumentFrameChanged;
  33.       }
  34.       catch { }
  35.     }
  36.  
  37.     void eventMngr_ApplicationDocumentFrameChanged(object sender, EventArgs e)
  38.     {
  39.       try {
  40.         Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  41.         ed.WriteMessage("\nМетод 1: Размер окна изменён");
  42.       }
  43.       catch { }
  44.     }
  45.   }
  46.  
  47.   /// <summary>
  48.   /// Для работы по Методу 2 (используется Application.PreTranslateMessage,
  49.   /// в котором проверяется не изменился ли размер окна)
  50.   /// </summary>
  51.   public class WinUtils2 : IExtensionApplication
  52.   {
  53.     DocumentCollection docMan = Application.DocumentManager;
  54.     Dictionary<Document, System.Windows.Size> winColl = new Dictionary<Document, System.Windows.Size>();
  55.  
  56.     void IExtensionApplication.Initialize()
  57.     {
  58.       foreach (Document doc in docMan) {
  59.         winColl.Add(doc, doc.Window.DeviceIndependentSize);
  60.       }
  61.       docMan.DocumentCreated += docMan_DocumentCreated;
  62.       docMan.DocumentToBeDestroyed += docMan_DocumentToBeDestroyed;
  63.       Application.PreTranslateMessage += Application_PreTranslateMessage;
  64.     }
  65.  
  66.     void Application_PreTranslateMessage(object sender, PreTranslateMessageEventArgs e)
  67.     {
  68.       try {
  69.         Document doc = docMan.MdiActiveDocument;
  70.         if (doc != null) {
  71.           System.Windows.Size curSize = doc.Window.DeviceIndependentSize;
  72.           if (curSize != winColl[doc]) {
  73.             doc.Editor.WriteMessage("\nМетод 2: Размер окна изменён");
  74.             winColl[doc] = curSize;
  75.           }
  76.         }
  77.       }
  78.       catch { }
  79.     }
  80.  
  81.     void docMan_DocumentToBeDestroyed(object sender, DocumentCollectionEventArgs e)
  82.     {
  83.       try { winColl.Remove(e.Document); } catch { }
  84.     }
  85.  
  86.     void docMan_DocumentCreated(object sender, DocumentCollectionEventArgs e)
  87.     {
  88.       winColl.Add(e.Document, e.Document.Window.DeviceIndependentSize);
  89.     }
  90.  
  91.     void IExtensionApplication.Terminate()
  92.     {
  93.       try {
  94.         Application.PreTranslateMessage -= Application_PreTranslateMessage;
  95.         docMan.DocumentCreated -= docMan_DocumentCreated;
  96.         docMan.DocumentToBeDestroyed -= docMan_DocumentToBeDestroyed;
  97.         foreach (Document doc in docMan) winColl.Remove(doc);
  98.       }
  99.       catch { }
  100.     }
  101.   }
  102. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Есть еще третий метод, с использованием COM/ActiveX интерфейса AutoCAD - событие AcadDocument.WindowMovedOrResized.
Но похоже оно как-то не слишком стабильно работает, так что рекомендовать его не буду.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн olvolАвтор темы

  • ADN OPEN
  • Сообщений: 6
  • Карма: 0
дошли руки (и время) взяться опять за программирование
Александр, спасибо за помощь, все работает отлично, но в процессе понял, что нужно более тонко все это отслеживать. Ваши варианты срабатывают только после изменения размеров окна, мне же нужно непосредственно перед изменением уже отреагировать (т.е. по аналогии -вместо события SystemVariableChanged нужно отследить SystemVariableChanging). Кроме того, теперь понимаю, что необходимо еще и положение окна документа отследить-не изменилось ли оно.

Но может есть какое-то другое решение? Я хочу поверх окна документа отображать свое, в которое выводить нужную мне информацию. В идеале - сделать менюшку типа автокадовской (см скрин). В принципе-то окно поверх сделать не сложно, но тогда начинаются заморочки с отслеживанием размеров, перемещения окна документа и проч. Я вот и думаю - может изначально не в ту сторону двинулся? Может есть какой другой способ получить желаемое? Да, сразу-палитры не подходят)

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Я хочу поверх окна документа отображать свое, в которое выводить нужную мне информацию. В идеале - сделать менюшку типа автокадовской (см скрин). В принципе-то окно поверх сделать не сложно, но тогда начинаются заморочки с отслеживанием размеров, перемещения окна документа и проч. Я вот и думаю - может изначально не в ту сторону двинулся?
Если ты поверх сделаешь своё окно, то зачем вообще отслеживать изменение окна документов? Пусть оно просто плавает над окном документов, а пользователь если хочет может его передвинуть. Можешь при желании сделать его с прозрачным фоном, без заголовка и т.д.

P.S.: Честно говоря мне совершенно непонятно желание перекроить AutoCAD под себя вместо того, чтобы использовать его встроенные UI-средства.

P.S.S.: Зачем отслеживать в момент изменения размеров/положения окна документа я тоже понять не могу. Закончится изменение - перенесёшь своё окошко. В противном случае это всё будет дергаться, перерисовываться. Оно тебе надо?
Если уж и решишься отслеживать изменения окна в момент их изменений, то тебе очень вероятно придётся использовать P/Invoke для ряда функций из Windows API, которых в .NET нет. Оно тебе нужно? Обычно для этой цели делается субклассирование окна, передача ему своей функции обработчика WndProc и в ней отслеживаешь изменение размеров окна. При этом ни в коем случае не забыть вернуть управление старому WndProc - иначе AutoCAD умрёт. В общем я бы не советовал это делать. Особенно в .NET.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн olvolАвтор темы

  • ADN OPEN
  • Сообщений: 6
  • Карма: 0
по порядку
1 по большому счету, конечно, можно и забить на все отслеживания и просто выводить окно поверх, просто если размер окна документа или его положение будет изменено, то мое окно (которое должно бы отображаться "внутри" окна документа) будет висеть в воздухе, после окончания изменения оно все-таки перерисуется в уже измененном, но колхоз будет заметен. Суть только в этом. Стремление к максимально возможному совершенству всего лишь

2 Какими стандартными средствами можно запилить что-то вроде менюшки со скрина? Данные, которые хочу выводить должны быть постоянно на экране, поэтому лента отпадает (вкладку ленты можно переключить). Тулбары? ну это как-то совсем по-деревенски будет. Палитры? много они места занимают и (по-моему) не особо удобны для моих целей. Что тогда остается?

3 После экспериментов пришел к выводу, пусть мое окно перерисовывается после изменения размеров - пусть и колхозно выглядит, но судя по количеству головной боли, которая предстоит, проще уж оставить так

Я правильно понимаю, что автокадовскими средствами сделать аналог панельки со скрина не возможно? Только через танцы с большим бубном?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Я правильно понимаю, что автокадовскими средствами сделать аналог панельки со скрина не возможно? Только через танцы с большим бубном?
Буду краток: API для создания такой менюшки в ObjectARX / AutoCAD .NET API нет.
Можно рисовать транзитную графику и использовать реактор PointMonitor. При этом графику придётся перерисовывать при каждом изменении вида, а не только размеров и положения окна документа. Так что это будут танцы на голове...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение