Inserts a new item of ActiveX type, and returns a handle to the newly created
item.
Type | Description | |||
Parent as HITEM | A long expression that indicates the handle of the parent item where the ActiveX will be inserted. If the argument is missing then the InsertControlItem property inserts the ActiveX control as a root item. If the Parent property is referring a locked item ( ItemLocked property ), the InsertControlItem property doesn't insert a new child ActiveX, instead insert the ActiveX control to the locked item that's specified by the Parent property. | |||
ControlID as String | A string expression that can be formatted as follows: a prog ID, a CLSID, a URL, a reference to an Active document , a fragment of HTML. | |||
License as Variant | A string expression that indicates the runtime license key for the component being inserted, if required. Only, the vendor of the component you are going to use is able to give you such of runtime license, so please contact the control's vendor for such of key. Your development license key is not compatible with the runtime license key, so it can't be used here. |
Return | Description | |||
HITEM | A long expression that indicates the item's handle that indicates the newly created item. |
The control supports ActiveX hosting, so
you can insert any ActiveX component as a child item of the control. If you are using the /NET assembly you can use the InsertObjectItem property to insert a /NET control as a child item of the control. The InsertControlItem property creates the specified ActiveX control and hosts to a new child item of the control, while the InsertObjectItem property hosts the already created object to a new child item of the control. An inner control sends notifications/events to parent control through the ItemOleEvent event.The ControlID must be formatted in one of the following ways:
In case the control you want to insert fails, you can add the "A2X:" prefix to the ControlID such as:
The InsertControlItem property creates an ActiveX control that's hosted by the exGrid control. The look and feel of the inner ActiveX control depends on the identifier you are using, and the version of the library that implements the ActiveX control, so you need to consult the documentation of the inner ActiveX control you are inserting inside the exGrid control.
Use the ItemHeight property to specify the height of the item when it contains an ActiveX control. Use the ItemWidth property to specify the width of the ActiveX control, or the position in the item where the ActiveX is displayed. Once that an item of ActiveX type has been added you can get the OLE control created using the ItemObject property. To check if an item contains an ActiveX control you can use ItemControlID property. Use the ItemAllowSizing property to let user resizes the item at runtime, and so the object being hosted. To change the height of an ActiveX item you have to use ItemHeight property. When the control contains at least an item of ActiveX type, it is recommended to set ScrollBySingleLine property of control to true. Events from contained components are fired through to your program using the exact same model used in VB6 for components added at run time ( See ItemOleEvent event, OleEvent and OleEventParam ). For instance, when an ActiveX control fires an event, the control forwards that event to your container using ItemOleEvent event of the exTree control. Use the BeginUpdate and EndUpdate methods to update the control's content when adding ActiveX controls on the fly. Use the ItemControlID property to retrieve the control's identifier.
You can use one of the following methods to find out information about the inner ActiveX control:
Private Sub Form_Load() With Grid1 .BeginUpdate .Columns.Add "Column 1" .Items.InsertControlItem , "Exontrol.ChartView" .EndUpdate With .Items PropertiesList1.Select .ItemObject(.ItemByIndex(0)) End With End With End Sub
This way the exPropertiesList control browses the object that's hosted by the first item in the exGrid control, so you will be able to see the properties that you will be able to call them for the inner ActiveX control. Please notice that some objects/identifier can't be browsed by the exPropertiesList control so, the Select method may fail. Also, if the exPropertiesList browser is empty when running the form, means that the control has not browse able properties, instead it may have methods or properties with parameters, that can't be browsed by the exPropertiesList control.
Private Sub Form_Load() With Grid1 .BeginUpdate .Columns.Add "Column 1" .Items.InsertControlItem , "MSHTML:<HTML><BODY>This is a line of text</BODY></HTML>" .EndUpdate With .Items Debug.Print PropertiesList1.Interfaces(.ItemObject(.ItemByIndex(0))) End With End With End Sub
Once that you run the sample, the output window ( Immediate window ) lists the interfaces that inner object implements, and so in our case we will notice a list like follows:
IUnknown IPersistFile IPersist IViewObject IDataObject IOleObject IOleInPlaceObject IOleWindow IOleInPlaceActiveObject IParseDisplayName IOleContainer IOleItemContainer IOleCache IViewObject2 IOleCache2 IDispatch IShellPropSheetExt IOleInPlaceObjectWindowless ICustomDoc IHTMLDocument3 IFPMarkupServices DispHTMLAnchorElement DispHTMLAreaElement DispHTMLBaseFontElement DispHTMLBlockElement DispHTMLBody DispHTMLTableCaption DispIHTMLOptionButtonElement DispHTMLCommentElement DispHTMLDDElement DispHTMLDivElement DispHTMLDTElement DispHTMLDivPosition DispHTMLFormElement DispHTMLStyleElement DispHTMLFontElement DispHTMLFrameElement DispHTMLFrameSetSite DispHTMLHeaderElement DispHTMLTitleElement DispHTMLMetaElement DispHTMLBaseElement DispHTMLIsIndexElement DispHTMLNextIdElement DispHTMLIFrame DispHTMLImg DispIHTMLInputImage DispIHTMLInputButtonElement DispHTMLButtonElement DispIHTMLInputTextElement DispHTMLTextAreaElement DispHTMLLabelElement DispHTMLLIElement DispHTMLLinkElement DispHTMLListElement DispHTMLMapElement DispHTMLMarqueeElement DispHTMLNoShowElement DispHTMLObjectElement DispHTMLOListElement DispHTMLOptionElement DispHTMLParaElement DispHTMLPhraseElement DispHTMLEmbed DispHTMLScriptElement DispHTMLSelectElement DispHTMLTable DispHTMLTableCol DispHTMLTableSection DispHTMLTableRow DispHTMLTableCell DispHTMLTextElement DispHTMLUListElement DispHTMLUnknownElement DispHTMLBRElement DispHTMLDListElement DispHTMLBGsound DispHTMLHRElement DispIHTMLTextContainer DispIHTMLControlElement DispHTMLFrameBase DispIHTMLInputFileElement DispHTMLSpanFlow DispHTMLFieldSetElement DispHTMLLegendElement DispHTMLSpanElement DispHTMLRichtextElement DispHTMLCurrentStyle DispCEventObj DispHTMLStyle DispHTMLRuleStyle DispHTMLWindow2 DispHTMLWindowProxy DispHTMLDocument DispHTMLHtmlElement DispHTMLHeadElement DispHTMLGenericElement DispHTMLDOMAttribute DispHTMLDOMTextNode DispHTMLAreasCollection DispHTMLElementCollection DispHTMLAttributeCollection IFPMarkupContainer DispHTCDefaultDispatch DispHTCEventBehavior DispDOMChildrenCollection DispHTMLAppBehavior DispHTMLInputElement DispHTCDescBehavior DispHTCPropertyBehavior DispHTMLDocumentFragment DispHTCAttachBehavior DispHTCMethodBehavior DispHTMLPopup DispHTMLRenderStyle DispHTMLDefaults DispHTMLStyleSheet DispHTMLDOMImplementation DispHTMLParamElement DispHTMLScreen IHTMLDocument4 IHTMLDocument5 IHTMLDocument2 IPerPropertyBrowsing IViewObjectEx IInternetHostSecurityManager IPointerInactive IHTMLDocument IServiceProvider ITargetContainer IHlinkTarget IPersistMoniker DataSource IPersistStreamInit IPersistHistory IMonikerProp IProvideClassInfo2 IDispatchEx IProvideMultipleClassInfo IProvideClassInfo IConnectionPointContainer IOleControl ISpecifyPropertyPages IOleDocument IOleDocumentView IOleCommandTarget IObjectIdentity IObjectSafety ISupportErrorInfo
The list of interfaces you got is quite long, but gives you useful information to start looking for the proper documentation that we need. In this list we need to locate the interfaces that are derived from the IDispatch interface, because in any COM oriented language you can call a property of an object only if it is derived from IDispatch interface. The question is how can we know which interface derives from IDispatch interface. In case you locate a IDispatchEx interface in your list, it means that it is possible to find multiple interfaces that derives from the IDispatch, else if only a IDispatch is located, one single interface can derive from the IDispatch. The list of interfaces differs from the objects to objects. For instance, if you are running the same code but using the "Exontrol.grid" identifier the list of interfaces looks like follows:
IUnknown IPersistStorage IPersist IViewObject IDataObject IOleObject IOleInPlaceObject IOleWindow IOleInPlaceActiveObject IViewObject2 IDispatch IOleInPlaceObjectWindowless IViewObjectEx IPersistStreamInit IGrid IProvideClassInfo2 IProvideClassInfo IConnectionPointContainer IOleControl ISpecifyPropertyPages IObjectSafety IQuickActivate ISupportErrorInfo
In our case the IHTMLDocument, IHTMLDocument2, IHTMLDocument3, IHTMLDocument4, IHTMLDocument5 interfaces derive from IDispatch so we can call any of properties of these interfaces like in the following code:
Private Sub Form_Load() With Grid1 .BeginUpdate .Columns.Add "Column 1" .Items.InsertControlItem , "MSHTML:<HTML><BODY>This is a line of text</BODY></HTML>" .EndUpdate With .Items Debug.Print .ItemObject(.ItemByIndex(0)).uniqueID() End With End With End Sub
We arbitrary choose the uniqueID property that's a property of the IHTMLDocument3 interface. The documentation for these interfaces can be found in your MSDN documentation or by looking on the net for these names. Another alternative is using the OLEView tool in order to list the object's type library. Unfortunately, You need to contact the vendor for particular ActiveX controls, because we can't provide documentation for any ActiveX control you might use. We can provide documentation only for our components. Let's say that you will need other HTML fragment like: "MSHTML:<HTML><BODY bgcolor='#000000'>This is a line of text</BODY></HTML>", and you will ask us why the control can't change the HTML's background color? Obviously, the control just passes the HTML fragment to the Web browser, and the Web browser handles in its own way. The idea is that the control is not responsible for the look and the behavior of the inner ActiveX controls. Anyway, in this particular case how can we solve the problem? If we see that some attributes are not recognized, we can try to look for a property that can do the same thing. In this case we are looking for the bkColor property of IHTMLDocument2 interface that sets or retrieves a value that indicates the background color behind the object. So the code should look like:
Private Sub Form_Load()
With Grid1
.BeginUpdate
.Columns.Add "Column 1"
.Items.InsertControlItem , "MSHTML:<HTML><BODY>This is a line of text</BODY></HTML>"
.EndUpdate
With .Items
With .ItemObject(.ItemByIndex(0))
.bgColor = RGB(0, 0, 0)
.fgcolor = RGB(255, 255, 255)
End With
End With
End With
End Sub
Once an item of ActiveX type has been added you can get the OLE control that was created using the ItemObject property. Use the ItemControlID property to check if an item contains an ActiveX control. Use the ItemHeight property to change the item's height ( the item's height manages the control's height ). When the control contains an item of ActiveX type, it is recommend that you set the ScrollBySingleLine property of the control to true. Events from contained components are fired through to your program using the exact same model used in VB6 for components added at run time ( See ItemOleEvent event, OleEvent and OleEventParam ). For instance, when an ActiveX control fires an event, the control forwards that event to your container using ItemOleEvent event of the ExGrid control. The InsertControlItem method is not available if the control is running in the virtual mode.
The following VB sample adds dynamically an ExGrid ActiveX Control and a Microsoft Calendar Control:
' Inserts a new ActiveX control of Exontrol.Grid type Dim hGrid As HITEM hGrid = Grid1.Items.InsertControlItem(Grid1.Items(0), "Exontrol.Grid", runtimelicensekey) ' Sets the ActiveX control height Grid1.Items.ItemHeight(hGrid) = 212 ' Gets the ExGrid control created. Since the ProgID used to create the item is "Exontrol.Grid" ' the object will be of EXGRIDLibCtl.Grid type Dim objGrid As Object Set objGrid = Grid1.Items.ItemObject(hGrid) objGrid.Columns.Add "Column" objGrid.Items.AddItem "One" objGrid.Items.AddItem "Two" objGrid.Items.AddItem "Three" ' Inserts a new ActiveX control of MSCAL.Calendar type Dim hCalc As HITEM hCalc = objGrid.Items.InsertControlItem(, "MSCal.Calendar") Set objCalc = Grid1.Items.ItemObject(hCalc) objCalc.ShowTitle = False objCalc.ShowDateSelectors = False
where the runtimelicensekey is the exGrid's runtime license key. Please contact us to get the exGrid's runtime license key. Your order number, or your registered e-mail address is required, when requesting the control's runtime license key. Only, the vendor of the component you are going to use is able to give you such of runtime license, so please contact the control's vendor for such of key. Your development license key is not compatible with the runtime license key, so it can't be used here. Please notice that your development license key is not equivalent with the generated runtime license key. If you are using the DEMO version for testing purpose, you don't need a runtime license key.
The following VB sample shows how to handle any event that a contained ActiveX fires:
Private Sub Grid1_ItemOleEvent(ByVal Item As EXGRIDLibCtl.HITEM, ByVal Ev As EXGRIDLibCtl.IOleEvent) On Error Resume Next Dim i As Long Debug.Print "The " & Ev.Name & " was fired. " If Not (Ev.CountParam = 0) Then Debug.Print "The event has the following parameters: " For i = 0 To Ev.CountParam - 1 Debug.Print " - " & Ev(i).Name & " = " & Ev(i).Value Next End If End Sub
Some of ActiveX controls requires additional window styles to be added to the container window. For instance, the Web Brower added by the Grid1.Items.InsertControlItem(, "https://www.exontrol.com") won't add scroll bars, so you have to do the following:
First thing is to declare the WS_HSCROLL and WS_VSCROLL constants at the top of your module:
Private Const WS_VSCROLL = &H200000 Private Const WS_HSCROLL = &H100000
Then you need to to insert a Web control use the following lines:
Dim hWeb As HITEM hWeb = Grid1.Items.InsertControlItem(, "https://www.exontrol.com") Grid1.Items.ItemHeight(hWeb) = 196
Next step is adding the AddItem event handler:
Private Sub Grid1_AddItem(ByVal Item As EXGRIDLibCtl.HITEM) If (Grid1.Items.ItemControlID(Item) = "https://www.exontrol.com") Then ' Some of controls like the WEB control, requires some additional window styles ( like WS_HSCROLL and WS_VSCROLL window styles ) ' for the window that host that WEB control, to allow scrolling the web page Grid1.Items.ItemWindowHostCreateStyle(Item) = Grid1.Items.ItemWindowHostCreateStyle(Item) + WS_HSCROLL + WS_VSCROLL End If End Sub
The following VB sample adds the Exontrol's ExCalendar Component:
With Grid1 .BeginUpdate .ScrollBySingleLine = True With Grid1.Items Dim h As HITEM h = .InsertControlItem(, "Exontrol.Calendar") .ItemHeight(h) = 182 With .ItemObject(h) .Appearance = 0 .BackColor = vbWhite .ForeColor = vbBlack .ShowTodayButton = False End With End With .EndUpdate End With
The following VB sample binds the master control to a table, and displays related tables when the user expands an item/record. The sample uses the DataSource property to bind a record set to the control. The InsertControlItem method inserts an ActiveX inside the item.
Option Explicit Public Function getRS(ByVal q As String) As Object Dim rs As Object, strDatabase strDatabase = App.Path + "\ExontrolDemo.mdb" Set rs = CreateObject("ADODB.Recordset") rs.Open q, "Provider = Microsoft.Jet.OLEDB.4.0; Data Source =" & strDatabase, 3, 3, 0 Set getRS = rs End Function Private Sub Form_Load() With Grid1 .BeginUpdate .LinesAtRoot = exLinesAtRoot .MarkSearchColumn = False .ScrollBySingleLine = True .HideSelection = True Set .DataSource = getRS("Transactions") .EndUpdate End With End Sub Private Sub Grid1_AddItem(ByVal Item As EXGRIDLibCtl.HITEM) With Grid1.Items .ItemHasChildren(Item) = .ItemParent(Item) = 0 End With End Sub Private Sub Grid1_BeforeExpandItem(ByVal Item As EXGRIDLibCtl.HITEM, Cancel As Variant) With Grid1.Items If .ItemHasChildren(Item) Then With .ItemObject(.InsertControlItem(Item, "Exontrol.Grid")) .BeginUpdate .MarkSearchColumn = False .HideSelection = True Set .DataSource = getRS("Select * from TransactionDetails where TrnDet_ID = " & Grid1.Items.CellValue(Item, "Trn_ID")) .Columns(0).Visible = False .EndUpdate End With .ItemHasChildren(Item) = False End If End With Grid1.Refresh End Sub
The following C++ sample adds the Exontrol's ExOrgChart Component:
#include "Items.h" #pragma warning( disable : 4146 ) #import <ExOrgChart.dll> CItems items = m_grid.GetItems(); m_grid.BeginUpdate(); m_grid.SetScrollBySingleLine( TRUE ); COleVariant vtMissing; V_VT( &vtMissing ) = VT_ERROR; long h = items.InsertControlItem( 0, "Exontrol.ChartView", vtMissing ); items.SetItemHeight( h, 182 ); EXORGCHARTLib::IChartViewPtr spChart( items.GetItemObject(h) ); if ( spChart != NULL ) { spChart->BeginUpdate(); spChart->BackColor = RGB(255,255,255); spChart->ForeColor = RGB(0,0,0); EXORGCHARTLib::INodesPtr spNodes = spChart->Nodes; spNodes->Add( "Child 1", "Root", "1", vtMissing, vtMissing ); spNodes->Add( "SubChild 1", "1", vtMissing, vtMissing, vtMissing ); spNodes->Add( "SubChild 2", "1", vtMissing, vtMissing, vtMissing ); spNodes->Add( "Child 2", "Root", vtMissing, vtMissing, vtMissing ); spChart->EndUpdate(); } m_grid.EndUpdate();
The sample uses the #import statement to include the ExOrgChart's Type Library. In this sample, the ItemObject property retrieves an IChartView object. The path to the library should be provided in case it is not located in your system folder.
The following C# sample adds the Exontrol's ExGrid Component:
axGrid1.BeginUpdate(); EXGRIDLib.Items items = axGrid1.Items; axGrid1.ScrollBySingleLine = true; int h = items.InsertControlItem(0, "Exontrol.Grid", ""); items.set_ItemHeight(h, 182); object gridInside = items.get_ItemObject(h); if (gridInside != null) { EXGRIDLib.Grid grid = gridInside as EXGRIDLib.Grid; if (grid != null) { grid.BeginUpdate(); grid.LinesAtRoot = EXGRIDLib.LinesAtRootEnum.exLinesAtRoot; grid.Columns.Add("Column 1"); grid.Columns.Add("Column 2"); grid.Columns.Add("Column 3"); EXGRIDLib.Items itemsInside = grid.Items; int hInside = itemsInside.AddItem("Item 1"); itemsInside.set_CellValue(hInside, 1, "SubItem 1"); itemsInside.set_CellValue(hInside, 2, "SubItem 2"); hInside = itemsInside.InsertItem(hInside, null, "Item 2"); itemsInside.set_CellValue(hInside, 1, "SubItem 1"); itemsInside.set_CellValue(hInside, 2, "SubItem 2"); grid.EndUpdate(); } } axGrid1.EndUpdate();
The following C# sample casts the ItemObject to IGrid interface:
int hX = axGrid1.Items.InsertControlItem(0, "Exontrol.Grid", ""); EXGRIDLib.IGrid spGrid = axGrid1.Items.get_ItemObject(hX) as EXGRIDLib.IGrid; spGrid.Columns.Add("Inner Column");
The following VB.NET sample adds the Exontrol's ExOrgChart Component:
With AxGrid1 .BeginUpdate() .ScrollBySingleLine = True With .Items Dim hItem As Integer hItem = .InsertControlItem(, "Exontrol.ChartView") .ItemHeight(hItem) = 182 With .ItemObject(hItem) .BackColor = ToUInt32(Color.White) .ForeColor = ToUInt32(Color.Black) With .Nodes .Add("Child 1", , "1") .Add("SubChild 1", "1") .Add("SubChild 2", "1") .Add("Child 2") End With End With End With .EndUpdate() End With
The following VB.NET sample casts the ItemObject to IGrid interface:
Dim hX As Long = .InsertControlItem(0, "Exontrol.Grid", "") Dim spGrid As EXGRIDLib.IGrid = .ItemObject(hX) spGrid.Columns.Add("Inner Column")
The following VFP sample adds the Exontrol's ExGrid Component:
with thisform.Grid1 .BeginUpdate() .ScrollBySingleLine = .t. with .Items .DefaultItem = .InsertControlItem(0, "Exontrol.Grid") .ItemHeight( 0 ) = 182 with .ItemObject( 0 ) .BeginUpdate() with .Columns with .Add("Column 1").Editor() .EditType = 1 && EditType editor endwith endwith with .Items .AddItem("Text 1") .AddItem("Text 2") .AddItem("Text 3") endwith .EndUpdate() endwith endwith .EndUpdate() endwithThe following VB6 sample shows you how to handle an event from a outer-inner-inner control. In other words, you have a master control (outer), which insert another control (inner), which insert another control (inner).
Private Sub expandItem(ByVal grid As Object, ByVal item As Long, ByVal level As Long) Debug.Print "Expand item in " & level & " control" End Sub ' BeforeExpandItem event - Fired before an item is about to be expanded (collapsed). Private Sub Grid1_BeforeExpandItem(ByVal item As EXGRIDLibCtl.HITEM, Cancel As Variant) expandItem Grid1.Object, item, 0 End Sub ' ItemOleEvent event - Fired when an ActiveX control hosted by an item has fired an event. Private Sub Grid1_ItemOleEvent(ByVal item As EXGRIDLibCtl.HITEM, ByVal Ev As EXGRIDLibCtl.IOleEvent) With Grid1 'Debug.Print Ev.ToString() If (Ev.ID = 12) Then ' BeforeExpandItem expandItem Grid1.Items.ItemObject(item), Ev.Param(0).Value, 1 Else If (Ev.ID = 14) Then ' ItemOLEEvent 'Debug.Print Ev.Param(1).Value.ToString() If (Ev.Param(1).Value.ID = 12) Then ' BeforeExpandItem 'Debug.Print "Expand item in inner-inner control" expandItem Grid1.Items.ItemObject(item).Items.ItemObject(Ev.Param(0).Value), Ev.Param(1).Value.Param(0).Value, 2 End If End If End If End With End Sub