Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Gennadiy от 25-11-2014, 15:36:31

Название: Как отловить потерю фокуса в PaletteSet
Отправлено: Gennadiy от 25-11-2014, 15:36:31
Добрый день.
Столкнулся с такой проблемой:
Создаю свою PaletteSet,  на ней есть TextBox, который при выделении примитива в чертеже отображает для редактирования определенное свойство из словаря.
Не могу понять как отловить событие когда PaletteSet теряет фокус (или окно Autocad его получает), например при щелчке мышкой на окне autocad, чтобы закончить  редактирование TextBox. События типа TextBox.LostFocus не срабатывают. Короче мне нужно чтобы срабатывало так как в палитре свойств autocad, когда например выделен блок с атрибутом и значение атрибута редактируется в палитре свойств, а затем вы щелкаете где нибудь в чертеже мышкой, то редактирование атрибута прекращается с изменением его значения, а у меня редактирование не прекращается. Помогите кто чем может!
П.С. AutoCAD 2012 c#
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: bargool от 25-11-2014, 15:48:13
Когда нужно принудительно сохранять фокус у палитры - присваивайте её свойству KeepFocus значение true
Вот классный (хоть и старый) гайд по работе с палитрами (http://forums.autodesk.com/autodesk/attachments/autodesk/152/26712/1/CP205-2_Mike_Tuersley.pdf)
Смотрите там Quirks / Combo Boxes

Блин. Чукча не читатель - чукча писатель..   :-X
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Александр Ривилис от 25-11-2014, 16:26:59
События типа TextBox.LostFocus не срабатывают.
А какие срабатывают? Например MouseLeave?
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Gennadiy от 25-11-2014, 16:37:23
MouseLeave срабатывает, так же как и все прочие, связанные с перемещением мышки, но при простом перемещении мне не нужно выходить из редактирования, нужно только если окно autocad получает фокус ввода. Думаю здесь без WinAPI не обойтись.
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Александр Ривилис от 25-11-2014, 17:40:21
Думаю здесь без WinAPI не обойтись.
Думаю можно обойтись, но нужно подбирать подходящее. Тут возможно сработает одно из событий Editor (возможно EnteringQuiescentState или LeavingQuiescentState). Возможно поможет одно из событий Editor.PointMonitor
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Gennadiy от 25-11-2014, 17:55:51
Пробовал EnteringQuiescentState - не совсем то что нужно, по поведению похоже в палитре свойств AutoCAD сделано через WinAPI, в котором я плохо разбираюсь.
Попробую ещё погуглить как отловить передачу фокуса окну AutoCAD через WinAPI.
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Александр Ривилис от 25-11-2014, 18:05:45
Возможно эта статья тебе поможет: http://adn-cis.org/kak-realizovat-windows-xuk-s-ispolzovaniem-acedregisterfilterwinmsg-v-.net.html
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Андрей Бушман от 25-11-2014, 22:09:11
Технологии WinForms и WPF имеют одноимённый класс Control в составе иерархий своих классов. В обоих случаях он имеет событие Control.LostFocus. На вкладках пользовательских палитр AutoCAD ты можешь создавать элементы как WinForms, так и WPF.

RTFM (MSDN)
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Дима_ от 25-11-2014, 22:54:58
Если конечно изменение того свойства не загружает ПК на пару минут - а чего не хотите менять "на лету" - ИХМО так в большинстве случаев "интерактивней" и дружелюбней для пользователя, а эти выбрал->подтвердил - по моему - наследие доса. Я наоборот "матерюсь" на автокад, что если операция "долговата", надо потоки в очередь ставить и выполнять только актуальный.
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Андрей Бушман от 25-11-2014, 23:02:34
Если конечно изменение того свойства не загружает ПК на пару минут - а чего не хотите менять "на лету" - ИХМО так в большинстве случаев "интерактивней" и дружелюбней для пользователя, а эти выбрал->подтвердил - по моему - наследие доса. Я наоборот "матерюсь" на автокад, что если операция "долговата", надо потоки в очередь ставить и выполнять только актуальный.
Несколько раз прочитал это "казнить нельзя помиловать". Ничего не понял. Сдаюсь, расставить здесь запятые так, чтобы шарада разгадалась, я не смог. :)
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Александр Ривилис от 26-11-2014, 00:27:36
Сдаюсь, расставить здесь запятые так, чтобы шарада разгадалась, я не смог. :)
Я тоже. Но это полбеды. Главное я не понял какое это отношение имеет к вопросу Gennadiy.
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Дима_ от 26-11-2014, 00:49:07
Главное я не понял какое это отношение имеет к вопросу Gennadiy.
Не знаю как правильно выразить - но можно сказать "глобальное". Как я понял, у него основной вопрос как отловить потерю фокуса для запуска функции "синхронизации" TextBox поля с чертежом, а я задаю вопрос - а надо-ли оно? Можно подписаться на событие изменения поля и вносить изменения "на каждой букве" - современные машины это в абсолютном большинстве случаев позволяют делать "не напрягаясь", да и пользователю так наглядней.
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Александр Ривилис от 26-11-2014, 00:53:10
Думаю, что это возможно и даже не особо сложно. Только делать это нужно из главной задачи. Но это несколько выбивается из общего интерфейса AutoCAD и будет в начале как минимум не очевидно пользователям.
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Андрей Бушман от 26-11-2014, 10:14:46
Я там выше, вроде как показал родное решение, что называется "из коробки". Чем оно-то не устраивает?
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Gennadiy от 26-11-2014, 10:51:25
Я там выше, вроде как показал родное решение, что называется "из коробки". Чем оно-то не устраивает?

Если ты про Control.LostFocus, то не работает это в данном случае. LostFocus срабатывает при перемещении фокуса на другой Control в палетке (например при нажатии Enter, Tab или просто мышкой щелкнуть на другом Control), но если я щелкаю в области окна autocad, то Control.LostFocus не работает.
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Дмитрий Загорулькин от 26-11-2014, 11:18:39
События щелчков и нажатия клавиш в контексте AutoCAD я обрабатывал с помощью такого решения: http://through-the-interface.typepad.com/through_the_interface/2008/05/filtering-windo.html
В двух словах: перед обработкой действия (нажатия кнопки мыши или клавиши), Application генерирует событие PreTranslateMessage. В его аргументе типа PreTranslateMessageEventArgs содержатся данные о том, какое событие произошло.
Название: Re: Как отловить потерю фокуса в PaletteSet
Отправлено: Gennadiy от 26-11-2014, 15:48:05
Да уж, пришлось изрядно повозиться чтобы найти более-менее приемлемое для меня решение.

Вот код, может кому ещё пригодится:

Код - C# [Выбрать]
  1. PaletteSet ps; // моя палетка
  2.  
  3.  public struct RECT
  4.  {
  5.     public int Left;
  6.     public int Top;
  7.     public int Right;
  8.     public int Bottom;
  9.   }
  10.  
  11.    const int WM_LBUTTONDOWN = 513;
  12.    const int WM_LBUTTONUP = 514;
  13.  
  14.   [DllImport("user32.dll", SetLastError = true)]
  15.   static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
  16. ...
  17.  
  18. AcAp.PreTranslateMessage += AcAp_PreTranslateMessage;
  19.  
  20.     void AcAp_PreTranslateMessage(object sender, PreTranslateMessageEventArgs e)
  21.     {
  22.       if (e.Message.message == WM_LBUTTONDOWN ||
  23.            e.Message.message == WM_LBUTTONUP)
  24.       {
  25.         RECT rct = new RECT();
  26.         GetWindowRect(ps.Handle, ref rct);
  27.         Point location = new Point(rct.Left, rct.Top);
  28.         Rectangle rec = new Rectangle(location, ps.Size);
  29.         if (!rec.Contains(new Point(e.Message.pt_x, e.Message.pt_y)))
  30.         {
  31.             // здесь завершаю редактирование в TextBox
  32.         }
  33.       }
  34.     }
  35.  

Суть в том чтобы отследить щелчок мышки за пределами палетки и закончить редактирование TextBox на палетке

Можно было бы обойтись без WinAPI функции GetWindowRect если бы ps.Location всегда выдавал координаты верхнего левого угла,
но блин это свойство зависит от того плавающая ли палетка или закрепленная и к какой стороне прикреплена!

Спасибо всем за помощь.