Как управлять Объектом имея его Dispath

Автор snegok74, 24.08.12, 14:34:37

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

snegok74

Работаю с примером ...DELPHIAUTO\EventsAuto
в файле BaseEvents.pas есть функция которая срабатывает когда создан новый документ
function ApplicationEvent.OnCreateDocument( newDoc : PIDISPATCH; docType : integer ) : boolean;
newDoc как я понимаю указатель на интерфейс только что созданного документа (уже созданного при вызове этой ф-ии)
и вот пытаюсь подписать этот документ на события, а для этого мне надо вызвать функцию DocumentEvent.Create и передать ей Reference  этого документа что никак не получается (((
constructor DocumentEvent.Create(  refDoc : Reference );
begin
  pObject := IDispatch( iKompasObject.ksGetDocumentByReference(refDoc) );
  inherited Create( Addr( pObject), DIID_ksDocumentFileNotify, refDoc, 0 );
end;


все способы какими пытался получить Reference  не опишу, но последний не работал и был такой..

// newDoc : PIDISPATCH;
DocumentEvent.Create(ksDocument2D(newDoc^).Reference);

z-arthur

Я подписывался на события документа следующим образом.


function ApplicationEvent.OnCreateDocument(newDoc: IDispatch; docType: integer): boolean;
var
  docRef: Reference;
begin
  Result := True;
  docRef := GetDocumentReference(newDoc, docType);
  if docRef <> 0 then
  begin
    NewDocumentEvent(docRef);
  end;
end;


Описание функции GetDocumentReference

function GetDocumentReference(iDoc: IDispatch; docType: Integer): Reference;
begin
  Result := 0;
  if iDoc <> nil then
    case docType of
      lt_DocSheetStandart,  // чертеж стандартный
      lt_DocSheetUser    :  // чертеж нестандартный
        Result := ksDocument2D(iDoc).Reference;
      lt_DocSpc          ,  // спецификация
      lt_DocSpcUser      :  // спецификация нестандартный формат
        Result := ksSpcDocument(iDoc).Reference;
      lt_DocPart3D        ,  // 3d-документ модель
      lt_DocAssemble3D    :  // 3d-документ сборка
        Result := ksDocument3D(iDoc).Reference;
      lt_DocTxtStandart   ,  // текстовый документ стандартный
      lt_DocTxtUser       :  // текстовый документ нестандартный
        Result := ksDocumentTxt(iDoc).Reference;
    end;
end;


Функция NewDocumentEvent описана в файле BaseEvents.pas


snegok74

 :%: и все равно не работает
в Вашем примере в параметре newDoc передается IDispatch, а в моем PIDispatch, а это указатель на интерфейс

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

function ApplicationEvent.OnCreateDocument( newDoc : PIDispatch; docType : integer ) : boolean;
var  docRef: Reference;
begin
  Result := True;
  docRef := GetDocumentReference(newDoc^, docType);
  if docRef <> 0 then
  begin
    NewDocumentEvent(docRef);
  end;
end;

GetDocumentReference выглядит так же как у Вас

в итоге получаю вот что.
скриншот в режиме отладки и скриншот ошибки



snegok74

Вот еще сделал снимок экрана из отладчика со всякими вариантами переменной newDoc

z-arthur

Точно, забыл указать. В sd есть запрос 728531 (если у вас есть доступ).

Нужно заменить PIDispatch на IDispatch. Это ошибка в примерах. Вот ответ с sd:

ЦитироватьОбработчик на создание документа CreateDocument присылает IDispatch, а не PIDISPATCH, т.е., если вернуться к предыдущему письму в обработчике
function BOMApplicationEvent.OnCreateDocument(newDoc: PIDISPATCH; docType: integer): boolean;
нужно испрвить PIDISPATCH на IDispatch и передавать newDoc без ^
docRef := GetDocumentReference(newDoc, docType);

У нас в примерах, похоже, ошибка.
Мы ведь по природе С++ - ники. И интерфейсы IDispatch приходят как указатели. В Delphi PIDISPATCH из С++ внутри преобразуется в IDispatch. Получается путаница.
А в GetDocumentReference Вы не попадаете, потому что пытаетесь разадресовать не указатель.

ЦитироватьСпасибо за ответ.

Еще один вопрос.
Если в обработчике
function BOMApplicationEvent.OnCreateDocument(newDoc: PIDISPATCH; docType: integer): boolean;
поменять PIDISPATCH на IDispatch, то также необходимо поменять поведение в обработчике
function ApplicationEvent.OnEvent( commandID : Integer; var Params : tagDISPPARAMS; var eventRes : boolean ): boolean.

Этот обработчик объявлен в файле BaseEvents.pas. В нем обработчику OnCreateDocument передается Params.rgvarg^[0].dispVal в качестве указателя на документ. dispVal по сути является указателем на IDispatch.

Какой параметр нужно будет использовать если поменять PIDISPATCH на IDispatch в обработчиках?


Работает в следующем виде:

function BOMApplicationEvent.OnCreateDocument(newDoc: IDispatch; docType:
integer): boolean;

function BOMApplicationEvent.OnEvent( commandID : Integer; var Params :
tagDISPPARAMS; var eventRes : boolean ): boolean.

case commandID of

koCreateDocument: // Документ создан
eventRes := OnCreateDocument(IDispatch(Params.rgvarg^[1].dispVal),
Params.rgvarg^[0].intVal);

Обратите внимание - первым приходит параметр с индексом 1 (Params.rgvarg^[1].) - это IDispatch,
затем с индексом 0 - это тип документа.
В Delphi параметры нужно разворачивать в обратном порядке.

function BOMApplicationEvent.OnCreateDocument(newDoc: IDispatch; docType:
integer): boolean;
begin
Result := true;
GetDocumentReference(newdoc, doctype);
end;

Измененный файл BaseEvents во вложении.
+ Благодарностей: 1

snegok74