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 » Dynamic Control Bar - Background image and pop up menu Collapse All
Subject Author Date
Yusuf Abdulkadir Jul 18, 2006 - 11:51 AM

Following your examples and article, I created a tabbed window application. My main frame is derived from CExtDynamicBarSite as follows

class CMainFrame
: public CMDIFrameWnd
, public CExtDynamicBarSite
{

and I have created a number of tabbed pages using CExtDynamicControlBar. Now that all my pages are working, I would like to know if it is possible to change the background and pop up menus.

when all the tabbed pages are closed, the default color of the theme I selected is used to paint the background of CExtDynamicBarSite. I have seen other questions and your reply on this forum how to change the default color. Instead of color, I want to show a bitmap as the background image, so when all the tabs are closed, the background image will be visible. Is this possible, if so, how do I accomplish this?

the second question is, when I right click on the tab page the default pop up menu is showed, which allows the control bar to dock or float with the following default entries
-floating
-dockable
-tabbed document
-Auto Hide
-hide

Is it possible to replace or extend this menu? Can I rename "tabbed document" to "Tabbed page"?

thank you

Technical Support Jul 19, 2006 - 5:31 AM

Your first question is how to repaint the background of MDI client area window. You can subclass this window and handle WM_PAINT messages. So, first of all, create a CWnd-derived class for handling both WM_PAINT and WM_ERASEBKGND messages:

class CYourMdiClientAreaWnd : public CWnd
{
public:
    CYourMdiClientAreaWnd(){} 
    ~CYourMdiClientAreaWnd(){}
protected:
    virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
    {
        if( message == WM_ERASEBKGND )
            return 1;
 
        if( message == WM_ERASEBKGND )
        {
            CPaintDC dc( this );
            CRect rcClient;
            GetClientRect( &rcClient );
            // this line will draw red background
            // but you should draw your bitmapped background instead
            dc.FillSolidRect( &rcClient, RGB(255,0,0) );
            return 0;
        }
        return CWnd::WindowProc( message, wParam, lParam )
    }
}
Now you should add this window to your CMainFrame class declaration:
    CYourMdiClientAreaWnd m_wndYourMdiClientAreaWnd;
And subclass the MDI client area window with the m_wndYourMdiClientAreaWnd object. You can do this somewhere at the the end of the CMainFrame::OnCreate() method:
    m_wndYourMdiClientAreaWnd.SubclassWindow( GetDlgItem(AFX_IDW_PANE_FIRST) );
Of course, you can modify the built-in menu of dynamic bar site or even re-create it from scratch. Please note this menu always deals with particular control bars. So, you should use your own CExtDynamicControlBar-derived class and implement the CExtDynamicControlBar::OnInitDbsMenu() virtual method. In it, you can invoke the parent class’s method and modify the menu created by default. Please also note:

1) Because of using your own CExtDynamicControlBar-derived class, it should have its own creatable run-time information:
class CYourDynamicBar : public
{
public:
    DECLARE_SERIAL( CYourDynamicBar );
    CYourDynamicBar(){}
    ~CYourDynamicBar(){}
    . . .
};
 
IMPLEMENT SERIAL_SERIAL( CYourDynamicBar . . .
2) You will need to make the CExtDynamicBarSite object using the CYourDynamicBar type instead of the CYourDynamicBar type. So, please use the RUNTIME_CLASS( CYourDynamicBar ) type information explicitly when allocating your dynamic bars:
CYourDynamicBar * pYourBar =
        STATIC_DOWNCAST(
            CYourDynamicBar,
            pDynamicBarSite->BarAlloc(
                _T("bar caption"),
                _cmdIcon,
                nBarID,
                RUNTIME_CLASS( CYourDynamicBar )
                )
            );

Yusuf Abdulkadir Jul 20, 2006 - 12:10 PM

thank you for your reply,

I guess I was not clear on my question. What you have shown, which I have already tried before, paints the CMainFrame client area. What I am trying to do paint CMDIChildWnd client area.

This is what my application looks like,

- I have created an MDI with no doc/view
- I created a child frame as follows

class CTabChildFrame : public CMDIChildWnd, public CExtDynamicBarSite
{
DECLARE_DYNCREATE(CTabChildFrame)
protected:
    CTabChildFrame(); // protected constructor used by dynamic creation
    virtual ~CTabChildFrame();

public:
CDockChildView m_wndView;

protected:
    DECLARE_MESSAGE_MAP()
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
afx_msg void OnSetFocus(CWnd* pOldWnd);
afx_msg void OnFileClose();
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
};

- my child frame’s view is
CDockChildView m_wndView;

which is defined as
class CDockChildView : public CExtTabPageContainerWhidbeyWnd
{
public:
    CDockChildView();
    DECLARE_DYNCREATE( CDockChildView );

// Attributes
public:

// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CDockChildView)
    protected:
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
    //}}AFX_VIRTUAL

// Implementation
public:
    virtual ~CDockChildView();
#ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
#endif

public:

// Generated message map functions
//{{AFX_MSG(CDockChildView)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
};


This works ok, which creates an empty tab window container which a default background color. What I want is to paint a bitmap on the tab container window background so when no tab pages are created or if all tab pages are hidden, it will show the background bitmap. Is this doable? if so what do I need to do to accompish this?

Thank you again for your great support.

Technical Support Jul 21, 2006 - 5:17 AM

Please override the WindowProc() virtual method in the CDockChildView class in the following way:

LRESULT CDockChildView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
 switch( message )
 {
 case WM_PAINT:
  {
   CPaintDC dcPaint( this );
   CExtPaintManager::stat_ExcludeChildAreas(
    dcPaint.GetSafeHdc(),
    GetSafeHwnd()
    );
   CRect rcClient;
   GetClientRect( &rcClient );
   CExtMemoryDC dc(
    &dcPaint,
    &rcClient
    );
 
   // PLACE YOUR PAINTING CODE HERE
  }
  return TRUE;
  
 case WM_ERASEBKGND:
  return FALSE;
  
 } // switch( message )
 
 return CExtTabPageContainerWhidbeyWnd::WindowProc(message, wParam, lParam);
}