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 Tech Support » CExtRibbonOptionsDialog: custom option pages larger than dialog control Collapse All
Subject Author Date
Oliver Rau Feb 8, 2008 - 4:55 AM

Dear ProfUIS-Team,

adding a new option page does not ensure resizing of the ribbon option dialog. The original ProfUIS code does not take care about the size of option pages. To create a ribbon’s option dialog the dialog template IDD_EXT_RIBBON_OPTIONS_DIALOG is taken from resources. If the size of a custom option page exceeds that of the dialog control IDC_EXT_RIBBON_STATIC_FRAME, then the problem is passed to the user.

Therefore we needed to customize ExtRibbonBar.cpp in order to deal with that problem:

BOOL CExtRibbonOptionsDialog::OnInitDialog()
{
	m_wndOptionsTabs.ResetContent();

	if(		m_pRibbonBar->GetSafeHwnd() == NULL
			||	( ! CExtNCW < CExtResizableDialog > :: OnInitDialog() )
		)
	{
		ASSERT( FALSE );
		return FALSE;
	}
	ASSERT_VALID( m_pRibbonBar );
	m_strCommandProfileName =
		g_CmdManager->ProfileNameFromWnd( m_pRibbonBar->m_hWnd );
	ASSERT( ! m_strCommandProfileName.IsEmpty() );
	g_CmdManager->ProfileWndAdd(
		LPCTSTR( m_strCommandProfileName ),
		m_hWnd
		);

	CWnd * pWnd = CExtControlBar::stat_GetWndForPlacement( m_pRibbonBar );
	HICON hIcon = NULL;
	if( pWnd->GetSafeHwnd() != NULL )
	{
		hIcon = (HICON)
			::SendMessage(
				pWnd->m_hWnd,
				WM_GETICON,
				ICON_BIG,
				0L
				);
		if( hIcon == NULL ) 
		{
			hIcon = (HICON)
				::SendMessage(
					pWnd->m_hWnd,
					WM_GETICON,
					ICON_BIG,
					0L
					);
			if( hIcon == NULL ) 
			{
				hIcon = (HICON)
					::GetClassLong(
						pWnd->m_hWnd,
						__EXT_MFC_GCL_HICON
						);
				if(hIcon == NULL) 
					hIcon = ::AfxGetApp()->LoadStandardIcon( IDI_WINLOGO );
			} // if( hIcon == NULL ) 
		} // if( hIcon == NULL ) 
	} // if( pWnd->GetSafeHwnd() != NULL )
	if( hIcon != NULL )
	{
		SetIcon( hIcon, TRUE );
		SetIcon( hIcon, FALSE );
	} // if( hIcon != NULL )

	AddAnchor( IDC_EXT_RIBBON_LIST_BOX_TABS, __RDA_LT, __RDA_LB );
	AddAnchor( IDC_EXT_RIBBON_STATIC_FRAME, __RDA_LT, __RDA_RB );
	AddAnchor( IDOK, __RDA_RB );
	AddAnchor( IDCANCEL, __RDA_RB );
	CRect rcWnd;
	GetWindowRect( &rcWnd );
	CSize _sizeMinTrack(
		::MulDiv( rcWnd.Width(),  5, 6 ),
		::MulDiv( rcWnd.Height(), 7, 8 )
		);
	SetMinTrackSize( _sizeMinTrack );

	CRect rcPage;
	m_labelEmptyFrame.GetWindowRect( &rcPage );
	ScreenToClient( &rcPage );
	m_pRibbonBar->OnRibbonOptionsDialogInitPageRTCs( *this );
	HWND hWndSelPage = NULL;
	HWND hWndInsertAfter = m_wndOptionsTabs.m_hWnd;
	INT nPageIndex, nPageCount = INT( m_arrPageRTCs.GetSize() );
	for( nPageIndex = 0; nPageIndex < nPageCount; nPageIndex ++ )
	{
		CRuntimeClass * pRTC = m_arrPageRTCs[ nPageIndex ];
		if(		pRTC == NULL
				||	( ! pRTC->IsDerivedFrom( RUNTIME_CLASS( CExtRibbonOptionsPage ) ) )
			)
		{
			ASSERT( FALSE );
			return FALSE;
		}
		CObject * pObject = pRTC->CreateObject();
		if( pObject == NULL )
		{
			ASSERT( FALSE );
			return FALSE;
		}
		CExtRibbonOptionsPage * pPage =
			STATIC_DOWNCAST( CExtRibbonOptionsPage, pObject );
		UINT nPageID = pPage->RibbonOptionsPage_GetID();
		if( ! pPage->Create( nPageID, this ) )
		{
			ASSERT( FALSE );
			return FALSE;
		}
		pPage->ShowWindow( SW_HIDE );
		if( ! m_wndOptionsTabs.AddPage( pPage ) )
		{
			ASSERT( FALSE );
			return FALSE;
		}
		if( hWndSelPage == NULL )
			hWndSelPage = pPage->m_hWnd;
		else if( m_nSelectedPageID == nPageID )
			hWndSelPage = pPage->m_hWnd;

		// ----------- START OF INSERTED CODE ------------
 		CRect pageRect;
		CRect newRect(rcWnd);
		pPage->GetWindowRect(&pageRect);

		int difX = pageRect.Width() - rcPage.Width();
		if (0 < difX )
		{
			newRect.right += difX;
			rcPage.right  += difX;
		}

		int difY = pageRect.Height()- rcPage.Height();
		if (0 < difY )
		{
			newRect.bottom += difY;
			rcPage.bottom  += difY;
		}

		if ( !newRect.EqualRect(rcWnd))
		{
			MoveWindow(&newRect);
			rcWnd = newRect;
		}
		// ----------- END OF INSERTED CODE ------------

		::SetWindowPos(
			pPage->m_hWnd,
			hWndInsertAfter,
			rcPage.left,
			rcPage.top,
			rcPage.Width(),
			rcPage.Height(),
			SWP_NOACTIVATE|SWP_NOOWNERZORDER
			);
		AddAnchor( pPage->m_hWnd, __RDA_LT, __RDA_RB );
		hWndInsertAfter = pPage->m_hWnd;
	} // for( nPageIndex = 0; nPageIndex < nPageCount; nPageIndex ++ )

	pWnd = GetWindow( GW_CHILD );
	for( ; pWnd != NULL; pWnd = pWnd->GetWindow( GW_HWNDNEXT ) )
	{
		CExtRibbonOptionsPage * pPage =
			DYNAMIC_DOWNCAST( CExtRibbonOptionsPage, pWnd );
		if( pPage == NULL )
			continue;
		if( ! pPage->RibbonOptionsPage_InitContent() )
		{
			ASSERT( FALSE );
			return FALSE;
		} // if( ! pPage->RibbonOptionsPage_InitContent() )
	} // for( ; pWnd != NULL; pWnd = pWnd->GetWindow( GW_HWNDNEXT ) )

	if( m_nSelectedPageID == __EXT_RIBBON_OPTIONS_DIALOG_PAGE_DEFAULT )
		m_nSelectedPageID = __EXT_RIBBON_OPTIONS_DIALOG_PAGE_CQATB;
	CExtRibbonOptionsPage * pSelectedPage = NULL;
	pWnd = GetDlgItem( m_nSelectedPageID );
	if( pWnd != NULL )
		pSelectedPage = DYNAMIC_DOWNCAST( CExtRibbonOptionsPage, pWnd );
	if( pSelectedPage == NULL )
	{
		pWnd = GetWindow( GW_CHILD );
		for( ; pWnd != NULL; pWnd = pWnd->GetWindow( GW_HWNDNEXT ) )
		{
			pSelectedPage = DYNAMIC_DOWNCAST( CExtRibbonOptionsPage, pWnd );
			if( pSelectedPage != NULL )
				break;
		} // for( ; pWnd != NULL; pWnd = pWnd->GetWindow( GW_HWNDNEXT ) )
	} // if( pSelectedPage == NULL )
	if( pSelectedPage != NULL )
		m_wndOptionsTabs.SelectPage( pSelectedPage );
	m_wndOptionsTabs.OnSwUpdateScrollBars();

	if( hWndSelPage != NULL )
	{
		m_labelEmptyFrame.ShowWindow( SW_HIDE );
		::ShowWindow( hWndSelPage, SW_SHOW );
	}

	return TRUE;
}
Would you please provide for such kind of resize functionality in future releases?

Best regards,

Martin

Technical Support Feb 9, 2008 - 1:47 AM

Thank you for sharing this interesting idea with us. We can add this improvement without any changes to Prof-UIS but it may potentially make the entire ribbon options dialog much wider and/or higher than the width and/or height of the desktop. We believe the better solution should be based on a scrollable dialog container which allows the user to scroll the dialog if there is not enough space for it and at the same time it should allow the use to implement control anchoring and automatic repositioning if there is enough space for this dialog. Here is the sample application demonstrating such ready-to-use scrollable dialog container:

TestScrollDialog.zip

The entire options dialog have some initial size which is not very big and not very small. Its size is some common dialog size which is close to the middle size of most of the dialogs in the most of applications. But the user can resize the options dialog if some page contains a larger number of controls and any other UI elements. This is behavior of the same dialog in MS Word. The CExtRibbonOptionsDialog class is kind of the CExtResizableDialog resizable dialog. It’s displayed modally in the virtual method. So, you can invoke resizable dialog’s EnableSaveRestore() method to make the position of the ribbon options dialog restorable.