Переключение на Главную Страницу Страницы: 1 [2]  ОтправитьПечать
Очень популярная тема (более 25 ответов) Внешняя компонента: обработка событий (число прочтений - 11588 )
artbear
1c++ developer
1c++ moderator
Отсутствует


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

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


Можно попробовать передавать контекст вызвавшей формы в ВК параметром.
1С-ка при передаче должна контекст завернуть в CBLExportContext (т.е. 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: Внешняя компонента: обработка событий
Ответ #16 - 20. Ноября 2007 :: 11:12
Печать  
Отпишись о результатах, лады?
  

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: Внешняя компонента: обработка событий
Ответ #17 - 20. Ноября 2007 :: 14:13
Печать  
artbear писал(а) 20. Ноября 2007 :: 11:12:
Отпишись о результатах, лады?


Ок. По ходу постановки задачи возникли вопросы:
1. Как определить, имеется ли в контексте метод с заданным именем и параметрами?
2.  Как вызвать метод с нужными параметрами?
Вижу готовый вариант реализации в посте #4. Есть ли другие варианты реализации?
  
Наверх
ICQ  
IP записан
 
Thor
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 82
Зарегистрирован: 12. Июля 2006
Re: Внешняя компонента: обработка событий
Ответ #18 - 28. Ноября 2007 :: 15:59
Печать  
Help! Не получается. Не ловится метод глобального модуля. Вот код:
Код
Выбрать все
function TAddInObject.CallEventProcedure(ProcedureName: string): Integer;
var MethodID: Integer;
    DispParams: TDispParams;
    ExcepInfo: TExcepInfo;
    Status: HResult;
    VarResult, obj, t: Variant;
begin
   CallEventProcedure := 1;

   obj := OleVariant(pCurrentConnection).AppDispatch;
   IDispatch(obj)._AddRef;
   //t := obj.OnTimer;
   MethodID := 0;
   if IDispatch(obj).GetIDsOfNames(GUID_NULL, @ProcedureName, 1, LOCALE_USER_DEFAULT, @MethodID) = S_OK then
	begin

	   DispParams.rgvarg:= nil;
	   DispParams.rgdispidNamedArgs := nil;
	   DispParams.cArgs := 0;
	   DispParams.cNamedArgs := 0;

	   t := obj.MethodFounded;
	   Status := IDispatch(obj).Invoke(MethodID, GUID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, DispParams, @VarResult, @ExcepInfo, nil);
	   if Status <> S_OK then
	   begin
		DispatchInvokeError(Status, ExcepInfo);
	   end;
	end
   else
	begin
	   t := obj.MethodNotFounded(OleVariant(ProcedureName), OLEVariant(MethodID));
	end;

   obj := Unassigned;
end;
 



Переменная pCurrentConnection - атрибут(член) класса TAddInObject, инициализируется следующим образом:
Код
Выбрать все
function TAddInObject.Init(pConnection: IDispatch): HResult; stdcall;
var iRes : Integer;
begin
     ...
     pCurrentConnection := pConnection;

     Init := S_OK;
end; 



Этот код срабатывает следующим образом: вызывается CallEventProcedure c параметром "OnTimer", при этом отрабатывает вызов obj.MethodNotFounded (т.е. GetIDsOfNames не нашла метод), хотя напрямую obj.OnTimer срабатывает. Не могу понять, в чем дело? Плачущий

P.S. OnTimer, MethodFounded, MethodNotFounded - процедуры глобального модуля, объявленные с признаком "Экспорт"

P.P.S. Сразу признаюсь - в Delphi я не силен, но вот пришлось самостоятельно заняться изысканиями Озадачен
  
Наверх
ICQ  
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Внешняя компонента: обработка событий
Ответ #19 - 30. Ноября 2007 :: 13:06
Печать  
Попробуй MethodName сделать Widestring:
MethodName    : Widestring;
есть подозрение, что нарываешься на абракадабру вместо русских буковок в названии метода.
  
Наверх
 
IP записан
 
Thor
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 82
Зарегистрирован: 12. Июля 2006
Re: Внешняя компонента: обработка событий
Ответ #20 - 30. Ноября 2007 :: 20:14
Печать  
sadovnikov писал(а) 30. Ноября 2007 :: 13:06:
Попробуй MethodName сделать Widestring:
MethodName    : Widestring;
есть подозрение, что нарываешься на абракадабру вместо русских буковок в названии метода.

Спасибо большое, помогло Очень довольный. Хотя я имена методов на английском указывал. Забыл, что СОМ работает с Unicode-строками. Нарыл в документации по Делфи, что при работе с OLE-объектами Делфи делает неявную конвертацию в Уникод, ну а если самому вызывать, то нужно конвертировать явно. Воистину дьявол в деталях.
  
Наверх
ICQ  
IP записан
 
Thor
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 82
Зарегистрирован: 12. Июля 2006
Re: Внешняя компонента: обработка событий
Ответ #21 - 03. Декабря 2007 :: 14:23
Печать  
artbear писал(а) 20. Ноября 2007 :: 11:12:
Отпишись о результатах, лады?


Результаты изысканий.
1. Вызов процедур глобального контекста  происходит, как и ожидалось, независимо от наличия 1С++.
2. Вызов процедур контекста формы происходит только при загруженной 1С++, причем есть одна особенность: если загрузить 1С++ из контекста формы и затем генерировать события, то события контекстом не ловятся. Если закрыть и повторно открыть форму (при уже загруженной 1С++), то события начинают ловиться. Точно не уверен, может это "особенность" моей реализации Подмигивание, но явление наблюдается.
3. С классом проблем не обнаружил, все нормально отрабатывает.

Спасибо всем откликнувшимся за помощь, особенно Артуру ака artbear и Садовникову Олегу.

Во вложении тестовая конфигурация
  

EventTest.zip ( 1254 KB | Загрузки )
Наверх
ICQ  
IP записан
 
Thor
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 82
Зарегистрирован: 12. Июля 2006
Re: Внешняя компонента: обработка событий
Ответ #22 - 03. Декабря 2007 :: 14:25
Печать  
... и исходный код компоненты (Delphi 5)
  

DirectEvents.zip ( 1063 KB | Загрузки )
Наверх
ICQ  
IP записан
 
Thor
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 82
Зарегистрирован: 12. Июля 2006
Re: Внешняя компонента: обработка событий
Ответ #23 - 03. Декабря 2007 :: 14:29
Печать  
P.S. Еще один момент. Иногда наблюдается "зависание" 1С-ки в процессах. Условия, при которых это происходит, определить пока не удалось.
  
Наверх
ICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


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

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Внешняя компонента: обработка событий
Ответ #24 - 04. Декабря 2007 :: 12:42
Печать  
Thor писал(а) 03. Декабря 2007 :: 14:23:
2. Вызов процедур контекста формы происходит только при загруженной 1С++, причем есть одна особенность: если загрузить 1С++ из контекста формы и затем генерировать события, то события контекстом не ловятся. Если закрыть и повторно открыть форму (при уже загруженной 1С++), то события начинают ловиться. Точно не уверен, может это "особенность" моей реализации Подмигивание, но явление наблюдается.

Так и должно быть Улыбка
В разделе ФормЕкс не так давно (месяц или два назад) я давал правильный код для загрузки ВК во внешнем отчете.
С его помощью все будет работать!!
  

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


I Love YaBB 2!

Сообщений: 82
Зарегистрирован: 12. Июля 2006
Re: Внешняя компонента: обработка событий
Ответ #25 - 06. Декабря 2007 :: 11:26
Печать  
artbear писал(а) 04. Декабря 2007 :: 12:42:
Так и должно быть Улыбка
В разделе ФормЕкс не так давно (месяц или два назад) я давал правильный код для загрузки ВК во внешнем отчете.
С его помощью все будет работать!!


Ссылку, плиз. Не нашел Печаль.
  
Наверх
ICQ  
IP записан
 
artbear
1c++ developer
1c++ moderator
Отсутствует


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

Сообщений: 6303
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Внешняя компонента: обработка событий
Ответ #26 - 06. Декабря 2007 :: 11:52
Печать  
  

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


I Love YaBB 2!

Сообщений: 82
Зарегистрирован: 12. Июля 2006
Re: Внешняя компонента: обработка событий
Ответ #27 - 28. Декабря 2007 :: 14:19
Печать  
Всем привет.

Натолкнулся на новую бяку. Пытаюсь реализовать обработку события закрытия окна ВК с возможностью отмены закрытия. В 1С-ке в модуле КОП прописана процедура:
Код
Выбрать все
Процедура ПриЗакрытииОкна(ОтменаЗакрытия) Экспорт
    Если Вопрос("Закрыть окно?", "Да+Нет") = "Нет" Тогда
	  ОтменаЗакрытия = 1;
    КонецЕсли;
КонецПроцедуры 

Во внешней компоненте выполняется код:
Код
Выбрать все
aCancel := 0; //Integer
InvokeProc( 'ПриЗакрытииОкна', [aCancel] )
If aCancel = 0 Then
    Action := caFree
Else
    Action := caNone; 

, где InvokeProc - процедура, выполняющая проверку наличия метода в модуле КОП, упаковку параметров и вызов IDispatch.Invoke.

При выполнении все нормально отрабатывает, процедура вызывается, значение параметра ОтменаЗакрытия равно 0, при нажатии на кнопку "Нет" устанавливается новое значение = 1, но в компоненту оно не попадает!!!. Окно все равно закрывается. Подскажите, где я не прав и куда копать?
  
Наверх
ICQ  
IP записан
 
Chieftain
Senior Member
****
Отсутствует


___

Сообщений: 498
Местоположение: Тула
Зарегистрирован: 15. Февраля 2007
Пол: Мужской
Re: Внешняя компонента: обработка событий
Ответ #28 - 29. Декабря 2007 :: 08:26
Печать  
Thor писал(а) 28. Декабря 2007 :: 14:19:
где InvokeProc - процедура, выполняющая проверку наличия метода в модуле КОП, упаковку параметров и вызов IDispatch.Invoke.

Саму процедуру-то покажи
  
Наверх
ICQ  
IP записан
 
Переключение на Главную Страницу Страницы: 1 [2] 
ОтправитьПечать