Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS General Discussion » RibbonBar: How to set focus on a specific textfield Collapse All
Subject Author Date
Oliver Rau Mar 11, 2009 - 7:37 AM

Dear ProfUIS-Team,


how can I programmatically set focus on a ribbon node that has been qualified as a text field using the __ECTN_TBB_TEXT_FIELD flag?


Kind regards,


Martin

Technical Support Mar 11, 2009 - 10:35 AM

This is a bit more complicated. If you found a text field button but it’s CExtBarButton::IsVisible() method returned false, then you should do the following:

1) Walk through parent buttons of the found button using the CExtBarButton::ParentButtonGet() method and find the instance of the CExtRibbonButtonGroup button using the DYNAMIC_DOWNCAST preprocessor function.

2) Invoke the CExtRibbonButtonGroup::OnTrackPopup() virtual method of the found group button.

3) If the popup ribbon page control is displayed, then the CExtRibbonBar::m_pPopupPageMenuGroup property is not NULL. It’s the ribbon popup menu displayed on the screen.

4) The CExtRibbonBar::m_pPopupPageMenuGroup.m_wndRibbonPage property is the CExtRibbonPage control inside the displayed on the screen popup menu. This ribbon page contains only one non collapsed group of buttons which contains cloned button copies from the collapsed group of button inside the main CExtRibbonBar control. You should repeat the text field searching for the CExtRibbonBar::m_pPopupPageMenuGroup.m_wndRibbonPage ribbon page window like we described it for the main ribbon bar window in our previous answer.

Oliver Rau Mar 12, 2009 - 11:24 AM

Thank you for your kind answer!

I tried the following code:

int i_idx =
	m_wndRibbonBar.CExtToolControlBar::CommandToIndex(ID_CMD);

if(i_idx >= 0)
{
	CExtBarButton * button =
		m_wndRibbonBar.CExtToolControlBar::GetButton(i_idx);
	if(!button->CExtBarButton::IsVisible())
	{
		button = button->ParentButtonGet();
		while(button)
		{
			if(DYNAMIC_DOWNCAST(CExtRibbonButtonGroup, button) )
			{
				(dynamic_cast<CExtRibbonButtonGroup *> (button))->
					CExtRibbonButtonGroup::OnTrackPopup(
						CPoint(-32767,-32767),
						true,
						true);
				break;
			}
			button = button->ParentButtonGet();
		}
		if (m_wndRibbonBar.m_pPopupPageMenuGroup)
		{
			i_idx = m_wndRibbonBar.m_pPopupPageMenuGroup->
				m_wndRibbonPage.CommandToIndex(ID_CMD);
				button = m_wndRibbonBar.m_pPopupPageMenuGroup->
				m_wndRibbonPage.GetButton(i_idx);
		}
		else
		{
			return;
		}
	}
	(dynamic_cast<CExtBarTextFieldButton *> (button) )->
		OnInplaceControlRun();
}

Unfortunately I got an error within ExtRibbonBar.cpp:


Calling IsAbleToTrackMenu() in function CExtRibbonButtonGroup::OnTrackPopup() returns false, thus -1 is being returned. (Yes, we’re still using ProfUIS 2.82 ;-)


What could I do to solve this issue?


Martin


 

Technical Support Mar 15, 2009 - 10:07 AM

Thank you for your question. It helped us find a small typo in the CExtRibbonBar::Ribbon_AutoHideModeDoExpanding() method. There are the following lines of code near the beginning of this method:

INT nSelIdx = RibbonTabPageButton_GetIndexOf( pTBB );
            if( nSelIdx <= 0 )
                        return false;
In fact they should be:
INT nSelIdx = RibbonTabPageButton_GetIndexOf( pTBB );
            if( nSelIdx < 0 )
                        return false;
We implemented programmatic activation of text/combo field buttons. We didn’t add any new methods to the CExtRibbonBar and CExtRibbonPage classes yet. But we made the RibbonBar sample application activating two different text fields when clicking on the Undo and Redo buttons inside the ribbon bar’s quick access toolbar area which is near the ribbon file button. We just inserted the following code into the beginning of the CMainFrame::OnCmdMsg() method in the RibbonBar sample application:
   if( ( nID == ID_QA_EDIT_UNDO || nID == ID_QA_EDIT_REDO ) && nCode == CN_COMMAND && pExtra == NULL )
            {
                        // the index of the Home or Mailings ribbon tab page
                        INT nRibbonTabPageIndex = ( nID == ID_QA_EDIT_UNDO ) ? 0 : 4;
                        // id of font face name or go to text fields
                        UINT nTextFieldButtonCmdID = ( nID == ID_QA_EDIT_UNDO ) ? ID_SE_FONT_LIST : ID_MAILINGS_GOTO_RECORD;
                        SendMessage( WM_CANCELMODE ); // close any popup windows
                        CExtRibbonPage * pWndRibbonPageToSearch = &m_wndRibbonBar;
                        if( ! m_wndRibbonBar.RibbonPage_ExpandedModeGet() )
                        {
                                    pWndRibbonPageToSearch = NULL;
                                    CExtRibbonButtonTabPage * pRibbonTabPageTBB = m_wndRibbonBar.RibbonTabPageButton_GetAt( nRibbonTabPageIndex );
                                    ASSERT_VALID( pRibbonTabPageTBB );
                                    if(                     m_wndRibbonBar.Ribbon_AutoHideModeDoExpanding( pRibbonTabPageTBB, false )
                                                &&        m_wndRibbonBar.m_pPopupPageMenuAutoHide != NULL
                                                )
                                    {
                                                ASSERT_VALID( m_wndRibbonBar.m_pPopupPageMenuAutoHide );
                                                ASSERT( m_wndRibbonBar.m_pPopupPageMenuAutoHide->GetSafeHwnd() != NULL );
                                                pWndRibbonPageToSearch = &m_wndRibbonBar.m_pPopupPageMenuAutoHide->m_wndRibbonPage;
                                    }
                        }
                        else
                                    m_wndRibbonBar.Ribbon_PageSelectionSet( nRibbonTabPageIndex );
                        if( pWndRibbonPageToSearch != NULL )
                        {
                                    ASSERT_VALID( pWndRibbonPageToSearch );
                                    ASSERT( pWndRibbonPageToSearch->GetSafeHwnd() != NULL );
                                    int nTextFieldIndex = pWndRibbonPageToSearch->CommandToIndex( nTextFieldButtonCmdID );
                                    if( nTextFieldIndex >= 0 )
                                    {
                                                CExtBarTextFieldButton * pTextFieldTBB =
                                                            DYNAMIC_DOWNCAST( CExtBarTextFieldButton, pWndRibbonPageToSearch->GetButton( nTextFieldIndex ) );
                                                if( pTextFieldTBB != NULL )
                                                {
                                                            ASSERT_VALID( pTextFieldTBB );
                                                            if( pTextFieldTBB->IsVisible() )
                                                                        pTextFieldTBB->OnInplaceControlRun();
                                                            else
                                                            {
                                                                        CExtRibbonButtonGroup * pGroupTBB = NULL;
                                                                        CExtBarButton * pTBB = pTextFieldTBB->ParentButtonGet();
                                                                        for( ; pTBB != NULL; pTBB = pTBB->ParentButtonGet() )
                                                                                    pGroupTBB = DYNAMIC_DOWNCAST( CExtRibbonButtonGroup, pTBB ); // find top group button
                                                                        if( pGroupTBB != NULL )
                                                                        {
                                                                                    ASSERT_VALID( pGroupTBB );
                                                                                    CPoint ptTrack = pGroupTBB->Rect().CenterPoint();
                                                                                    bool bSavedTCS = pGroupTBB->TopCollapsedStateGet();
                                                                                    pGroupTBB->TopCollapsedStateSet( true );
                                                                                    pGroupTBB->OnTrackPopup( ptTrack, false, false );
                                                                                    pGroupTBB->TopCollapsedStateSet( bSavedTCS );
                                                                                    if(                     pWndRibbonPageToSearch->m_pPopupPageMenuGroup->GetSafeHwnd() != NULL
                                                                                                &&        pWndRibbonPageToSearch->m_pPopupPageMenuGroup->m_wndRibbonPage.GetSafeHwnd() != NULL
                                                                                                )
                                                                                    {
                                                                                                pWndRibbonPageToSearch = &pWndRibbonPageToSearch->m_pPopupPageMenuGroup->m_wndRibbonPage;
                                                                                                nTextFieldIndex = pWndRibbonPageToSearch->CommandToIndex( nTextFieldButtonCmdID );
                                                                                                if( nTextFieldIndex >= 0 )
                                                                                                {
                                                                                                            pTextFieldTBB =
                                                                                                                        DYNAMIC_DOWNCAST( CExtBarTextFieldButton, pWndRibbonPageToSearch->GetButton( nTextFieldIndex ) );
                                                                                                            if( pTextFieldTBB != NULL )
                                                                                                            {
                                                                                                                        ASSERT_VALID( pTextFieldTBB );
                                                                                                                        if( pTextFieldTBB->IsVisible() )
                                                                                                                                    pTextFieldTBB->OnInplaceControlRun();
                                                                                                            }
                                                                                                }
                                                                                    }
                                                                        }
                                                            }
                                                }
                                    }
                        }
                        m_wndRibbonBar.Invalidate();
                        return TRUE;
            }
As we said, we didn’t insert a new method doing the same into Prof-UIS. We think we need to add some additional cases. For instance, the text/combo field ribbon items can be even deeper in the ribbon tree - they can be inside popup menus displayed by some ribbon buttons. They also can be inside ribbon file menu displayed from ribbon file button, inside quick access toolbar and part of right buttons group that is at right side of ribbon tabs. This task is even more interesting. There are several other ribbon elements which you may need to display programmatically and/or set focus to them: different types of galleries, popup color and date picker menus, check boxes etc. We are trying to design and test some more universal code which is able to solve your task as one of possible tasks. So, if you have any whishes or any similar tasks in your project, then we are ready to discuss them.

Please also note, if you will not apply the issue fix we meant at the beginning of this message, then only the Undo button will activate and focus ribbon text field after modifying the RibbonBar sample application.


Oliver Rau Mar 16, 2009 - 6:54 AM

Thanks again for answering - you guys do a great support job!


Now everything’s working perfect so far. At the moment we do not have any further tasks concerning focus and/or activate special ribbon items. But in the future, who knows ... ;-)


Greetings from Germany,


Martin

Technical Support Mar 11, 2009 - 8:53 AM

This is performed in the same way for ribbon bar and for toolbar controls because the ribbons are very extended customizable toolbars. You should use the CExtToolControlBar::CommandToIndex() method to find button index by its command identifier. The ribbon bar keeps created the toolbar buttons for the selected ribbon page only. So, if your text field button is not displayed, then the CExtToolControlBar::CommandToIndex() method will return -1. Then you should use the CExtToolControlBar::GetButton() method to get the CExtBarButton pointer of your text field button. Then you should use the DYNAMIC_DOWNCAST or STATIC_DOWNCAST preprocessor functions to get the CExtBarTextFieldButton pointer. Then you should invoke the CExtBarTextFieldButton::OnInplaceControlRun() method to start the editor in your button.

Oliver Rau Mar 11, 2009 - 9:19 AM

Thank you for your quick and detailed answer!


As long as the ribbon is expanded, everything’s working fine concerning the focus.


If the ribbon is in the collapsed state and I get the focus, there’s the problem that I cannot see the textfield.


Question: How can I programmatically expand the ribbon? Or is there a more elegant way, e.g. a kind of flag that automatically expands the ribbon when something inside has been focussed?


Martin