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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Корректное создание COM-сервера, как реализовать? Стандартное описание из книг не помогло 
:(
    Опции темы
Caduser
Дата 24.1.2007, 06:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Есть много информации о том как сделать свой COM-сервер (внешне-процессный EXE) с помощью мастера Delphi "Automation Object Wizard". Однако поведение такого сервера будет несколько иным, чем у скажем у Word, Exel и т.д.)
1. Если при подсоединении клиентского приложения, COM-сервер не был запущен то он автоматически запускается - это правильно. Однако если закрыть клиента, то закрывается и запущенный им сервер - ЭТО НЕ ПРАВИЛЬНО (например Word, после отсоединения клиента остается запущенным). Может я просто выбрал не ту модель - ciMultiInstance, tmApartment?
2. Для соединения с Word можно использовать примерно такой код:
Код

  try  // Пытаемся подключиться к запущенному Word
    AppWord := GetActiveOleObject('Word.Application');
  except // не смогли подключиться - запускаем новый экземпляр приложения  
     AppWord := CreateOleObject('Word.Application);
  end;

Однако для самодельного COM-сервера это не сработает, почему??? нужно делать так:
Код

  CreateComObject(CLASS_MyApp) as IMyApp;

Как заставить свой COM-сервер вести себя аналогично Word???

Это сообщение отредактировал(а) Caduser - 24.1.2007, 06:22
PM MAIL ICQ   Вверх
CatATonik
Дата 24.1.2007, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



См. функции RegisterActiveObject и RevokeActiveObject
PM MAIL   Вверх
Caduser
Дата 24.1.2007, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(CatATonik @ 24.1.2007,  10:25)
См. функции RegisterActiveObject и RevokeActiveObject

Использование этих функций не помогло, приложение ведёт себя как и прежде: закрываем клиента - закрывается сервер. Вообще эти функции использует пример из JCL "jcl\examples\windows\delphitools\peviewer", не ясно зачем они? Может они срабатывают в Win98?

Это сообщение отредактировал(а) Caduser - 24.1.2007, 14:23
PM MAIL ICQ   Вверх
CatATonik
Дата 24.1.2007, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



У меня срабататывают, может чего-то не так делаешь? Они предназначены ровно для того, что ты описал и работать должны под всеми виндами (может кроме Vista и виндовс 3.1  smile )
PM MAIL   Вверх
Caduser
Дата 25.1.2007, 05:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Разобрался (спасибо CatATonik!), теперь работает как надо. В RegisterActiveObject необходимо устанавливать флаг ACTIVEOBJECT_STRONG тогда в процессе регистрации у объекта увеличивается счетчик ссылок и даже после отключения от объекта всех программ-клиентов объект из памяти не выгружается.
Вот работающий код:
Код

var
  FROTHandle: Integer;
  // ...
procedure TProgControl.Initialize;
begin
  inherited;
  OleCheck(RegisterActiveObject(Self as IUnknown, Class_PeViewerControl,
    ACTIVEOBJECT_STRONG, // вместо "ACTIVEOBJECT_WEAK"
    FROTHandle));
  {$IFDEF COMPILER5_UP}
  ComServer.UIInteractive := False;
  {$ENDIF}
end;

destructor TProgControl.Destroy;
begin
  OleCheck(RevokeActiveObject(FROTHandle, nil));
  inherited;
end;

initialization
  TAutoObjectFactory.Create(ComServer, TProgControl, Class_ProgControl,
    ciMultiInstance, tmApartment);

end.

Нашел еще одно решение:
Код

initialization
  TAutoObjectFactory.Create(ComServer, TProgControl, Class_ProgControl,
    ciMultiInstance, tmApartment);
  if Comserver.StartMode = smAutomation then
    ComObj.CoAddRefServerProcess;
finalization
  if Comserver.StartMode = smAutomation then
    ComObj.CoReleaseServerProcess;

так же увеличивает счетчик ссылок на единицу, однако для второго варианта уже не будет работать схема подключения типа:
Код

 try
    App1 := GetActiveOleObject('...');
  except
    try
      App1 := CreateOleObject('...');
    except
      ShowMessage('Не удалось подключиться!');
    end;
  end;

интересно почему?

Это сообщение отредактировал(а) Caduser - 25.1.2007, 05:20
PM MAIL ICQ   Вверх
CatATonik
Дата 25.1.2007, 09:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Потому что RegisterActiveObject заносит объект в системный список активных OLE объектов, по которой и происходит поиск при GetActiveOleObject, видимо во втором варианте этого не происходит.
PM MAIL   Вверх
Caduser
Дата 26.1.2007, 01:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Теперь все предельно ясно. Спасибо за помощь!
PM MAIL ICQ   Вверх
jashilko
Дата 6.5.2009, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



У меня такая проблема, каждый клиент создаёт свой сервер что ли. То есть, я регистрирую в сервере событие, каждому клиенту по кнопке делаю реакцию на это событие и пишу обработчик, получается так, что в одном клиенте я событие вызвал, а в других оно не вызывается, почеум так может быть?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.3178 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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