2011-12-24 15 views
5

Đây là mã mà tôi cố gắng thiết lập giao diện IAdviseSink được triển khai trong lớp TForm1 để bắt một số sự kiện của tài liệu MSWord mới được tạo. Tôi không có bất kỳ lỗi nào trong khi mã chạy, nhưng tôi không thể bắt bất kỳ sự kiện nào, trong khi lưu tài liệu hoặc đóng tài liệu. Làm cách nào để thiết lập IAdviseSink cho tài liệu MSWord chính xác?Thiết lập IAdviseSink để bắt các sự kiện tài liệu 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

Với thiết lập đó, OnClose kích hoạt ở đây tốt khi tôi đóng tài liệu, khi tôi lưu tài liệu 'OnRename' kích hoạt, khi tôi lưu lại với tên mới ' OnRename 'cháy. Đưa cái gì? –

+1

Ví dụ 'OnClose' [ở đây] (http://stackoverflow.com/a/2886747/243614), nhưng tôi chưa thử nghiệm các sự kiện khác sau đó .. –

Trả lời

0

Edit:

Đừng bận tâm câu trả lời này. Để nó vào cho mục đích giáo dục.


Tại sao lại chọn IAdviseSink(Self)?

Nếu bạn tuyên bố giao diện trong khai báo lớp của Form:

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

, bạn không cần phải.

Thực tế là bạn sử dụng dàn diễn viên (và một diễn viên cứng mà chỉ yêu cầu trình biên dịch tắt), có thể chỉ ra rằng bạn đã không. Và điều đó cũng có thể khiến cơ chế gửi đi tìm thấy rằng biểu mẫu của bạn không triển khai IAdviseSink và do đó không có gì để gọi phương thức OnSave.


Giải thích về lý do tại sao trên không phải là vấn đề:

Tôi không hiểu Sertac của bình luận 'Nhưng sau đó mã sẽ không biên dịch' lần đầu tiên. Ông có nghĩa rằng nếu không có IAdviseSink là một phần của khai báo lớp của hình thức, dòng

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

sẽ gây ra một [DCC Lỗi] Unit1.pas (41): E2010 loại không tương thích: 'IAdviseSink' và 'TForm1'

Các IAdviseSink(Self) rõ ràng không phải là một diễn viên cứng đơn giản như TForm(SomePointer) là, mà về cơ bản nói với trình biên dịch để đóng cửa và điều trị SomePointer như là một TForm. Một giao diện đúc sau đó, nhắc trình biên dịch để kiểm tra xem dụ dụ đang được đúc thực sự hỗ trợ giao diện. Không biết điều đó. Học điều mới mỗi ngày.

+3

Nhưng sau đó mã sẽ không biên dịch .. –

+0

@Sertac: Tại sao lại không? Nó biên dịch tốt trên máy tính của tôi (D2010). –

+0

Tôi không có ý là diễn viên. Nếu biểu mẫu chưa được triển khai IAdviseSink, thì 'Lời khuyên (Self..' sẽ không biên dịch. Không phải' Lời khuyên (IAdviseSink (Tự), ..', cho * 'Các kiểu không tương thích ..' * tại đây. –

0

Không chính xác một câu trả lời, nhưng ...

Có một lý do cụ thể tại sao bạn muốn phát minh lại bánh xe và làm toàn bộ Advise -thing mình? Tại sao không chỉ sử dụng lớp bao bọc TWordDocument từ Word2000 -unit đi kèm với Delphi (tất cả những gì bạn phải làm trong trường hợp đó là gọi ConnectTo() và chỉ định trình xử lý sự kiện của bạn)? Tuy nhiên, đối tượng Document không có sự kiện OnSave (ít nhất là không có trong phiên bản 2000 của TLB, thường là mẫu số chung tốt nếu bạn muốn ứng dụng của mình tương thích với nhiều phiên bản Office). Đối tượng ApplicationBeforeDocumentSave -event, mặc dù ...

Các vấn đề liên quan