Модераторы: MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обработка события COM-объекта, Обработка события COM-объекта 
:(
    Опции темы
Ahmed
Дата 27.11.2006, 08:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 27.11.2006

Репутация: нет
Всего: нет



Господа, добрый день. Помогите разобраться с проблемой.
Нужно обработать событие com-объекта CreateSession( .. );
Это событие описано в интерфейсе 
 ISessionEvents = dispinterface
    ['{67В71FA4-9381-4061-B3BB-74A545C75874}']
    procedure CreateSession(const Session: GuiSession); dispid 514;
  end;
Есть пример на VBScript. Нужно это же сделать на Delphi. Кто сможет помочь?

Код

Dim objSapGui
Set objSapGui = GetObject("MyComObj") 
Dim objScriptingEngine
Set objScriptingEngine = objSapGui.GetScriptingEngine
WScript.ConnectObject objScriptingEngine, "Engine_"
Dim Waiting
Waiting = 1
Do While (Waiting = 1)
      WScript.Sleep(100)
Loop        
Set objScriptingEngine = Nothing
Set objSapGui = Nothing
Sub Engine_CreateSession(ByVal Session)
      Dim result
      result = MsgBox("Session created", vbOKCancel)
      If result = vbCancel then
        Waiting = 0
      End If
End Sub

PM MAIL   Вверх
Romkin
Дата 27.11.2006, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 189
Регистрация: 14.11.2006
Где: Москва

Репутация: нет
Всего: 5



На Delphi вообще-то достаточно сделать Import type library с инсталляцией компонента. Насколько я понял, объест самописный?
PM ICQ   Вверх
Ahmed
Дата 27.11.2006, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 27.11.2006

Репутация: нет
Всего: нет



Цитата(Romkin @ 27.11.2006,  11:23)
На Delphi вообще-то достаточно сделать Import type library с инсталляцией компонента. Насколько я понял, объест самописный?

К сожалению сом-объект несамописный. Я импортнул библиотеку типов. Просто как прикрутить к событию CreateSession свой обработчик. Через object inspector/events не получится, потому что это событие описано в другом интерфейсе.
PM MAIL   Вверх
Romkin
Дата 27.11.2006, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 189
Регистрация: 14.11.2006
Где: Москва

Репутация: нет
Всего: 5



В этом случае прикручивание состоит в том, что ты должен сам реализовать объект-обработчик.
Если импортнул библиотеку, то там, насколько я понял, и описан ISessionEvents.
Делай следующее: 
1. New -> ActiveX -> AutomationObject
2. Именуй как хочешь. О выборе Threading model - потом поговорим smile
3. в получившемся модуле в uses интерфейсной части сразу пиши модуль импорта библиотеки
4. View -> type library. Там на вкладке uses выбирай ту библиотеку, которую импортировал (намекаю: используй правую клавишу мыши)
5. ТАм же смело удаляй интерфейс только что созданного объекта
6. Вставай на кокласси в закладке implemets добавляй ISessionEvents
7. рефреш - и у тебя в модуле должен быть метод CreateSession.
Все. Пиши в этом методе, что нужно.
Можно и проще, но проще - объяснять дольше smile

Теперь модель потока: сделаешь апартмент, как по умолчанию - метод будет дергаться в другом потоке, нужна синхронизация. Рекомендую single, чтобы не париться...

А вот как запихнуть твой объект-событие в ScriptingEngine - тут надо смотреть на описание... Навскидку не скажу, что делает WScript.ConnectObject smile
Ну не работал я с IConnectionPoint smile
PM ICQ   Вверх
Ahmed
Дата 28.11.2006, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 27.11.2006

Репутация: нет
Всего: нет



Сделал.
Только теперь проект не компилируется. 

 TMyClass = class(TAutoObject, ISapSessionEvents)
  protected
    procedure CreateSession(const Session: GuiSession); stdcall;
   ...

 Ошибка : Interface type required
 Ругается на ISapSessionEvents


PM MAIL   Вверх
Romkin
Дата 28.11.2006, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 189
Регистрация: 14.11.2006
Где: Москва

Репутация: нет
Всего: 5



А что в ..._TLB.pas написано?
PM ICQ   Вверх
Ahmed
Дата 29.11.2006, 07:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 27.11.2006

Репутация: нет
Всего: нет



type
...
  ISapSessionEvents = dispinterface;
// *********************************************************************//
// DispIntf:  ISapSessionEvents
// Flags:     (4096) Dispatchable
// GUID:      {67A71FA4-9381-4061-B3BB-74A545C75874}
// *********************************************************************//
  ISapSessionEvents = dispinterface
    ['{67A71FA4-9381-4061-B3BB-74A545C75874}']
    procedure CreateSession(const Session: GuiSession); dispid 514;
...
  end;

таким образом декларирован.

PM MAIL   Вверх
Romkin
Дата 29.11.2006, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 189
Регистрация: 14.11.2006
Где: Москва

Репутация: нет
Всего: 5



А, только disp... Сорри, но тогда не пойдет smile
Я уже запутался. Забудь все, что я говорил, у тебя обычный объект с событиями.
Импортируй библиотеку с флажком "Generate component wrapper", тогда у тебя будет класс, с property CreateSession, и все будет прозрачно. Инсталлировать, кстати, и не надо, просто Create unit.
PM ICQ   Вверх
Ahmed
Дата 29.11.2006, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 27.11.2006

Репутация: нет
Всего: нет



Дело в том, что класс этого интерфейса не создается при импорте TLB-файла. Было бы все просто и прозрачно. События декларированы в интерфейсе ISapSessionEvents. И все. в TLB больше нет упоминания об этих событиях. Я поэтому и привел пример VBScript'a, в котором все работает.
PM MAIL   Вверх
Romkin
Дата 29.11.2006, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 189
Регистрация: 14.11.2006
Где: Москва

Репутация: нет
Всего: 5



Как это нет?! При импорте, если заказываешь враппер, создается класс, с нужным событием. Вручную писать - замучаешься.
Вот что примерно должно быть: 
Код

{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
  TEvProgProperties= class;
{$ENDIF}
  TEvProg = class(TOleServer)
  private
    FOnMsgShow: TEvProgOnMsgShow;
    FIntf:        IEvProg;
{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
    FProps:       TEvProgProperties;
    function      GetServerProperties: TEvProgProperties;
{$ENDIF}
    function      GetDefaultInterface: IEvProg;
  protected
    procedure InitServerData; override;
    procedure InvokeEvent(DispID: TDispID; var Params: TVariantArray); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy; override;
    procedure Connect; override;
    procedure ConnectTo(svrIntf: IEvProg);
    procedure Disconnect; override;
    procedure MsgShow(const MsgStr: WideString);
    property DefaultInterface: IEvProg read GetDefaultInterface;
  published
{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
    property Server: TEvProgProperties read GetServerProperties;
{$ENDIF}
    property OnMsgShow: TEvProgOnMsgShow read FOnMsgShow write FOnMsgShow;
  end;

И название последнего свойства - как раз обработчки события:
Код

  IEvProg = interface(IDispatch)
    ['{39BC12F2-7F7C-11DB-B744-00508B0973BE}']
    procedure MsgShow(const MsgStr: WideString); safecall;
  end;

  IEvProgEvents = dispinterface
    ['{39BC12F4-7F7C-11DB-B744-00508B0973BE}']
    procedure OnMsgShow(var MsgStr: WideString); dispid 1;
  end;

PM ICQ   Вверх
Ahmed
Дата 30.11.2006, 07:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 27.11.2006

Репутация: нет
Всего: нет



Не так выразился.
Ни в одном сгенеренном классе не описывается это событие "CreateSession".
Например,
Код

{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
  TGuiCollectionProperties= class;
{$ENDIF}
  TGuiCollection = class(TOleServer)
  private
    FIntf:        ISapGenericCollection;
{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
    FProps:       TGuiCollectionProperties;
    function      GetServerProperties: TGuiCollectionProperties;
{$ENDIF}
    function      GetDefaultInterface: ISapGenericCollection;
  protected
    procedure InitServerData; override;
    function Get_type_: WideString;
    function Get_Length: Integer;
    function Get_NewEnum: IUnknown;
    function Get_TypeAsNumber: Integer;
    function Get_Count: Integer;
  public
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy; override;
    procedure Connect; override;
    procedure ConnectTo(svrIntf: ISapGenericCollection);
    procedure Disconnect; override;
    procedure Add(Item: OleVariant);
    function ElementAt(Index: Integer): OleVariant;
    function Item(Index: OleVariant): OleVariant;
    property DefaultInterface: ISapGenericCollection read GetDefaultInterface;
    property type_: WideString read Get_type_;
    property Length: Integer read Get_Length;
    property NewEnum: IUnknown read Get_NewEnum;
    property TypeAsNumber: Integer read Get_TypeAsNumber;
    property Count: Integer read Get_Count;
  published
{$IFDEF LIVE_SERVER_AT_DESIGN_TIME}
    property Server: TGuiCollectionProperties read GetServerProperties;
{$ENDIF}
  end;

И так же примерно в других классах. 

PM MAIL   Вверх
Romkin
Дата 30.11.2006, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 189
Регистрация: 14.11.2006
Где: Москва

Репутация: нет
Всего: 5



Тогда вряд ли я сейчас смогу что-то сказать. Просто не попадалось такого.
Могу только подсказать, что использовать надо ConnectEvents, ручками. У потомков TOleServer как раз это есть. Прямо в Connect:
Код

procedure TGuiCollection.Connect;
var
  punk: IUnknown;
begin
  if FIntf = nil then
  begin
    punk := GetServer; // У тебя должно быть что-то другое, скорее всего
    ConnectEvents(punk);
    Fintf:= punk as IGuiCollection;
  end;
end;

//И перекрыть 
procedure TGuiCollection.InvokeEvent(DispID: TDispID; var Params: TVariantArray);
begin
  case DispID of
    -1: Exit;  // DISPID_UNKNOWN
   514: if Assigned(FCreateSession) then //угу, dispID 514 у тебя
            FCreateSession(const Session: GuiSession);
  end; {case DispID}
end;

Как все делается автоматически (как должно), можено увидеть, быстро создав ActiveX Library с Automation object, у которого при создании включено "Generate event support code". Эвенты вводятся как методы у dispinterface.
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: ActiveX/СОМ/CORBA"

Rrader
Girder

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Delphi
  • Вопросы по SQL и вопросы по базам данных, не связанные с Delphi, задавать здесь

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Rrader, Girder.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: ActiveX/СОМ/CORBA | Следующая тема »


 




[ Время генерации скрипта: 0.0480 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.