Окно внешней компоненты (Delphi) при повторном вызове не получает фокус ввода #662185


#0 by and_del
Много лет работает внешняя компонента написанная на основе кода из . Спасибо автору. Во внешней компоненте реализованы функции в которых открываются модальные окна. По некоторым причинам экземпляр окна сразу же после закрытия убивать нельзя. Соответственно есть глобальная переменная, и при повторном вызове, если эта переменная не nil, то осуществляется повторный вызов окна из существующего экземпляра.  ...  if ZSel_frm=nil Then  ... До сего момента она вызывалась из под 1С версии 7.7. Сейчас осуществляется переход на 1С 8.2. Обнаружена проблема. При повторном вызове из 1С 8.2 окно открывается, но фокус ввода на него не передается. Кажется что окно "подвисло". Но это не так, окно отрабатывает сообщения скрола от колеса мыши (только если фокус ввода Notepad++). Проблему решил принудительным Free и созданием нового экземпляра. Вопросы. 1. В чем причина описанной проблемы? 2. Как правильно вызывать дельфийские (модальные) окна из внешней компоненты?
#1 by Serginio1
Вообщето нужно хэндл приложения передавать например полученной из GetAppMainFrame If Assigned(pExtWndsSupport) Then     Begin Для модального лучше TZakazSelFrm.Create(Application,DM1.OraSession1);
#2 by and_del
Не помогло. Взял чистый исходник TestVK. Добавил форму Form1. Добавил в Init: Вызов окна:  ...      m_execute:        begin          if Form1=nil Then Теперь не появляется второй иконки. Но проблема при повторном вызове meth4 осталась. Про Form2:=TForm1.CreateParented(ChildWnd); не понял. Это вариант child окна MDI?
#3 by Serginio1
Да
#4 by Serginio1
Я бы тебе посоветовал использовать Исходник ВК которая загружает Объект Автоматизации поддерживающий ITypeInfo и выполняет все его свойства и методы через IlanguageExtender. Поддержка Var и Out параметров, передача в методы Объектов 1С, а так же поддержка Свойст Массивов. Сам использую уже лет 10.
#5 by and_del
Спасибо, но изучать и отлаживать другой механизм нет времени. Как писал в первом посте проблему решил при помощи костыля (принудительное Free перед повторным вызовом). Было интересно почему отработанный с 1С 7.7 механизм дал такой сбой на 1С версии 8.2.
#6 by and_del
Я не программист 1С. У меня самописная производственная система. Внешний компонент работает на интеграцию двух систем. Пока поддержка передачи объектов 1С не требовалась. Обхожусь простыми типами данных и процедурной парадигмой.
#7 by Serginio1
Да там просто пишешь Automation объект. В него добавляешь метод procedure TAddinTypeInfo.InitFrom1C(const pCon: IDispatch); begin     If Not Assigned(pConn) Then Загрузить объект в ВК можно двумя способами Где    AddInFromITypeInfo.dll это данная ВК;   AddinTypeInfo.AddinTypeInfo пример Automation Object находящийся в VKITypeInfoAddinTypeInfo
#8 by and_del
Спасибо, скачал Ваш компонент. Если понадобится объектов 1С, то обязательно разберусь. Но по обозначенной мной проблеме, не думаю, что дополнительный объект автоматизации изменит грабли с потерей фокуса ввода дельфийской VCL формы при вызове из 1С 8.2.
#9 by Serginio1
Ну а применял  SetFocus для окна формы?
#10 by and_del
Нет. Я кликал мышью по окну, нажимал Alt+Tab. Не помогло. При нажатии Alt+Tab заметил, что 1С вообще исчезло из ленты окошек.
#11 by Serginio1
Если используешь TForm1.Create(Application) то по идее 1С не должно исчезать. Но впринципе проще использовать Free после использования формы или установки procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin   action:=CaFree; end;
#12 by and_del
Само окно 1С не исчезает, исчезает иконка с изображением окна 1С из ленты переключений между задачами windows, которая появляется при нажатии Alt+Tab. И еще раз повторю, что такое происходит только при повторном вызове, при первом вызове все нормально работает. За подсказку с "action:=CaFree" спасибо, я в курсе. Добавил после Form1.ShowModal; Form1.SetFocus; ничего не изменилось. Операционка: Windows 7 Еще один момент, программист 1С встроил загрузку компоненты в глобальный модуль, а вызов метода происходит из обработки заполнения табличных частей. При попытке закрыть окно 1С задает вопрос "Завершить работу с программой?", при положительном ответе окна 1С закрываются, но процесс остается висеть в памяти.
#13 by Serginio1
Form1.SetFocus; после ShowModal; не имеет смысла. Надо в Form1 FormShow
#14 by Serginio1
А по поводу висения здесь могут быть две причины. Не вызов )._AddRef для AppDispatch obj:=OleVariant(Pconn).AppDispatch; IDispatch(obj)._AddRef; Второе использование переменных модуля а не объекта
#15 by and_del
Если Вы про висение после завершения работы, то тут все гораздо проще, как я думаю, висит потому что ShowModal не вернул управление.
#16 by Serginio1
Ну если окно открыто в модальном режиме, то закрыть окно 1С проблематично.
#17 by Serginio1
Вообще для интереса перед закрытием получить Счетчик ссылок через_AddRef и  Release компоненты.
#18 by and_del
Видимо я слишком коротко написал про закрытие 1С. В штатном режиме все отлично закрывается без проблем. Вот когда модальное окно "подвисло", то ничего не остается сделать как через средства Windows "закрыть окно". Так как в такой момент ни окна 1С, ни окно моей компоненты не реагируют на клики мыши и нажатия клавиш. И вот когда в Windows после клика правой кнопкой мыши над иконкой 1С в панели задач выбираешь "Закрыть окно", то 1С "отлипает", но только с одним конкретным вопросом "Завершить работу с программой?". При положительном ответе еще может спросить нужно ли сохранить данные. И вот только в этом случае после закрытия окон процесс остается висеть в памяти. Я думаю, что это связано с "подвисшим" модальным окном внешней компоненты. И это не является проблемой. И на мой взгляд вполне объяснимо.
#19 by Serginio1
Сделай в компоненте Метод закрывающий модальное окно. И вызывай его при ПриЗавершенииРаботыСистемы Процедура ПриЗавершенииРаботыСистемы
Тэги: 1С 8
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С