eXPlorerBar - FAQ
Exontrol.COM Software - Frequently Asked Questions - ExplorerBar Component
1:
The control's release notes can be found on our web site, looking for the Release Notes column in the control's main page. Click here for direct link.
2:
Yes. The following tutorial shows the steps that are required to insert an ActiveX control inside the control. Shortly, the idea is to insert child windows to the control, and to move the windows when the control fires the LayoutChanged event. The following sample shows how to add a SysTreeView32 window to the control. The following sample contains all code you need to handle ActiveX inside the control.
  • Insert an ExplorerBar control ( IDC_EXPLORERBAR1 ), to the dialog (form)
  • Add a variable member m_explorerBar, using the Class wizard
  • Add a Tree control ( IDC_TREE1 ) to the dialog ( form )
  • Add a variable member m_tree, using the Class wizard
  • Locate the OnInitDialog member of the dialog
  • Call the initialization functions to the OnInitDialog function like follows:
    BOOL OnInitDialog()
    {
    	....
    	initTree();
    	initExplorerBar();
    	...	
    	return TRUE;  
    }
  • Implement the initTree function. For instance, the following sample adds few items to the tree control 
    void initTree()
    {
    	HTREEITEM h = m_tree.InsertItem( _T("Root") );
    	HTREEITEM hChild1 =m_tree.InsertItem( _T("Child1"), h );
    	m_tree.InsertItem( _T("SubChild1"), hChild1 );
    	m_tree.InsertItem( _T("SubChild2"), hChild1 );
    	HTREEITEM hChild2 =m_tree.InsertItem( _T("Child2"), h );
    	m_tree.Expand( h, TVE_EXPAND );
    	m_tree.Expand( hChild1, TVE_EXPAND );
    }
  • Implement the initExplorerBar function like follows:
    void initExplorerBar()
    {
    	COleVariant vtMissing; V_VT( &vtMissing ) = VT_ERROR;
    	m_explorerBar.BeginUpdate();
    		// Adds a group that hosts a tree control 
    		CGroups groups = m_explorerBar.GetGroups();
    		CGroup group = groups.Add( _T("Tree inside") );
    		group.SetItemHeight( 84 );
    		group.AddItem( _T(""), vtMissing );
    		group.SetExpanded( TRUE );
    		initHost( m_tree.m_hWnd, m_explorerBar, group.GetIndex() );
    	m_explorerBar.EndUpdate();
    }

    The initExplorerBar function adds a group, and a single item to the group. The ItemHeight property of the Group object is called, to specifies the height of the item, but in our case it will specify the height of the hosted window. The initHost function changes the parent window of the host window, and holds the window's handle to the group's user data. 

  • Implement the initHost function like follows:
    void initHost( HWND hWnd, CExplorerBar& explorerBar, long nGroupIndex )
    {
    	CGroup group = explorerBar.GetGroups().GetItem( COleVariant( nGroupIndex ) );
    	if ( hWnd )
    	{
    		::SetClassLong( hWnd, GCL_STYLE, CS_HREDRAW | CS_VREDRAW );
    		::SetWindowPos( explorerBar.m_hWnd, hWnd , 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED );
    		::SetParent( hWnd, explorerBar.m_hWnd );
    		
    		// Stores the handle to the inside window to the group's user data.
    		group.SetUserData( COleVariant( (long)hWnd ) );
    		moveHost( hWnd, explorerBar, nGroupIndex );
    	}
    }

The initHost function changes the Z order of the window, change the parent window, holds the window's handle to the group's user data, and moves the window to the new position.

  • Implement the moveHost function like follows:
    void moveHost( HWND hWnd, CExplorerBar& explorerBar, long nGroupIndex )
    {
    	if ( ::IsWindow( hWnd ) )
    	{
    		CGroup group = explorerBar.GetGroups().GetItem( COleVariant( nGroupIndex ) );
    		CRect rtGroup;
    		rtGroup.left = group.GetLeft();
    		rtGroup.right = rtGroup.left + group.GetWidth();
    		rtGroup.top = group.GetTop();
    		rtGroup.bottom = rtGroup.top + group.GetHeight();
    /*
    		::SetWindowPos( hWnd, NULL, rtGroup.left, rtGroup.top, rtGroup.Width(), rtGroup.Height(), SWP_FRAMECHANGED | SWP_NOZORDER | SWP_HIDEWINDOW | SWP_NOREDRAW);
    		::SetWindowPos( hWnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | ( group.GetExpanded() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW ) );
    */
    		::SetWindowPos( hWnd, NULL, rtGroup.left, rtGroup.top, rtGroup.Width(), rtGroup.Height(), SWP_NOZORDER | ( group.GetExpanded() ? SWP_SHOWWINDOW : SWP_HIDEWINDOW ) );
    	}
    }

The moveHost function moves the window to the coordinates specified by Left, Top, Width and Height properties of the Group object.

  • Handle the LayoutChanged event of the ExplorerBar control like follows:
void OnLayoutChangedExplorerbar1() 
{
	if ( IsWindow( m_explorerBar.m_hWnd ) )
	{
		CGroups groups = m_explorerBar.GetGroups();
		for ( long i = 0; i < groups.GetCount(); i++ )
			moveHost( m_explorerBar, i );
	}
}
In conclusion, the tutorial describes how the control is able to host windows inside, so you will be able to host any ActiveX control that exposes a hWnd property.
3:
Yes. The following tutorial shows the steps that are required to insert an ActiveX control inside the control. Shortly, the idea is to insert child windows to the control, and to move the windows when the control fires the LayoutChanged event. The following sample shows how to add a ListBox control to the ExplorerBar control. The following sample contains all code you need to handle ActiveX inside the control.
  • Insert an ExplorerBar control ( ExplorerBar1 ) to the form
  • Add a ListBox control ( List1 ) to the form
  • Call initialization functions in the Form_Load event like follows:
    Private Sub Form_Load()
        ...
        initList
        initExplorerBar
        ...
    End Sub
  • Implement the initList function. For instance, the following sample adds few items to the ListBox control 
    Private Sub initList()
        With List1
            .AddItem "Item 1"
            .AddItem "Item 2"
            .AddItem "Item 3"
            .AddItem "Item 4"
        End With
    End Sub
  • Implement the initExplorerBar function like follows:
    Private Sub initExplorerBar()
        With ExplorerBar1
            .BeginUpdate
                With .Groups.Add("List")
                    .ItemHeight = 84
                    .AddItem ""
                    initHost List1, ExplorerBar1, .Index
                    .Expanded = True
                End With
            .EndUpdate
        End With
    End Sub

    The initExplorerBar function adds a group, and a single item to the group. The ItemHeight property of the Group object is called, to specify the height of the item, but in our case it will specify the height of the hosted window. The initHost function changes the parent window of the host window, and holds the control's reference to the group's user data. 

  • Implement the initHost function like follows:
    Private Sub initHost(ByVal c As Object, ByVal e As EXPLORERBARLibCtl.ExplorerBar, ByVal i As Long)
        Dim g As EXPLORERBARLibCtl.Group
        Set g = e.Groups(i)
        If Not c Is Nothing Then
            SetParent c.hwnd, e.hwnd
            g.UserData = c
            moveHost e, i
        End If
    End Sub

    The initHost function change the parent window, holds the control to the group's user data, and moves the control to the new position.

  • Implement the moveHost function like follows:
    Private Sub moveHost(ByVal e As EXPLORERBARLibCtl.ExplorerBar, ByVal i As Long)
    On Error Resume Next
        Dim g As EXPLORERBARLibCtl.Group
        Set g = e.Groups(i)
        Dim c As Object
        Set c = g.UserData
        If Not c Is Nothing Then
            If Not (g.Expanded) Then
                c.Visible = False
            End If
            c.Left = g.Left * Screen.TwipsPerPixelX
            c.Top = g.Top * Screen.TwipsPerPixelY
            c.Width = g.Width * Screen.TwipsPerPixelX
            c.Height = g.Height * Screen.TwipsPerPixelY
            If (g.Expanded) Then
                c.Visible = True
            End If
        End If
    End Sub

    The moveHost function moves the control to the coordinates specified by Left, Top, Width and Height properties of the Group object.

  • Handle the LayoutChanged event of the ExplorerBar control like follows:
Private Sub ExplorerBar1_LayoutChanged()
    Dim g As EXPLORERBARLibCtl.Group
    For Each g In ExplorerBar1.Groups
        moveHost ExplorerBar1, g.Index
    Next
End Sub
4:
Yes. Starting with the version 1.0.2.3 the control supports custom size pictures. Use the Item.Image property to assign an icon or a picture to an item. Use the Group.Image property to assign an icon or a picture to a group. The Image property takes a long expression that indicates the index of icon being displayed, a string expression that indicates the base64 encoded string that holds a picture object, or a picture object. Use the eximages tool to save your picture as base64 encoded format.
5:
The Visible property of the Item object shows or hides an item. Use the Position property to specify the position of the item. Use the ItemByPos property to get an item by its position.
How-To Questions
General Questions