Работаю с примером ...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);
Я подписывался на события документа следующим образом.
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
спасибо!
:%: и все равно не работает
в Вашем примере в параметре 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 выглядит так же как у Вас
в итоге получаю вот что.
скриншот в режиме отладки и скриншот ошибки
Вот еще сделал снимок экрана из отладчика со всякими вариантами переменной newDoc
Точно, забыл указать. В 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 во вложении.
УСЁ РАБОТАЕТ!! СПАСИБО!