2011-02-02 41 views
2

更新:如何將C#接口傳遞給外部COM對象以供其使用?

我發現ITfDocumentMgr的IID在註冊表中,但ITextStoreACP的IID不是。當我從ITextStoreACP接口定義刪除[的Guid(「28888 ......」),推送()方法沒出事,我懷疑,因爲我的類是不報有這樣的接口。然後我將它放回來,並使組件,類和接口NOT COM可見。同樣,我的AdviseSink方法沒有被調用。

對此有何想法,將不勝感激。


NEAR原貼:

我想文本服務框架融入我的C#應用​​程序,我的C#應用​​程序的客戶端TSF(而不是一個TSF服務)。我可以獲得TSF COM接口來創建文檔管理器。我創建了一個實現ITextStoreACP的文本存儲。

[ComVisible(true)] 
public class TextStore : ITextStoreACP 
{ 
    public uint AdviseSink(
     [MarshalAs(UnmanagedType.Struct)] ref IID Iid, 
     [MarshalAs(UnmanagedType.IUnknown)] Object pUnknown, 
     uint Mask 
     ) 
    { 
     ITextStoreAcpSink Sink = pUnknown as ITextStoreAcpSink; 
     return 0; 
    } 
.... 
} 

後,我創建一個使用我的ITextStoreACP上下文,然後我用DocumentMgr.Push()使用引用我的文本存儲上下文。反過來,TSF框架應該使用其接收器接口調用我的ITextStoreACP.AdviseSink()方法,以便在文本存儲器內容發生更改時通知框架。

public partial class Form1 : Form 
{ 
    static ITextStoreACP pStore = new TextStore(); 
    static Object pIunknown; 

    static ITfContext Context; 
    static ITfDocumentMgr DocMgr; 
    static IThreadMgr ThreadMgr; 


    protected override void OnLoad(EventArgs e)   
    { 
     base.OnLoad(e); 

     TfClientId Tid = new TfClientId(); 
     TfEditCookie Cookie = new TfEditCookie(); 
     uint hr; 


     // Get a new thread manager... 
     ThreadMgr = TsfInterfaces.CreateManager(); 
     // Activate the thread manager and get our cookie back... 
     hr = ThreadMgr.Activate(out Tid); 
     // Create a document manager for our use... 
     hr = ThreadMgr.CreateDocumentMgr(out DocMgr); 

     // Get the IUnknown interface to pass to CreateContext()... 
     pIunknown = pStore as Object; 

     // Create a context to work in, designating our text store for our use... 
     hr = DocMgr.CreateContext(Tid, 0, pIunknown, out Context, out Cookie); 

     try 
     { 
      // Select our context to work in now. With a text store as part of 
      // the context, the Text services framework should call into our 
      // text store object with its sink interface. 
      // 
      //  But it crashes instead. 
      // 
      hr = DocMgr.Push(Context); 
     } 
     catch 
     { 
     } 

    } 

} 

我在這裏使用ITfDocumentMgr接口定義:

[Guid("aa80e7f4-2021-11d2-93e0-0060b067b86e")] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface ITfDocumentMgr 
{ 
    uint CreateContext(
     TfClientId Tid, 
     uint Flags, 
     [MarshalAs(UnmanagedType.IUnknown)] Object pUnkUnique, 
     [MarshalAs(UnmanagedType.Interface)] out ITfContext pContext, 
     out TfEditCookie pCookie 
     ); 

    uint Push([MarshalAs(UnmanagedType.Interface)] ITfContext pContext); 

    uint Pop(uint Flags); 

    uint GetTop(out ITfContext Context); 

    uint GetBase(out ITfContext Context); 

    uint EnumContexts(out IEnumITfContexts EnumContexts); 
} 

然而,可替換的接打電話給我AdviseSink()方法,應用程序崩潰,並從通話中關閉,以推送() 。如果我當我打電話的createContext不及格的文本存儲的接口(這是合法的),而是一空,然後按()返回罰款,因爲沒有ITextStoreACP.AdviseSink()調用。

我設置項目屬性「使得安裝COM可見」爲true。 我將項目屬性「Register for COM interop」設置爲true,但我不認爲這是必要的。

還有什麼我需要做的,使基於ITextStoreACP界面我的C#類對象可以訪問到外部COM對象的方法才能正常使用?

I類基礎我TextStore對象從下一個示出的接口。所有方法都在文本存儲中實現,至少缺省爲「Method not implemented」異常,以便我可以運行代碼。

[Guid("28888fe3-c2a0-483a-a3ea-8cb1ce51ff3d")] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface ITextStoreACP 
{ 
    uint AdviseSink(
     [MarshalAs(UnmanagedType.Struct)] ref IID Iid, 
     [MarshalAs(UnmanagedType.IUnknown)] object pUnknown, 
     uint Mask 
     ); 

    uint UnadviseSink([MarshalAs(UnmanagedType.IUnknown)] object pUnknown); 

    uint RequestLock(uint LockFlags, out uint hrSession); 

    uint GetStatus([MarshalAs(UnmanagedType.Struct)] out TS_STATUS TSS); 


    uint QueryInsert(long TestStart, long TestEnd, ulong Count, out long ResultStart, out long ResultEnd); 

    uint GetSelection(
     ulong Index, 
     ulong Count, 
     [MarshalAs(UnmanagedType.Struct)] out TS_SELECTION_ACP Selection, 
     out ulong Fetched 
     ); 

    uint SetSelection( 
     ulong Count, 
     [MarshalAs(UnmanagedType.Struct)] ref TS_SELECTION_ACP Selection 
     ); 

    uint GetText(
     long Start, 
     long End, 
     out string Plain, 
     ulong PlainReq, 
     out ulong PlainRet, 
     [MarshalAs(UnmanagedType.Struct)] out TS_RUNINFO RunInfo, 
     ulong RunInfoReq, 
     out ulong RunInfoRet, 
     out long Next 
     ); 

    uint SetText(
     uint Flags, 
     long Start, 
     long End, 
     string Text, // What kind of marshaling should I specify here for "in WCHAR *" types? 
     ulong Count, 
     [MarshalAs(UnmanagedType.Struct)] out TS_TEXTCHANCE Change 
     ); 

    uint GetFormattedText(
     long Start, 
     long End, 
     [MarshalAs(UnmanagedType.Interface)] out IDataObject DataObject 
     ); 

    uint GetEmbedded(
     long Pos, 
     [MarshalAs(UnmanagedType.Struct)] ref IID GUID_Service, 
     [MarshalAs(UnmanagedType.Struct)] ref IID IID_Service, 
     [MarshalAs(UnmanagedType.IUnknown)] out object pUnk 
     ); 

    uint QueryInsertEmbedded(
     [MarshalAs(UnmanagedType.Struct)] ref IID GUID_Service, 
     [MarshalAs(UnmanagedType.Struct)] ref FORMATETC FormatEtc, 
     [MarshalAs(UnmanagedType.Bool)] out bool IsInsertable 
     ); 

    uint InsertEmbedded(
     uint Flags, 
     long Start, 
     long End, 
     [MarshalAs(UnmanagedType.Interface)] IDataObject DataObject, 
     [MarshalAs(UnmanagedType.Struct)] out TS_TEXTCHANCE Change 
     ); 

    uint InsertTextAtSelection(
     uint Flags, 
     string Text, 
     ulong Count, 
     out long Start, 
     out long End, 
     [MarshalAs(UnmanagedType.Struct)] out TS_TEXTCHANCE Change 
     ); 

    uint InsertEmbeddedAtSelection(
     uint Flags, 
     [MarshalAs(UnmanagedType.Interface)] IDataObject DataObject, 
     out long Start, 
     out long End, 
     [MarshalAs(UnmanagedType.Struct)] out TS_TEXTCHANCE Change 
     ); 

    uint RequestSupportedAttrs(
     uint Flags, 
     ulong FilterAttrs, 
     [MarshalAs(UnmanagedType.Struct)] ref TS_ATTRID AttrId 
     ); 

    uint RequestAttrsAtPosition(
     long Pos, 
     ulong FilterAttrs, 
     [MarshalAs(UnmanagedType.Struct)] ref TS_ATTRID AttrId, 
     uint Flags 
     ); 

    uint RequestAttrsTransitioningAtPosition(
     long Pos, 
     ulong FilterAttrs, 
     [MarshalAs(UnmanagedType.Struct)] ref TS_ATTRID AttrId, 
     uint Flags 
     ); 

    uint FindNextAttrTransition(
     long Start, 
     long Halt, 
     ulong FilterAttrs, 
     [MarshalAs(UnmanagedType.Struct)] ref TS_ATTRID AttrId, 
     uint Flags, 
     out long Next, 
     out bool Found, 
     out long FoundOffset 
     ); 

    uint RetrieveRequestedAttrs(
     ulong Count, 
     [MarshalAs(UnmanagedType.Struct)] ref TS_ATTRVAL Vals, 
     out ulong Fetched 
     ); 

    uint GetEndACP(out long Acp); 

    uint GetActiveView(out TsViewCookie Cookie); 

    uint GetACPFromPoint(
     TsViewCookie Cookie, 
     [MarshalAs(UnmanagedType.Struct)] ref POINT Point, 
     uint Flags, 
     out long Acp 
     ); 

    uint GetTextExt(
     TsViewCookie Cookie, 
     long Start, 
     long End, 
     [MarshalAs(UnmanagedType.Struct)] out RECT Rect, 
     out bool IsClipped 
     ); 

    uint GetScreenExt(
     TsViewCookie Cookie, 
     [MarshalAs(UnmanagedType.Struct)] out RECT Rect 
     ); 

    uint GetWnd(
     TsViewCookie Cookie, 
     [MarshalAs(UnmanagedType.I4)] IntPtr hWnd 
     ); 
} 
+0

沒有,如果你只需要一個接口,這是你需要做什麼! – 2011-02-02 22:01:22

回答

0

事實證明,我需要以下特徵:

[ComVisible(true)] 
[Guid("28888fe3-c2a0-483a-a3ea-8cb1ce51ff3d")] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface ITextStoreACP 
{ 
    uint AdviseSink(
     ref Guid Iid, 
     [MarshalAs(UnmanagedType.IUnknown)] object pUnknown, 
     uint Mask 
     ); 
    ....... 
} 


public class TextStore : ITextStoreACP 
{ 
    #region ITextStoreACP Members 

    public uint AdviseSink(ref Guid Iid, object pUnknown, uint Mask) 
    { 
     throw new NotImplementedException(); 
    } 
    ..... 
} 

但現在我發現讀訪問衝突,看來,堆棧指針的路上突然出現0回來,這似乎表明通話本身還不完全正確。

然後我發現我只需添加[PreserveSig]將AdviseSink方法聲明,一切都很好....

...或更改UINT(HRESULT)爲void(無返回碼)。見鏈接在這裏:

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.preservesigattribute%28v=VS.90%29.aspx http://social.msdn.microsoft.com/Forums/en-US/clr/thread/a8c2d872-a42e-441a-907b-62d4a05f75ea

也沒必要聘請任何人,只需要一點點方向。謝謝大家!你太棒了!

相關問題