2011-12-24 7 views
5

Oto kod, w którym próbuję skonfigurować interfejs IAdviseSink zaimplementowany w mojej klasie TForm1 w celu przechwycenia niektórych zdarzeń z nowo utworzonego dokumentu MSWord. Nie mam żadnych błędów podczas działania kodu, ale nie mogę przechwycić żadnego zdarzenia, podczas gdy zapisz dokument lub go zamknij. How to to setup IAdviseSink dla dokumentu MSWord poprawnie?Konfiguracja IAdviseSink do przechwytywania zdarzeń dokumentu MSWorda

 

    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

Przy tej konfiguracji, włącza OnClose pożary tutaj, gdy zamykam dokument, kiedy zapisuję pożegnanie dokumentu "OnRename", kiedy ponownie zapisuję nową nazwę " OnRename "uruchamia się. Co daje? –

+1

Przykład "OnClose" [tutaj] (http://stackoverflow.com/a/2886747/243614), ale nie testowałem innych zdarzeń. –

Odpowiedz

0

Edit:

Nieważne tę odpowiedź. Pozostawiając go do celów eductional.


Dlaczego obsada IAdviseSink(Self)?

Jeżeli ogłoszony interfejs w deklaracji klasy postaci to:

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

, nie należy tego robić.

Fakt, że używasz obsady (i twardej obsady, która po prostu mówi kompilatorowi, żeby się zamknął), może oznaczać, że tego nie zrobiłeś. A to może spowodować, że mechanizm wysyłki wykryje, że twoja forma nie implementuje IAdviseSink i dlatego nie ma nic, co można by nazwać metodą OnSave.


Wyjaśnienie dlaczego powyższe nie jest kwestia:

nie rozumieć Sertac za komentarz, ale wtedy byłoby skompilować kod nie "na początku. Chodziło mu o to, że bez IAdviseSink będącego częścią deklaracji klasy formularza, linia

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

będzie powodować [DCC Error] Unit1.pas (41): E2010 niezgodne typy: 'IAdviseSink' oraz 'TForm1'

Oczywiście nie jest to prosta, trudna obsada, taka jak TForm(SomePointer), która zasadniczo nakazuje kompilatorowi zamknięcie i traktowanie SomePointer jako TForm. Następnie rzutowany interfejs monituje kompilator, aby sprawdzić, czy instancja, która jest obsada, faktycznie obsługuje interfejs. Tego nie wiedziałem. Naucz się czegoś nowego każdego dnia.

+3

Ale kod nie skompilowałby się. –

+0

@Czas: Dlaczego nigdy nie? Kompiluje się dobrze na moim komputerze (D2010). –

+0

Nie miałem na myśli obsady. Jeśli formularz nie implementował IAdviseSink, wówczas 'Doradztwo (Self..' nie skompilowałoby się ani' Advise (IAdviseSink (Self), ..', daje * 'Niezgodne typy ..' * tutaj . –

0

Niezupełnie odpowiedź, ale ...

Czy istnieje szczególny powód, dla którego chcesz wyważać otwartych drzwi i zrobić cały Advise -thing siebie? Dlaczego po prostu nie używać klasy opakowującej TWordDocument z jednostki Word2000, która jest dostarczana w pakiecie z Delphi (wszystko, co musiałbyś zrobić w takim przypadku, to wywołanie ConnectTo() i przypisanie procedur obsługi zdarzeń)? Jednak obiekt Document nie ma zdarzenie OnSave (przynajmniej nie w wersji TLB z 2000, co jest ogólnie dobrym wspólnym mianownikiem, jeśli chcesz, aby aplikacja była kompatybilna z wieloma wersjami pakietu Office). Obiekt Application ma jednak BeforeDocumentSave -vent, chociaż ...

Powiązane problemy