2011-12-24 14 views
5

Aquí está el código donde intento configurar la interfaz IAdviseSink implementada en mi clase TForm1 para capturar algunos eventos del documento MSWord recién creado. No tengo ningún error mientras se ejecuta el código, pero no puedo ver ningún evento, al guardar el documento o cerrarlo. ¿Cómo configurar IAdviseSink para el documento MSWord correctamente?Configuración de IAdviseSink para capturar eventos de documentos de MSWord

 

    var 
     Form1 : TForm1; 
     doc_ole_obj : IOleObject; 
     word : IDispatch; 
     Connection: LongInt; 

    implementation 

    //------------ Setup IAdviseSink 
    procedure TForm1.Setup; 
    begin 
    word := CreateOleObject('Word.Application'); 
    OleVariant(word).Visible := True; 

    IUnknown(OleVariant(word).Documents.Open('file.doc')).QueryInterface(IOleObject,doc_ole_obj); 
    doc_ole_obj.Advise(IAdviseSink(Self), Connection); 
    end; 

    //------------- catch Sink events 
    procedure TForm1.OnSave; 
    begin 
     Caption := 'saved at ' + TimeToStr(Now); 
    end; 
 
+0

Con esa configuración, OnClose se activa aquí cuando cierro el documento, cuando guardo los fuegos 'OnRename' del documento, cuando guardo con un nuevo nombre de nuevo ' OnRename 'dispara. ¿Lo que da? –

+1

'Ejemplo de OnClose' [aquí] (http://stackoverflow.com/a/2886747/243614), pero no he probado otros eventos, entonces ... –

Respuesta

0

Editar:

No importa que esta respuesta. Dejándolo para propósitos educativos.


Por qué el elenco IAdviseSink(Self)?

Si usted declaró en la interfaz de declaración de la clase del formulario:

TForm1 = class(TForm, IAdviseSink) 
    ... 
end; 

, no debería tener que hacerlo.

El hecho de que use el molde (y un molde duro que simplemente le dice al compilador que se calle), puede indicar que no lo hizo. Y eso bien puede hacer que el mecanismo de envío encuentre que su formulario no implementa IAdviseSink y, por lo tanto, no tiene nada para llamar al método OnSave.


Explicación de por qué lo anterior no es la cuestión:

Yo no entendí el comentario de Sertac 'Pero entonces el código no se compilará' al principio. Se refería a que, sin formar parte de IAdviseSink declaración de la clase de la forma, la línea

doc_ole_obj.Advise(IAdviseSink(Self), Connection); 

causaría un [DCC] Unit1.pas de error (41): E2010 tipos incompatibles: 'IAdviseSink' y 'TForm1'

El IAdviseSink(Self) obviamente no es un simple molde duro como TForm(SomePointer), que básicamente le dice al compilador que se calle y trate SomePointer como un TForm. Entonces, una conversión de interfaz solicita al compilador que compruebe si la instancia que se está emitiendo realmente admite la interfaz. No lo sabía Aprenda algo nuevo cada día.

+3

Pero entonces el código no compilaría ... –

+0

@Sertac: ¿Por qué no? Compila bien en mi máquina (D2010). –

+0

No me refería al elenco. Si el formulario no ha estado implementando IAdviseSink, entonces 'Advise (Self..' no compilará. Ni 'Advise (IAdviseSink (Self), ..', da *' Tipos incompatibles .. '* aquí. –

0

No es exactamente una respuesta, pero ...

¿Hay alguna razón particular por la que quiere reinventar la rueda y hacer todo el Advise -cosa ti mismo? ¿Por qué no usar la clase de contenedor TWordDocument de la unidad Word2000 que viene incluida con Delphi (todo lo que tendrías que hacer en ese caso sería llamar al ConnectTo() y asignar tus controladores de eventos)? Sin embargo, el objeto Document no tiene un evento OnSave (al menos no en la versión 2000 del TLB, que generalmente es un buen denominador común si desea que su aplicación sea compatible con varias versiones de Office). El objeto Application tiene un BeforeDocumentSave -evento, aunque ...

Cuestiones relacionadas