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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как получить коллекцию от add-in-а? возврат коллекции реализованной в add-in 
V
    Опции темы
cat512
Дата 14.10.2010, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Да, забыл написать, там для примера что выложил
надо в реестр добавить раздел
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\Word\Addins\OutlookGrabberAddin.OutlookGrabber
а в разделе создать параметр LoadBehavior со значением 3
PM MAIL   Вверх
aleksh
Дата 14.10.2010, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



твой пример работает отлично, но вот в моем адд-ин-е реализовать такое не полуается
вот в этой строчке
Код

if Pointer(Grabber) <> Pointer(Self as IOutlookGrabber) then

self пустой...
PM MAIL   Вверх
cat512
Дата 14.10.2010, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



smile, почему пустой? Пустой он может быть только в одном случае - если объект не создался. Выложи код, посмотрим. 
PM MAIL   Вверх
aleksh
Дата 14.10.2010, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



заработало!
но есть один вопрос: для чего следующий код
Код

      if Pointer(Grabber) <> Pointer(Self as IOutlookGrabber) then
      begin
//it calls interface the firsts object from any other object
        Result := Grabber.GetData;
      end
      else begin
//        Result := -5;
//this code only performs in the firsts object

?
точнее - что за объекты?
PM MAIL   Вверх
cat512
Дата 14.10.2010, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Эх, значит не понял ты для чего мы кашу с моникером городили :-(

У нас при запуске оффисного приложения создаётся Основной (назовём его посредником) объект,
владеющий интерфейсами выполняемого приложения! Остальные объекты, создаваемые не оффисным приложением, не имеют доступа к интерфейсам офф. прил. Поэтому, что бы получить доступ к оффис. приложению, в других объектах, мы "ходим" через посредника, который находится в адресном пространстве конкретного приложения word, и возвращает нам его интерфейсы. Так же через него, будут ходить объекты, создаваемые другими копиями оффисного прилож., хотя реально у них должны быть интерфейсы своего приложения.
В принципе всё зависит от реализации. Можно например сделать, что бы посредник грабил данные в свои структуры, а в других объектах ты будешь получать интерфейсы на эти структуры и работать с ними. А ещё лучший вариант Реализовать фабрику, которая будет возвращать указатель на единственный созданный объект, IMHO так будет правильней. 

Код о котором ты спрашиваешь, разделяет контексты выполнения для обекта "посредника" и остальных объектов. Т. е. в посреднике будет выполняться только код, находящийся в блоке
Код

else begin
//        Result := -5;
//this code only performs in the firsts object
end;

В остальных объектах, будет выполняться код
Код

      if Pointer(Grabber) <> Pointer(Self as IOutlookGrabber) then
      begin
//it calls interface the firsts object from any other object
        Result := Grabber.GetData;
      end

Т. е. условие
Код

if Pointer(Grabber) <> Pointer(Self as IOutlookGrabber) then

определяет, в контексте какого объекта мы сейчас находимся




Это сообщение отредактировал(а) cat512 - 14.10.2010, 16:17
PM MAIL   Вверх
aleksh
Дата 14.10.2010, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(cat512 @  14.10.2010,  16:08 Найти цитируемый пост)
Эх, значит не понял ты для чего мы кашу с моникером городили :-(

это понял, не надо уж так...
просто во время тестирования не смог создать условия при котором результат был тру - вот и спрашиваю, мол, когда такое может произойти

кстати - все реализовал, работает отлично
Цитата(cat512 @  13.10.2010,  17:32 Найти цитируемый пост)
И ещё, было бы не плохо изменить(дополнить) название темы (Ну что - то типа: Addin DLL singleton, или как - нибудь по другому),
потому как некоторые люди уже спрашивали как делать подобные весчи, совсем не давно. 

может лучше создать отдельную тему, в ней сделать ссылку на эту и выложить код адд-ин-а?

Добавлено через 1 минуту и 23 секунды
забыл вопрос пометить решенным
PM MAIL   Вверх
cat512
Дата 14.10.2010, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



На самом деле условие выполняется, как тру так и фолсе, можешь проверить, изменив условие на противоположное, соответственно инвертировав и блоки кода тоже.
Просто во время тестирования, отладчик показывает только контекст выполнения либо посредника, либо других объектов, т. е в один момент времени он может работать либо с word-ом, либо с другим приложением, поэтому ты на смог посмотреть полный стэк вызовов.

На счёт названия темы, не знаю, сделай так как посчитаешь правильным.

Это сообщение отредактировал(а) cat512 - 14.10.2010, 16:37
PM MAIL   Вверх
aleksh
Дата 14.10.2010, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(cat512 @  14.10.2010,  16:32 Найти цитируемый пост)
На счёт названия темы, не знаю, сделай так как посчитаешь правильным.

если не ошибаюсь - название темы не меняется, поэтому создам, пожалуй, новую

Добавлено через 8 минут и 49 секунд
большое спасибо cat512 за помощь в написании ниже приведенного кода
Код

unit uAddin;

interface

uses
  Classes, Windows, ComObj, ActiveX, ABOutlook_TLB, StdVcl, Registry,
  Variants, sysutils, dialogs,
  AddInDesignerObjects_TLB, Outlook_TLB, office_tlb;

type

  TABFactory = class(TAutoObjectFactory)
  public
    procedure UpdateRegistry(Register: Boolean); override;
  end;

  TAB = class(TAutoObject, IAB, _IDTExtensibility2)
  private
    outlook, namespace, cfolder: OleVariant;
    FApp, FAddin: IDispatch;
    FRotEntry: LongInt;
  protected
    function CountOfBooks: Integer; safecall;
    function NameOfBooks(index: Integer): WideString; safecall;
    function CountOfContacts(const name: WideString): Integer; safecall;
    function FieldOfContacts(const book: WideString; index,
      field: Integer): WideString; safecall;
    { Protected declarations }
  public
    constructor Create;
    procedure OnConnection(const Application: IDispatch; ConnectMode: ext_ConnectMode;
                           const AddInInst: IDispatch; var custom: PSafeArray); safecall;
    procedure OnDisconnection(RemoveMode: ext_DisconnectMode; var custom: PSafeArray); safecall;
    procedure OnAddInsUpdate(var custom: PSafeArray); safecall;
    procedure OnStartupComplete(var custom: PSafeArray); safecall;
    procedure OnBeginShutdown(var custom: PSafeArray); safecall;
  end;

implementation

uses ComServ;

{ TAdFactory }

procedure TABFactory.UpdateRegistry(Register: Boolean);
var Reg:TRegistry;
begin
  inherited;
  Reg:=TRegistry.Create;
  try
    Reg.RootKey:=HKEY_LOCAL_MACHINE;
    if Register then
      begin
        if Reg.OpenKey('Software\Microsoft\Office\Outlook\Addins\'+GetProgID, TRUE) then
          Reg.WriteInteger('LoadBehavior', 3);
      end
    else
      if Reg.KeyExists('Software\Microsoft\Office\Outlook\Addins\'+GetProgID) then
        Reg.DeleteKey('Software\Microsoft\Office\Outlook\Addins\'+GetProgID);
  finally
    Reg.Free;
  end;
end;

{ TAd }

procedure TAB.OnAddInsUpdate(var custom: PSafeArray);
begin
end;

procedure TAB.OnBeginShutdown(var custom: PSafeArray);
begin
end;

procedure TAB.OnConnection(const Application: IDispatch;
  ConnectMode: ext_ConnectMode; const AddInInst: IDispatch;
  var custom: PSafeArray);
var
  Mon: IMoniker;
  Rot: IRunningObjectTable;
begin
Mon := nil;
Rot := nil;
FApp := Application;
FAddin := AddInInst;
if CreateItemMoniker(nil,PWideChar(GuidtoString(IAB)),Mon) <> S_OK then
  RaiseLastOSError;

if GetRunningObjectTable(0, Rot) <> S_OK then
  RaiseLastOSError;

if Rot.Register(ROTFLAGS_REGISTRATIONKEEPSALIVE,Self as IAB,Mon,FRotEntry) <> S_OK then
  RaiseLastOSError;

outlook := application;
namespace := outlook.getnamespace('MAPI');
cfolder := namespace.getdefaultfolder(olfoldercontacts);
end;

procedure TAB.OnDisconnection(RemoveMode: ext_DisconnectMode;
  var custom: PSafeArray);
var
  Rot: IRunningObjectTable;
begin
FApp := nil;
FAddin := nil;
if (FRotEntry <> -1) and (GetRunningObjectTable(0, Rot) <> S_OK) then
  Rot.Revoke(FRotEntry);
cfolder := unassigned;
namespace := unassigned;
outlook := unassigned;
end;


procedure TAB.OnStartupComplete(var custom: PSafeArray);
begin
end;

function TAB.CountOfBooks: Integer;
var
  Rot: IRunningObjectTable;
  Mon: IMoniker;
  TargetObject: IUnknown;
  AB: IAB;
  I: Integer;
begin
if CreateItemMoniker(nil, PWideChar(GuidToString(IAB)), Mon) <> S_OK then Exit;;
if not (GetRunningObjectTable(0, Rot) = S_Ok) then Exit;
if Rot.GetObject(Mon, TargetObject) = S_OK then
  begin
    if TargetObject.QueryInterface(IAB, AB) = S_OK then
      with AB do
        begin
          if Pointer(AB) <> Pointer(Self as IAB) then
            begin
              Result := AB.CountOfBooks;
            end
          else
            begin
              result := 1;

              for I := 1 to cfolder.folders.count do
                inc(result);
            end;
        end;
  end;
end;

function TAB.NameOfBooks(index: Integer): WideString;
var
  Rot: IRunningObjectTable;
  Mon: IMoniker;
  TargetObject: IUnknown;
  AB: IAB;
begin
if CreateItemMoniker(nil, PWideChar(GuidToString(IAB)), Mon) <> S_OK then Exit;;
if not (GetRunningObjectTable(0, Rot) = S_Ok) then Exit;
if Rot.GetObject(Mon, TargetObject) = S_OK then
  begin
    if TargetObject.QueryInterface(IAB, AB) = S_OK then
      with AB do
        begin
          if Pointer(AB) <> Pointer(Self as IAB) then
            begin
              Result := AB.NameOfBooks(index);
            end
          else
            begin
              if index = 1 then
                result := cfolder.name
              else
                if (index > 1) and (index <= (cfolder.folders.count + 1)) then
                  result := cfolder.folders.item[index - 1].name
                else
                  result := '';
            end;
        end;
  end;
end;

function TAB.CountOfContacts(const name: WideString): Integer;
var
  Rot: IRunningObjectTable;
  Mon: IMoniker;
  TargetObject: IUnknown;
  AB: IAB;
begin
if CreateItemMoniker(nil, PWideChar(GuidToString(IAB)), Mon) <> S_OK then Exit;;
if not (GetRunningObjectTable(0, Rot) = S_Ok) then Exit;
if Rot.GetObject(Mon, TargetObject) = S_OK then
  begin
    if TargetObject.QueryInterface(IAB, AB) = S_OK then
      with AB do
        begin
          if Pointer(AB) <> Pointer(Self as IAB) then
            begin
              Result := AB.CountOfContacts(name);
            end
          else
            begin
              if name = cfolder.name then
                result := cfolder.items.count
              else
                try
                  result := cfolder.folders(name).items.count;
                except
                  result := 0;
                end;
            end;
        end;
  end;
end;

constructor TAB.Create;
begin
inherited Create;
FApp := nil;
FAddin := nil;
FRotEntry := -1;
end;

function TAB.FieldOfContacts(const book: WideString; index,
  field: Integer): WideString;
var
  adrbook: variant;
  Rot: IRunningObjectTable;
  Mon: IMoniker;
  TargetObject: IUnknown;
  AB: IAB;
begin
if CreateItemMoniker(nil, PWideChar(GuidToString(IAB)), Mon) <> S_OK then Exit;;
if not (GetRunningObjectTable(0, Rot) = S_Ok) then Exit;
if Rot.GetObject(Mon, TargetObject) = S_OK then
  begin
    if TargetObject.QueryInterface(IAB, AB) = S_OK then
      with AB do
        begin
          if Pointer(AB) <> Pointer(Self as IAB) then
            begin
              Result := AB.FieldOfContacts(book,index,field);
            end
          else
            begin
              if (book = cfolder.name) then
                begin
                  if (index <= cfolder.items.count) and (index > 0) then
                    begin
                      case field of
                        0 : result := cfolder.items.item[index].fullname;
                        1 : result := cfolder.items.item[index].email1address;
                        2 : result := cfolder.items.item[index].businessfaxnumber;
                      else
                        result := '';
                      end
                    end
                  else
                    result := '';
                end
              else
                begin
                  try
                    adrbook := cfolder.folders(book);
                    if (index <= adrbook.items.count) and (index > 0) then
                      begin
                        case field of
                          0 : result := cfolder.items.item[index].fullname;
                          1 : result := cfolder.items.item[index].email1address;
                          2 : result := cfolder.items.item[index].businessfaxnumber;
                        else
                          result := '';
                        end
                      end
                    else
                      result := '';
                  except
                    result := '';
                  end;
                end;
            end;
        end;
  end;
end;

initialization
  TABFactory.Create(ComServer, TAB, Class_AB, ciMultiInstance, tmApartment);
end.


PM MAIL   Вверх
cat512
Дата 14.10.2010, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Result в функциях поинициализируй начальными значениями, иначе на клиенте будешь получать "разрушительный сбой"
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: ActiveX/СОМ/CORBA"

Rrader
Girder

Запрещено:

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

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


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

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

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


 




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


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

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