Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Очень популярная тема (более 25 ответов) Внешняя компонента: обработка событий (число прочтений - 11584 )
Thor
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 82
Зарегистрирован: 12. Июля 2006
Внешняя компонента: обработка событий
19. Ноября 2007 :: 12:09
Печать  
Всем привет.

Имеется следующая проблемка.
Есть внешняя компонента - визуальный объект, которая в 1С-ке открывается в отдельном окне (используется метод CreateAddinWindow). Нужно организовать взаимодействие между 1С-кой и компонентой с помощью событий. Сейчас события обрабатываюся стандартным образом - компонента генерирует внешнее событие, 1С-ка его ловит и обрабатывает. Проблема в том, что мне нужно ловить события в форме документа, из которого открывается окно компоненты, а так как фокус на окне компоненты, то события ловит ОбработкаВнешнегоСобытия() в глобальном модуле (форма документа неактивна Печаль).

Вопрос: как можно (эффектно и эффективно  Улыбка) реализовать обмен событиями в моем случае?
  
Наверх
ICQ  
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2344
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Внешняя компонента: обработка событий
Ответ #1 - 19. Ноября 2007 :: 13:13
Печать  
Фиксируй контекст открытого документа в глобальной переменной и используй
ОткрытьФорму и ПриПовторномОткрытии.
  
Наверх
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Внешняя компонента: обработка событий
Ответ #2 - 19. Ноября 2007 :: 13:14
Печать  
Если в 2-х словах, то нужно писать ВК по технологии Rainbow.
В ВК получать контекст, в котором создается AddinWindow (или передавать его явно при инициализации).
Посмотреть исходники 1С++ и из ВК вызывать методы контекста (т.е. процедуры-обработчики) напрямую.
Ключевое слово для поисков по исходникам 1С++ - CBLModule.
  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Внешняя компонента: обработка событий
Ответ #3 - 19. Ноября 2007 :: 13:24
Печать  
Степан, у Олега Садовникова есть несколько ВК, написанных по штатной технологии и использующих прямой вызов процедур/функций ГМ как обработчиков соответствующих событий.
Они написаны на Делфи, так что технология Rainbow для них недоступна Улыбка
Я знаю, что вызов событий ГМ идет с помощью соответствующих методов интерфейса IDispatch.
Более подробно Олег расскажет, наверное.

ЗЫ я ему отписался, но пока его в аське нету.
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Внешняя компонента: обработка событий
Ответ #4 - 19. Ноября 2007 :: 13:31
Печать  
artbear писал(а) 19. Ноября 2007 :: 13:24:
Они написаны на Делфи, так что технология Rainbow для них недоступна Улыбка
Я знаю, что вызов событий ГМ идет с помощью соответствующих методов интерфейса IDispatch.

О, нашел в хистори аськи
Цитата:
26.06.2007 19:55:29 Садовников Олег wrote:
Код
Выбрать все
MethodName := 'Инет_СтрокаОтКлиента';
if IDispatch(obj).GetIDsOfNames(GUID_NULL, @MethodName, 1, LOCALE_USER_DEFAULT, @MethodID) = S_OK then begin
      //Параметры идут в обратном порядке
      Args[0] := ConnectServer^.GUID;
      Args[1] := ConnectServer^.ReadStr;

      DispParams.rgvarg:=@Args;   //Инициализация массива Variant
      DispParams.rgdispidNamedArgs := nil;
      DispParams.cArgs := 2;
      DispParams.cNamedArgs := 0;
      IDispatch(obj).Invoke(MethodID, GUID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, DispParams, @VarResult, @ExcepInfo, @ArgErr);
end; 



27.06.2007 11:08:46 artbear wrote:
и таким макаром вызываются методы глобальника??

27.06.2007 11:08:56 Садовников Олег wrote:
Ага
Экспортируемый метод светится наружу как диспинтерфейс

27.06.2007 11:19:18 Садовников Олег wrote:
Код
Выбрать все
obj             : Variant;
function TRiK_Inet.Init(pConnection: IDispatch): HResult; stdcall;
var
  iLen : Integer;
begin
  p1c             := pConnection;
//Получение указателя на 1С
  if VarType(obj) And varTypeMask = varEmpty then  begin
    obj := OleVariant(p1c).AppDispatch;
    //Обязательно вызывать ТОЛЬКО _AddRef!!! Иначе 1С висит в процессах после закрытия
    IDispatch(obj)._AddRef;
  end; 


  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
trdm
1c++ power user
qt1l developer
1c++ moderator
Отсутствует



Сообщений: 2344
Местоположение: г. Ростов-на-Дону
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Внешняя компонента: обработка событий
Ответ #5 - 19. Ноября 2007 :: 13:58
Печать  
а чем (#1) не угодил?
Просто и без ВК копательства.
  
Наверх
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Внешняя компонента: обработка событий
Ответ #6 - 19. Ноября 2007 :: 14:04
Печать  
Посылка событий через ВнешнееСобытие является асинхронной, т.е. будет вызвана после окончания работы кода ВК Печаль
т.е. для нормальной обработки событий нужно писать более сложные обработки, чем в случае прямого вызова методов ГМ.
Но, возможно, кому-то нравится подобное извращение Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Внешняя компонента: обработка событий
Ответ #7 - 19. Ноября 2007 :: 14:05
Печать  
Там вызываются экспортные методы ГМ. А вопрос был задан так:Thor писал(а) 19. Ноября 2007 :: 12:09:
Проблема в том, что мне нужно ловить события в форме документа, из которого открывается окно компоненты


Можно попробовать передавать контекст вызвавшей формы в ВК параметром.
1С-ка при передаче должна контекст завернуть в CBLExportContext (т.е. IDispatch) и выставить наружу экспортные методы.
  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Внешняя компонента: обработка событий
Ответ #8 - 19. Ноября 2007 :: 14:08
Печать  
steban писал(а) 19. Ноября 2007 :: 14:05:
Можно попробовать передавать контекст вызвавшей формы в ВК параметром.
1С-ка при передаче должна контекст завернуть в CBLExportContext (т.е. IDispatch) и выставить наружу экспортные методы.

Вот этот вариант мне нравится, думаю, что это подойдет.
Но думаю, что он сработает только при использовании ТурбоБЛ или 1С++ Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
steban
1c++ developer
Отсутствует


#define sizeof(x) rand()

Сообщений: 787
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Внешняя компонента: обработка событий
Ответ #9 - 19. Ноября 2007 :: 14:11
Печать  
artbear писал(а) 19. Ноября 2007 :: 14:08:
Но думаю, что он сработает только при использовании ТурбоБЛ или 1С++ Улыбка

а я думаю, и без 1С++ прокатит Улыбка
  

int getRandomNumber()&&{&&  return 4; //chosen by fair dice roll&&         //guaranteed to be random&&}
Наверх
 
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Внешняя компонента: обработка событий
Ответ #10 - 19. Ноября 2007 :: 14:17
Печать  
Вот такое точно работает:
  private
    { Private declarations }

    p1c         : OleVariant; //IDispatch; //Указатель на 1С
    KontDoc     : OleVariant; //Контекст документа, из которого открыли журнал
...

  Str:='""O"",""0"",""0"",""'+VarToStr(ADOQuery1.FieldValues['IDDOCDEF'])+'"",""0"",""0"",""';
  Str:=Str+VarToStr(N)+'""';
  ret:=obj.EvalExpr('ЗначениеИзСтрокиВнутр("{'+Str+'}")');
  KontDoc.Документ:=ret;
  KontDoc.Активизировать('КомментарийКСтроке');

P.S. Не пинайте сильно, это еще до рождества  RainBow было Печаль
  
Наверх
 
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Внешняя компонента: обработка событий
Ответ #11 - 19. Ноября 2007 :: 14:34
Печать  
Нет, ИМХО вариант без загрузки ТурбоБЛ/1С++ контекст (GroupContext) просто не увидит методы модуля, т.е. GroupContext::FindMethod(НаименованиеМетодаМодуляФормы) просто вернет -1.
Т.к. только в этих ВК в GroupContext добавлена возможность обращения к методам/свойствам модуля формы через контекст.
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Thor
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 82
Зарегистрирован: 12. Июля 2006
Re: Внешняя компонента: обработка событий
Ответ #12 - 19. Ноября 2007 :: 14:51
Печать  
trdm писал(а) 19. Ноября 2007 :: 13:13:
Фиксируй контекст открытого документа в глобальной переменной и используй
ОткрытьФорму и ПриПовторномОткрытии.

Я рассматривал такой вариант, но у него есть существенное ограничение - работа в одном сеансе только с одним окном внешней компоненты. Видимо, это самый простой способ.

steban писал(а) 19. Ноября 2007 :: 13:14:
Если в 2-х словах, то нужно писать ВК по технологии Rainbow.
В ВК получать контекст, в котором создается AddinWindow (или передавать его явно при инициализации).
Посмотреть исходники 1С++ и из ВК вызывать методы контекста (т.е. процедуры-обработчики) напрямую.
Ключевое слово для поисков по исходникам 1С++ - CBLModule.

В том то и дело, что компонента на Delphi написана Озадачен

А будет ли рабочим такой вариант: сделать компоненту ActiveX-объектом с генерацией событий, разместить его на форме как элемент диалога. Будут ли в этом случае ловиться события в контексте формы? Вроде бы она активной будет Озадачен

  
Наверх
ICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


Эх, дайте что-нибудь новенькое
да полезное потести

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Внешняя компонента: обработка событий
Ответ #13 - 19. Ноября 2007 :: 14:56
Печать  
Автор, ты наши последние посты читал или еще не успел?
Тебе предложили вариант решения Улыбка
  

OpenConf developer :: http://openconf.1cpp.ru&&FormEx developer :: http://formex.dorex.ru&&1C++ active developer && tester :: www.1cpp.ru
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Thor
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 82
Зарегистрирован: 12. Июля 2006
Re: Внешняя компонента: обработка событий
Ответ #14 - 19. Ноября 2007 :: 15:00
Печать  
steban писал(а) 19. Ноября 2007 :: 14:05:
Там вызываются экспортные методы ГМ. А вопрос был задан так:Thor писал(а) 19. Ноября 2007 :: 12:09:
Проблема в том, что мне нужно ловить события в форме документа, из которого открывается окно компоненты


Можно попробовать передавать контекст вызвавшей формы в ВК параметром.
1С-ка при передаче должна контекст завернуть в CBLExportContext (т.е. IDispatch) и выставить наружу экспортные методы.


Интересный вариант, дома попробую, спасибо. Кстати, если контекст КОП передать, то сработает? Дело в том, что я с компонентой через КОП работаю, было бы неплохо инкапсулировать обработку событий в КОП.
  
Наверх
ICQ  
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать