2009-11-13 23 views
1

或VB6兼容集合對象創建VB6集合對象。如何使用ATL

我們通過一系列API爲我們的.net產品提供掛鉤。

我們需要繼續支持從VB6調用API的客戶,所以我們需要繼續支持VB6集合對象(在.net中使用VBA.Collection是很簡單的)。

問題是支持一些使用VBScript調用我們的API的網站。 VBScript沒有集合對象的概念,所以要創建一個集合對象傳遞給我們的API,我們構建了一個VB6 ActiveX DLL,它提供了一個「CreateCollection」方法。此方法只是創建並傳回一個新的集合對象。問題解決了。

經過多年的修剪,移植和重新構建,這個DLL是我們唯一的VB6代碼。因此,我們仍然需要在我們的Dev &構建機器上安裝Visual Studio 6。

我不滿意我們對這個DLL的依賴有幾個原因(我個人不喜歡VB6不是其中之一)。最重要的是微軟不再支持Visual Studio 6.

我的問題是,我如何獲得ATL創建一個集合對象實現與VB6集合對象相同的接口。我已經很好地掌握了C++,但只是對ATL的一種輕鬆掌握 - 我可以創建簡單的對象並實現簡單的方法,但這超出了我的想象。

+0

這聽起來像此VB6 DLL更改很少。你真的需要經常創建它嗎?我的想法是不再支持** VB6 IDE **,但支持** VB6運行時**。如果你不需要構建這麼多的DLL,是不是支持IDE的一個大問題? – MarkJ

+0

我知道你的意思,但我們有法定義務能夠建立我們所有的代碼。我們不能擁有我們無法構建的非第三方組件。 –

+0

VB6中的「強類型」集合仍然通過IEnumVARIANT枚舉。投射是隱式完成的(並可能失敗)。 – wqw

回答

6

收藏或多或少根據慣例。他們實施IDispatch和揭露一些標準的方法和屬性:

  • Add() - 可選
  • Remove() - 可選
  • Item()
  • Count - 只讀
  • _NewEnum - 隱藏只讀,返回指針枚舉實現IEnumVariant

_NewEnum屬性是允許的Visual Basic For Each對象。

在IDL您使用dual接口:

  • DISPID_VALUEItem()
  • [propget, id(DISPID_NEWENUM), restricted] HRESULT _NewEnum([out, retval] IUnknown** pVal)

這裏有一些MSDN項:Design Considerations for ActiveX Objects
這裏是一些ATL特定方便: ATL Collections and Enumerators

2

讓靶此的VBScript代碼段

Dim vElem 
For Each vElem In MyObject 
    ... 
Next 

特別MyObject來執行。至少必須在DISPID_NEWENUM的默認調度接口(其dual/dispinterface來討論DISPID)上實現一個方法/ propget。無論你想要什麼,你都可以命名它,沒關係。大多數集合使用NewEnum,並將其標記爲隱藏在IDL中。 VB6使用下劃線前綴來標記隱藏的方法,所以你可能會看到_NewEnum作爲推薦,但這是ATL所做的一種貨物崇拜。

不需要需要任何計數,項目,添加,刪除,清除或任何其他方法(在默認界面上)。您可以提供這些作爲一種便利(特別是項目訪問者,可能計數),但您不必,以使上面的示例代碼工作。

接下來,retval 設置爲一個單獨的對象(所謂的枚舉器),它使用指向MyObject的(專用)指針實現IEnumVARIANT接口。在IDL中,你可以聲明retval爲IUnknown,在這裏沒有錯。最有趣的是,只有才能實現IEnumVARIANT上的Next方法,如果你願意或者可以選擇實現它們,你可以返回E_NOTIMPLEMENTED,儘管這些永遠不會被For Each調用。什麼使得實現更容易是Next的celt參數(請求的項目數)是總是 1,所以For Each請求項總是一個接一個。

你可以在ATL中使用的是CComEnumOnSTL等,以在STL容器上創建「代理」枚舉器,或者基於數組的枚舉器ATL提供(並排除STL)。

+0

對於For Each,您不需要計數等,但可能會破壞利用它們的其他代碼。另外MSDN說它必須命名爲_NewEnum - 雖然這可能不是必需的VB6,它可能會打破其他代碼... http://msdn.microsoft.com/en-us/library/ms221672.aspx –

+0

我見過CComEnumOnSTL對象和ATL集合對象。這是「被選擇寵壞」的問題,我不知道該選擇哪一個。任何建議用於在ATL中構建一個集合對象,我可以將它傳遞給期望VB6集合的VB6函數? –

+0

@gf:活動目錄對象是支持枚舉而不暴露Item/Count的coclasses示例。我不確定他們在進入最後一個元素之前是否知道計數。 – wqw

0

對於如何落實,將在腳本編程語言自然中使用的COM集合一個很好的例子,看看my website

它提供瞭如何做一個全面的例子...