Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как подключиться к СОМ-объекту, зная его Хэндл?  (Прочитано 18584 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Igel
Опытный

ru
Offline Offline
Пол: Мужской

« : 01-07-2005 09:22 » 

Ситуация такая, приложение знает Хэндл окна СОМ-сервера. Нужно получить доступ именно к этому объекту.
И вообще реально-ли такое?
Записан

Ёжики, это не только ценные шкурки...
Igel
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 18-03-2006 17:25 » 

Нашел способ!
Правда он ориентирован на то, что у самого СОм-сервера есть метод, возвращающий Хэндл.
1. С помощью Running Object Table (ROT), точнее с помощью интерфейса доступа к онной можно получить список запущенных.
Тут есть ньюанс, что СОМ серверы должны регистрироваться в этой таблице.
Тот сервер, с которым я работаю это может (AutoCAD).

2. Т.е. получаем список активных серверов, выделяем те, которые соответствуют нашему СОМ-интерфейсу и перебираем их, проверяя Хэндл.
Записан

Ёжики, это не только ценные шкурки...
zubr
Гость
« Ответ #2 : 19-03-2006 08:53 » 

Это интересно. Кодом можешь поделиться? Буду очень признателен.
Записан
Igel
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 19-03-2006 17:12 » 

Я код списал со статьи "Что такое Running Object Table" она по адресу:
http://www.osp.ru/pcworld/1998/08/174.htm
Там код для Сыча, а в Дельфе, если кому интересно так:
Код:
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, registry, StdCtrls, ExtCtrls, ole2, ComObj, ActiveX;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    ProgID: TLabel;
    Label3: TLabel;
    ProgName: TLabel;
    SrvList: TListBox;
    Panel1: TPanel;
    UpdateBtn: TButton;
    procedure FormCreate(Sender: TObject);
    procedure UpdateBtnClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure SrvListClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Reg:tregistry;
  pirot:IRunningObjectTable;
  penum:IEnumMoniker;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var res:integer;
begin
  res:=CoInitialize(nil);
  if res=s_ok then application.Terminate;
  reg:=tregistry.Create;

  GetRunningObjectTable(0, pirot);
  UpdateBtnClick(UpdateBtn);
end;

procedure TForm1.UpdateBtnClick(Sender: TObject);
var pmon:IMoniker;
    pibc:IBindCtx;
    start, len:integer;
    name:POLESTR;
begin
  //button click
  SrvList.Clear;
  ProgName.Caption:='';
  ProgID.Caption:='';
  pirot.EnumRunning(penum);
  penum.Reset;
  while penum.Next(1,pmon,nil)=s_ok do begin
    CreateBindCtx(0, pibc);
    pmon.GetDisplayName(pibc,pmon,name);
    start:=Pos('{', AnsiString(name));
    if start>0 then  begin
      len:= Pos('}', AnsiString(name))-start;
      SrvList.Items.Add(copy (AnsiString(name), start,len+1));
    end;
    CoTaskMemFree(name);
    //pibc._Release;
    //pmon._Release;
  end;
  //penum._Release;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  pirot._Release;
  CoUninitialize;
  //reg;
end;

procedure TForm1.SrvListClick(Sender: TObject);
var Clsid:AnsiString;
begin
//
  clsid:=SrvList.Items.Strings[SrvList.itemindex];
  reg.RootKey:=HKEY_CLASSES_ROOT;
  try
    if reg.OpenKeyReadOnly('\\CLSID\\' +clsid) then
      ProgName.Caption:=reg.ReadString('');
    reg.CloseKey;
    if reg.OpenKeyReadOnly('\\CLSID\\' +clsid+'\\ProgID') then
      ProgID.Caption:=reg.ReadString('');
    reg.CloseKey;
  finally


  end;
end;

end.

« Последнее редактирование: 19-12-2007 21:28 от Алексей1153++ » Записан

Ёжики, это не только ценные шкурки...
zubr
Гость
« Ответ #4 : 19-03-2006 20:21 » 

Igel, спасибо.+
Записан
Igel
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 20-03-2006 16:26 » 

Зубр, не за что... Сделать-то то что хотел так и не получилось. Код раздобыл, вроде все понял, а как дошло до реализации, так тупик.
Ситуация такая приведенный выше код выводит список СОМ-серверов, точнее нечто вроде процессов, не знаю как еще сказать. Если бы не фильтрация в коде по признаку наличия CLSID - выдавал бы все задачи в панели задач, точнее их названия.
Ну ладно, выдал он мне что у меня запущено 2 экземпляра нужного мне сервера. Встает вопрос как определить какой мне нужен? Критерий есть Хэндл окна. Метод такой у сервера есть - за чем дело встало? А дело встало за тем, что у меня есть только IMoniker объекта и ROT. Но у ROT-а есть метод GetObject, который по указанному IMoniker-у возвращает интерфейс.
Код:
var intf:IInterface;
     ac:IAcadApplication;//Мой искомый интерфейс
...
  while penum.Next(1,pmon,nil)=s_ok do begin
    CreateBindCtx(0, pibc);
    pmon.GetDisplayName(pibc,pmon,name);
    start:=Pos('{', AnsiString(name));
    if start>0 then  begin
//NEW Если у нас CLSID
       if pirot.GetObject(pmon,intf)=s_ok then begin//Получаем интерфейс Моникера
          if intf.QueryInterface(IID_AcadApplication, ac)=E_NoInterface{??не помню константу} then
            h:=-1;
          else//"Наш человек", в смысле интерфейс
            h:=ac.activedocument.hwnd;
         //Выводим хэндлы объектов наших интерфейсов
          ListBox1.items.add(inttostr(h));
       end;
//END NEW
      len:= Pos('}', AnsiString(name))-start;
      SrvList.Items.Add(copy (AnsiString(name), start,len+1));
    end;
    CoTaskMemFree(name);
   ...
После выполнения я вижу, что Хэндлы у всех одинаковые. И тут до меня доходит, что я ничерта не понимаю в интерфейсах и СОМ.
Интерфейс просто описание, внешняя связка, методы какого-то объекта. Получается у меня один интерфейс на несколько объектов, что верно. Но Моникеры-то разные должны быть, раз объекты разные. Но интерфейс у них один.
Сейчас будет глупый вопрос!
Связан интерфейс с конкретным объектом?
И вообще можно как-то связать интерфейс с объектом?
И вообще объясните мне в чем здесь дело?

П.С. Есть куча различной информации и статей о интерфейсах, СОМ, но этого я как-то не встречал.
« Последнее редактирование: 19-12-2007 21:29 от Алексей1153++ » Записан

Ёжики, это не только ценные шкурки...
x77
Команда клуба

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #6 : 06-04-2006 22:16 » 

насколько я понимаю, наоборот - несколько интерфейсов соответствуют одному объекту Улыбаюсь точнее, конкретной Instance данного СОМ-объекта.

не проще решать задачу от обратного? если известен COM-сервер (автокад), то у него есть гуид (уникальный в пределах вселеной и одинаковый для любого компа, на котором стоит автокад), ну так и обращаемся сразу к СОМ-объекту, зачем такой обходной путь?
Записан

Igel
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 07-04-2006 16:15 » new

насколько я понимаю, наоборот - несколько интерфейсов соответствуют одному объекту Улыбаюсь точнее, конкретной Instance данного СОМ-объекта.
В том-то и дело что нет. Если я запущу 2 одинаковых приложения - у меня 2 его экземпляра. Если это приложение - СОМ-сервер, который имеет интерфейс - описание методов и свойств, то у двух приложений один интерфейс.

не проще решать задачу от обратного? если известен COM-сервер (автокад), то у него есть гуид (уникальный в пределах вселеной и одинаковый для любого компа, на котором стоит автокад), ну так и обращаемся сразу к СОМ-объекту, зачем такой обходной путь?
Обисняю. Запущено 2 АвтоКАД-а. И к конкретному из них моя программа должна подключиться, т.е. использовать методы СОМ-сервера.
Задача1. Из Акад-а запущена программа, а если Акад-ов несколько, то она не может найти тот, который ее вызвал, что-бы вернуть результат.
Есть еще ряд задач.
Записан

Ёжики, это не только ценные шкурки...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines