Click here to Skip to main content
15,868,016 members
Articles / Desktop Programming / MFC
Article

A Visual Framework (Views, Tabs and Splitters)

Rate me:
Please Sign up or sign in to vote.
4.96/5 (71 votes)
6 Dec 2002 767.3K   17.9K   301   250
Creating SDI/MDI applications with splitter and tab windows
  • Download SDI demo project - 43Kb
  • Download MDI demo project - 43Kb
  • Download source code - 16 Kb

    Visual Fx sample image

    When creating applications with a complex view layout, there are several features that are missing from MFC. First, each type of view layout is created differently (simple view vs. splitter vs. nested splitter). Simple view layout does not need any additional code (MFC handles the creation). Splitter layout needs a CSplitterWnd and manual creation of each pane. Even more complex is the nested splitter. Second, MFC does not support tab windows that can be found in almost any commercial application and is great for better UI orgranization.

    Last year, I read Daniel Harth's article about tabbed views (on CodeGuru) It was not exactly what I needed so I modified it and as a result I had a tab window class that may be within a splitter window and may also contain a splitter window. However, it was not a framework. Creating a user interface was spread throughout the code since (for complex layouts) part of the code was done in OnCreateClient and other parts in one or more tab window derived classes. The Visual Framework presented in this article is a complete redesign.

    Latest update

    14.01.2000 - Frederic Gullet

    Frederic pointed out how to add icons to tab items. Based on his comment to the article, I updated the code and demo projects. Adding icon (16x16 pixels) to tab is optional. If you need it then execute TVisualObject::SetIcon() (see example below and pictures above) Adding icons to visual objects that are not tabs will not produce any errors and will have no effects. Previous function loads the icon from application resource and pass it to the tab window.

    Note: All updates are marked with [NEW] for easier search.

    Introduction

    Visual Framework supports both the SDI and MDI applications with any combination of CView derived classes, CSplitterWnd and TTabWnd derived windows. It is very easy to use. Here is a code snippet that creates the framework shown on picture 1.

    BOOL CSplitterTabFrame::OnCreateClient(LPCREATESTRUCT lpcs, 
                                           CCreateContext *pContext) 
    {
    // m_Framework is a member of CSplitterTabFrame class 
    (derived from CMDIChildWnd)
    // Splitter (1 row, 2 columns). Second column is a tab with 2 panes 
    TVisualObject *pSplitter = new TVisualObject(1, "", 1, 2, pContext);
    TVisualObject *pView1    = new TVisualObject(2, 0,0,pContext, 
                               RUNTIME_CLASS(CDummyTree), CSize(150,0));
    TVisualObject *pTab      = new TVisualObject(3, 0,1,pContext, 
                               RUNTIME_CLASS(TTabWnd), CSize(0,0));
    TVisualObject *pTabView1 = new TVisualObject(4, "Cars",pContext,
                               RUNTIME_CLASS(CDummyList));
    TVisualObject *pTabView2 = new TVisualObject(5, "Fruits", pContext,
                               RUNTIME_CLASS(CDummyTree));
    	
    // Define tab icons [NEW]
    pTabView1->SetIcon(IDI_ICON_A);
    pTabView2->SetIcon(IDI_ICON_A);
    	
    // Add all visual objects to the framework
    m_Framework.Add(pSplitter); 
    m_Framework.Add(pSplitter, pView1); 
    m_Framework.Add(pSplitter, pTab); 
    m_Framework.Add(pTab, pTabView1);
    m_Framework.Add(pTab, pTabView2);
    	
    // Create the framework and all windows
    return m_Framework.Create(this);
    } 

    Here is a list of supported features:

    • Support for both MDI and SDI applications.
    • Any combination of views, miltiple splitter and tab windows.
    • Support for nested splitters.
    • Supports simple CView based applications.
    • Support for hotkey (for example, ALT+3) to select the active pane.
    • Support for Ctrl+Tab to switch tabs.
    • Support for enumeration.
    • Tabs can be either on top or on bottom of the tab window.

    Complete implementation is in 2 files (VisualFx.cpp and VisualFx.h). These files implement the following classes:

    • TVisualFramework class. This class is derived from CCmdTarget. It implements the complete framework.
    • TVisualObject class. This class represents the visual object (view, splitter or tab window).
    • TVisualFrameworkIterator class. This class is designed for enumeration of visual objects in the framework.
    • TTabWnd class. This class is derived from CWnd and represents the tab window.
    • TTabItem class. This class represents one tab within the tab window.
    • TVisualFormView class. Derived from CFormView. It handles the SetFont() and EnableWindow() for form views.

    Terminology

    In order to clear any confusion related to terms used in this article, following picture explains the parts of the typical framework:

    Image 2

     

    Using the Visual Framework

    The Visual Framework is designed to be easy to use. It also offers a consistent interface that is the same no matter what type of application you are creating (simple view, splitter, splitter with nested splitters or more complex with tab windows). As a result, modifying the user interface (view layout) is simple and localized to a single function (OnCreateClient()).

    Once the framework is created, you can perform many tasks (set fonts, change active panes, change active tab, get active pane, get active tab etc) using either the framework object (with a visual object as an argument) or visual object directly (with no arguments).

    Step 1: Creating Visual Objects

    First, you must create TVisualObject objects for each window that you need (using the appropriate constructor). Since TVisualObject class has a private default constructor, objects of this class must be created with new (framework will delete these pointers). Pointers to TVisualObject objects are ideal for access to windows created by the framework. You must not delete these pointers since they are internally used by the framework. For example,

    // Creating a simple view 
    TVisualObject *pView     = new TVisualObject(1,pContext,
                               RUNTIME_CLASS(CDummyList));
    
    // Creating a splitter window with 2 views
    TVisualObject *pSplitter = new TVisualObject(1,"", 1, 2, pContext);
    TVisualObject *pView1    = new TVisualObject(2,0,0,pContext, 
                               RUNTIME_CLASS(CDummyTree), CSize(150,0));
    TVisualObject *pView2    = new TVisualObject(3,0,1,pContext, 
                               RUNTIME_CLASS(CDummyEdit), CSize(0,0));
    
    // Creating a tab window with 2 panes
    TVisualObject *pTab      = new TVisualObject(1,"",pContext,
                               RUNTIME_CLASS(TTabWnd));
    TVisualObject *pTabPane1 = new TVisualObject(2,"Cars",pContext,
                               RUNTIME_CLASS(CDummyList));
    TVisualObject *pTabPane2 = new TVisualObject(3,"Fruits", pContext,
                               RUNTIME_CLASS(CDummyTree));

    Step 2 (optional): Add hotkeys, descriptions and icons

    If you need hotkey support (setting the active pane with key combination like Alt+3) you need to add the following (note that there is no sense to define the hotkey for windows that cannot have the focus -- splitter and tab windows):

    // Define hotkey for panes<br>pTabPane1->SetHotKey('1');
    pTabPane2->SetHotKey('2'); 

    If your application performs enumeration of framework windows, you may also define a description for each window. For example:

    // Define description<br>pTabPane1->SetDescription("Pane with car list");
    pTabPane2->SetDescription("Pane with fruit list");

    [NEW] If you need icons on tabs, then execute the following:

    pTabPane1->SetIcon(IDI_ICON_A);
    where IDI_ICON_A is a 16x16 pixels icon in the application resource.

    Step 3: Declare framework object

    Framework is represented with the TVisualFramework object that is a member of the CFrameWnd derived class. For SDI applications, it is a class derived from CFrameWnd and for MDI applications, it is a class derived from CMDIChildWnd.

    // Framework object<br>TVisualFramework m_Framework;

    Step 4: Add objects to framework

    Once all Visual Objects are created, you have to add them to the Visual Framework. Visual Framework supports only one root Visual Object (view, splitter or tab window). All other Visual Objects are added to the framework by specifying their parent object. Framework will check (in debug version) the validity of the performed operation (for example, you cannot add a tab window to a view). For example,

    m_Framework.Add(pTab);		// Root level object
    m_Framework.Add(pTab, pTabPane1);	// Add first pane to tab
    m_Framework.Add(pTab, pTabPane2);	// Add second pane to tab

    Step 5: Creating the framework

    At last, call the Create method of the framework to actually create the framework and all defined windows. Supplied pointer to parent window must point to a window derived from CFrameWnd. Since the complete framework definition and creation is done from within the OnCreateClient() function in a window derived from either CFrameWnd or CMDIChildWnd (that is derived from CFrameWnd), this pointer should be supplied.

    // Create the framework
    m_Framework.Create(this);

    Once the framework is created, each TVisualObject instance contains a pointer to a created and valid window.

    Step 6: Destroying the framework

    One other important thing to do it the framework destruction. To destroy the framework, call Destroy() member function from within the OnDestroy() function of the CFrameWnd derived window.

    // Destroy the framework
    m_Framework.Destroy();

    Framework cannot be destroyed in the destructor of the TVisualFramework object. In case you forget to call Destroy() as explained above, you will get an ASSERT in debug version of the application.

    Step 7 (optional): Add support for Ctrl+Tab and hotkeys

    If you need the hotkey support (see Step 2), you need to override the CWinApp derived class PreTranslateMessage function and add the following code (this example is for SDI application):

    BOOL CTabWndApp::PreTranslateMessage(MSG* pMsg)
    {
    	CMainFrame *pFrame = (CMainFrame*)::AfxGetMainWnd();
    	if (pFrame)
    	{
    		 if(pFrame->m_Framework.ProcessMessage(pMsg))
    		 	 return TRUE;
    	}
    	
    	return CWinApp::PreTranslateMessage(pMsg);
    } 

    This enables the framework to check each message in the application queue and handle the Ctrl+Tab key combination or hotkeys (Alt+2 for example).

    Implementation

    All data structures in the framework are implemented with STL. STL containers store pointers to objects. Visual object hierarchy in the framework is implemented with list container where each visual object within the container contains another list of child visual objects. This hierarchy is used for creating and destroying objects (windows) using private recursive functions. When creating visual objects, framework scans the hierarchy from top to bottom. On the other hand, framework is scanned from bottom to top during framework destruction.

    Besides the object hierarchy, framework contains a map of all visual objects where a key is a DWORD supplied by the user as a first argument to each TVisualObject constructor. If this key is not unique in the framework, Add() function (see Step 4) will fail (ASSERT in debug version). This key is used for any visual object related operation and also to obtain the pointer to visual object from the framework.

    TTabWnd class implements the tab window. It is derived from CWnd and is intended to be used only as part of the framework. Tab window class contains a list of TTabItem objects. Each TTabItem object represents a tab and contains a pointer to the window associated with the tab (tab pane). Tab caption is a CStatic object. TTabWnd is responsible for updating the frame window when the active tab pane is changed. When changing the active tab pane, TTabWnd will call 2 virtual function with a default implementation: CanSetActivePane() and OnSetActivePane(). Class derived from TTabWnd has a chance to prevent changing the active pane with the first function and a possibility to perform the additional activities in the second function.

    Demo projects

    There is a demo project for SDI and MDI application. SDI application contains the code for several different user interface view layouts. In order to test them, change #define ... at the beginning of OnCreateClient() of the CFrameWnd derived window and rebuild the project. MDI application defines several different templates. Select File | New to create windows with different view layout.

    Class reference

    Classes

    • TVisualObject
    • TVisualFramework
    • TVisualFrameworkIterator
    • TTabWnd

    Member functions

    • TVisualObject
      • TVisualObject
      • TObjectStyle
      • CanFocus
      • SetHotKey
      • SetDescription
      • SetIcon [NEW]
      • SetActivePane
      • SetActiveTab
      • Enable
      • EnableTab
      • ShowTab
      • IsEnabled
      • IsTabEnabled
      • IsTabVisible
      • IsTabPane
      • IsTabWindow
      • IsSplitterPane
      • IsSplitterWindow
      • IsView
      • GetID
      • GetWnd
      • GetSafeWnd
      • GetTitle
      • GetDescription
      • GetParentWnd
      • GetFramework
      • GetOwner
    • TVisualFramework
      • TVisualFramework
      • Add
      • Create
      • Destroy
      • GetWnd
      • GetSafeWnd
      • GetObject
      • Get
      • IsTabPane
      • IsTabWindow
      • IsSplitterPane
      • IsSplitterWindow
      • IsView
      • GetCount
      • GetActiveTab
      • SetActiveTab
      • SetActivePane
      • GetActivePane
      • Enable
      • EnableTab
      • ShowTab
      • IsEnabled
      • IsTabEnabled
      • IsTabVisible
      • SetFont
      • EnableCtrlTab
      • CreateSplitter
      • ProcessMessage
    • TVisualFrameworkIterator
      • TVisualFrameworkIterator
      • operator->
      • Get
      • End
      • operator++
    • TTabWnd
      • HitTest
      • SetActivePane
      • CanSetActivePane
      • OnSetActivePane

       

    Class TVisualObject

    TVisualObject<a name="Func_TVisualObject_TVisualObject"></a>(DWORD dwId, CCreateContext *pContext, CRuntimeClass *pClass)
    TVisualObject(DWORD dwId, LPCTSTR szTitle, CCreateContext *pContext, 
                  CRuntimeClass *pClass, DWORD dwStyle = 0)
    TVisualObject(DWORD dwId, LPCTSTR szTitle, int nRows, 
                  int nCols, CCreateContext *pContext, DWORD dwStyle = 0)
    TVisualObject(DWORD dwId, int nRow, int nCol, CCreateContext *pContext, 
                  CRuntimeClass *pClass, CSize size, DWORD dwStyle =  0)
    TVisualObject(DWORD dwId, int nRow, int nCol, int nRows, int nCols, 
                  CCreateContext *pContext, DWORD dwStyle = 0)

    Constructs the visual object.

    DWORD dwId is the unique ID (user defined) for this visual object.
    CRuntimeClass *pClass is a runtime class of the window associated with this visual object. It may indicate a class derived from CView or from TTabWnd. Class objects derived from CSplitterWnd cannot be created in runtime. Check TVisualFramework::CreateSplitter() virtual function.

    LPCTSTR szTitle is a title of the tab of the parent tab window.
    int nRows, nCols is a number of rows and columns for a splitter window.
    int nRow, nCol is the row and column of the pane within a splitter window.
    CSize size is the initial size of the splitter pane.

    DWORD dwStyle is a bit OR combination of the styles in enum TObjectStyle.

    First constructor creates a plain view. Supplied pClass argument must indicate a class derived from CView.

    Second constructor creates either a tab window or a pane within a tab window depending on the CRuntimeClass pClass argument. If pClass indicates a class derived from TTabWnd then this constructor creates a tab window. If pClass indicates a class derived from CView then this constructor creates a pane within a tab window.

    Third constructor creates a static splitter window. Since CSplitterWnd does not support object creation in runtime, application that need to create a window derived from CSplitterWnd must derive a class from TVisualFramework and overload the virtual function CreateSplitter.

    Fourth constructor creates a pane within a splitter window. pClass must indicate a class derived from either CView or TTabWnd.

    Fifth constructor creates a nested splitter window. It is located in the nRow row and nCol column of the parent splitter window. Since CSplitterWnd does not support object creation in runtime, application that need to create a window derived from CSplitterWnd must derive a class from TVisualFramework and overload the virtual function CreateSplitter.

    enum TObjectStyle <a name="Enum_TVisualObject_TObjectStyle"></a>

    This enum defines styles for the visual object. Default style is no style. Possible styles are:

    • TOS_TABTOP
    • TOS_TABBOTTOM
    • TOS_SELECTED

    TOS_TABTOP is a style valid only for tab window objects. It indicates that the tabs are at the top of the window (above tab panes).

    TOS_TABBOTTOM is a style valid only for tab window objects. It indicates that the tabs are at the bottom of the window (below tab panes).

    TOS_SELECTED is a style valid only for tab panes. It indicates which tab pane of the parent tab window is selected.

    BOOL CanFocus(void)<a name="Func_TVisualObject_CanFocus"></a>

    Returns TRUE if this visual object can be focused (is either a CView or derived from CView). Returns FALSE if this object is derived from either TTabWnd or CSplitterWnd.

    void SetHotKey(CHAR cHotKey)<a name="Func_TVisualObject_SetHotKey"></a>

    Sets the hotkey for this visual object. Defining the hotkey for visual objects that cannot be focused has no sense. Hotkey should be a number since the framework checks hotkeys on WM_SYSKEYDOWN Windows message.

    void SetDescription(LPCTSTR szDesc)

    Optional. This function sets the description for the visual object. Description is not used by the framework but may be used by the application.

    BOOL SetActivePane(void)

    Set the pane represented with this visual object as the active pane in the framework. Return code is FALSE if the visual object cannot be focused (CanFocus() returns FALSE) or if the window represented with this visual object is disabled. Frame window is updated so that CFrameWnd::GetActiveView() returns the window associated with this visual object. Active pane has a keyboard and mouse focus.

    BOOL SetActiveTab(void)

    If the parent of this visual object is a tab window, this function sets the active tab pane of parent tab window to this visual object. The window associated with this visual object is not activated. However, virtual functions TTabWnd::CanSetActivePane() and TTabWnd::OnSetActivePane() are called. Return code is TRUE if the active tab is changed. In any other case, return code is FALSE.

    BOOL Enable(BOOL bEnable)

    Enables or disables the window associated with this visual object depending on the supplied argument. If parent is a tab window then also the tab is enabled/disabled. Disabled tab caption is shown in gray and cannot be selected. Returns FALSE if this visual object is associated with a class not derived from CView.

    BOOL EnableTab(BOOL bEnable)

    Enables or disables the only the tab tab of the parent tab window. Window associated with tab is not modified. The function fails if it is called for a currently active tab/

    BOOL ShowTab(BOOL bShow)

    Show or hide the tab of the parent tab window. If the tab is currently active, application will assert in debug version.

    BOOL IsEnabled(BOOL& bEnabled)

    Returns TRUE if this is a valid operation for this visual object. If the return code is TRUE, then bEnabled indicates whether the window associated with this visual object is enabled.

    BOOL IsTabEnabled(BOOL& bEnabled)

    Returns TRUE if this is a valid operation for this visual object. If the return code is TRUE, then bEnabled indicates whether the tab of the parent tab window is enabled.

    BOOL IsTabVisible(BOOL& bVisible)

    Returns TRUE if this is a valid operation for this visual object. If the return code is TRUE, then bVisible indicates whether the tab of the parent tab window is visible.

    BOOL IsTabPane(void)

    Returns TRUE if the parent of the window associated with this visual object is a tab window.

    BOOL IsTabWindow(void)

    Returns TRUE if the window associated with this visual object is a tab window.

    BOOL IsSplitterPane(void)

    Returns TRUE if the parent of the window associated with this visual object is a splitter window.

    BOOL IsSplitterWindow(void)

    Returns TRUE if the window associated with this visual object is a splitter window.

    BOOL IsView(void)

    Returns TRUE if the window associated with this visual object is a derived from CView.

    DWORD GetID(void)

    Returns unique ID of this visual object.

    CWnd *GetWnd(void)

    Returns a pointer to the window associated with this visual object.

    CWnd *GetSafeWnd(void)

    Returns a safe pointer to the window associated with this visual object. Pointer will be NULL if the window handle is not valid.

    CString GetTitle(void)

    Returns a title of this visual object. Title may be empty for visual objects that are not tabs of the parent tab window.

    CString GetDescription(void)

    Returns a description of this visual object. Description is empty if it is not defined with SetDescription.

    CWnd *GetParentWnd(void)

    Returns a pointer to the parent window of the window associated with this visual object.

    TVisualFramework *GetFramework(void)

    Returns a pointer to the framework. This pointer is defined when the visual object is added to the framework.

    TVisualObject *GetOwner(void)

    Returns a pointer to the parent visual object. It is NULL for a root level visual object.

     

    Class TVisualFramework

    TVisualFramework()

    Constructs the visual framework object. SDI applications must have only one framework object. MDI applications should have one framework object for each MDI child frame.

    BOOL Add(TVisualObject *pObject)<br>
      BOOL Add(TVisualObject *pOwner, TVisualObject *pObject)

    First function adds the supplied visual object to the framework. The supplied visual object is a root level object. If executed more then once, application will assert in debug version. Returns TRUE if the object is added to the framework. Returns FALSE if the object does not have a unique ID.

    Second function adds a visual object (pObject) to its parent (pOwner). This function will check (in debug version) the validity of the object to add. Returns TRUE if the object is added to its parent. Returns FALSE if the object does not have a unique ID.

    virtual BOOL Create(CWnd *pWnd = NULL)

    Creates a framework and all windows in visual object hierarchy. Supplied pointer must not be NULL and must point to a window derived from CFrameWnd. When creating visual object windows, framework scans the visual object hierarchy from top to bottom. After creating all windows, framework will find the first window that can be focused and call SetActivePane().

    virtual void Destroy(void)

    Destroys the framework. Must be called from within the main frame window OnDestroy() function. In case this is not done, application will assert in debug version. Framework is destroyed by scanning the visual object hierarchy from bottom to top. Each CSplitterWnd or TTabWnd derived class is destroyed by calling DestroyWindow(). Views are not destroyed since the applications frame window is responsible for this.

    CWnd *GetWnd(void)

    Returns a pointer to frame window supplied in Create().

    CWnd *GetSafeWnd(void)

    Returns a safe pointer to frame window supplied in Create(). If the window handle is not valid, it returns NULL.

    CWnd *GetObject(DWORD dwId)
    DWORD GetObject(CWnd *pWnd)

    First function returns a window associated with the visual object that has a dwId unique ID.

    Second function returns a unique ID of the visual object associated with the supplied window.

    TVisualObject *Get(DWORD dwId)
    TVisualObject *Get(CWnd *pWnd)

    First function returns a pointer to the visual object that has the specified unique ID. Do not delete this pointer.

    Second function returns a pointer to the visual object that is associated with the specified window. Do not delete this pointer.

    BOOL IsTabPane(TVisualObject *pObject)

    Returns TRUE if the supplied visual object is a tab pane of the parent tab window.

    BOOL IsTabWindow(TVisualObject *pObject)

    Returns TRUE if the supplied visual object is a tab window.

    BOOL IsSplitterPane(TVisualObject *pObject)

    Returns TRUE if the supplied visual object is a splitter pane of the parent splitter window.

    BOOL IsSplitterWindow(TVisualObject *pObject)

    Returns TRUE if the supplied visual object is a splitter window.

    BOOL IsView(TVisualObject *pObject)

    Returns TRUE if the supplied visual object is a view.

    int GetCount(void)

    Returns a count of visual objects in the framework.

    TVisualObject *GetActiveTab(TVisualObject *pObject)

    Returns a pointer to the visual object that represents the currently active tab in the tab window represented with the visual object pObject. If pObject is not a tab window, NULL is returned.

    BOOL SetActiveTab(TVisualObject *pObject)

    Set the active tab represented with pObject of the parent tab window. If pObject parent is not a tab window, FALSE is returned. Active tab does not have the keyboard and mouse focus.

    BOOL SetActivePane(TVisualObject *pObject)

    Set the keyboard and mouse focus to the supplied visual object window. Function will fail with FALSE if the window associated with the supplied pObject visual object cannot be focused or is disabled. Function will update the frame window by calling SetActiveView().

    TVisualObject *GetActivePane(void)

    Returns a pointer to the visual object that represents the currently active pane.

    BOOL Enable(TVisualObject *pObject, BOOL bEnable)

    Enables or disables a view represented with pObject. If pObject is not associated with a view, returned code is FALSE.

    BOOL EnableTab(TVisualObject *pObject, BOOL bEnable)

    Enables or disables the tab associated with pObject. Returns FALSE if pObject parent is not a tab window or if pObject tab is currently active.

    BOOL ShowTab(TVisualObject *pObject, BOOL bEnable)

    Show or hide the tab associated with the pObject. Returns FALSE if pObject parent is not a tab window or if pObject tab is currently active.

    BOOL IsEnabled(TVisualObject *pObject, BOOL& bEnabled)

    Returns TRUE if this operation is valid. In this case, bEnabled indicates whether the visual object window is enabled or disabled.

    BOOL IsTabEnabled(TVisualObject *pObject, BOOL& bEnabled)

    Returns TRUE if this operation is valid (pObject parent is a tab window). In this case, bEnabled indicates whether the visual object window is enabled or disabled.

    BOOL IsTabVisible(TVisualObject *pObject, BOOL& bVisible)

    Returns TRUE if this operation is valid (pObject parent is a tab window). In this case, bVisible indicates whether the visual object window is visible or not.

    void SetFont(CFont *pFont)

    Set the font for all visual objects in the framework. It will also change the font of all tab captions. If visual object hierarchy contains an object derived from TVisualFormView then the font of all form view controls is changed also.

    void EnableCtrlTab(BOOL bEnable)

    If the framework is used in an SDI application, Ctrl+Tab handling is enabled by default. However, MDI applications use Ctrl+Tab to switch among all opened child frames. In this case, Ctrl+Tab handling by the framework is disabled. You can enable it with this function.

    virtual CSplitterWnd *CreateSplitter(DWORD dwId)

    Since CSplitterWnd does not support object creation with CRuntimeClass, this virtual function offers a possibility to return a pointer to CSplitterWnd derived class object. In order to do this, you must derive a class from TVisualFramework and overload this function. Do not call a base class function. Visual object that needs a pointer to CSplitterWnd or CSplitterWnd derived class object is identified with its unique ID dwId.

    virtual BOOL ProcessMessage(MSG *pMsg)

    In order to handle hotkeys and Ctrl+Tab, you must implement a PreTranslateMessage() of the application's CWinApp derived class and call framework's ProcessMessage() function. If this function returns TRUE then it handled the supplied message and CWinApp::PreTranslateMessage() should not be called. See Step 7.

     

    Class TVisualFrameworkIterator

    This class is used for iterating thru the visual objects. Typical use is explained with the following code:

    TVisualFrameworkIterator iterator(m_Framework);
    while (!iterator.End()) 
    {
    	TVisualObject *pObject = iterator.Get();
    	// ...
    	iterator ++;
    }
    TVisualFrameworkIterator(TVisualFramework& obj)
    TVisualFrameworkIterator(TVisualObject& obj)

    Creates an iterator object.

    First constructor creates an iterator that goes thru all visual objects in the framework. This iterator scans the framework's internal visual object map. Sequence of returned visual objects depend on the visual object unique IDs.

    Second constructor creates an iterator that goes thru all visual objects that are child to the specified parent visual object.

    TVisualObject*operator->() 

    Overloaded operator that returns a pointer to visual object.

    TVisualObject *Get(void) 

    Returns a pointer to visual object.

    int End(void) 

    Returns non-zero if there are more visual objects.

    int operator++(int) 

    Overloaded operator to go to the next visual object.

     

    Class TTabWnd

    Since TTabWnd class is intended to be used only as part of the framework, here is the documentation of relevant functions.

    virtual int HitTest(int x, int y)
    virtual int HitTest(CPoint& point)

    Returns an index of the tab that corresponds to the supplied point. Index starts from 0. x, y and point are client coordinates.

    BOOL SetActivePane(int nIndex, BOOL bActivate = TRUE)

    Changes the active tab. Returns TRUE if tab is changed. If bActivate is TRUE, frame window is updated and the tab pane associated with the tab receives mouse and keyboard focus.

    virtual BOOL CanSetActivePane(CWnd *pOldPane, CWnd *pNewPane)

    Derived class has a chance to prevent changing the active tab by returning FALSE from this function.

    virtual void OnSetActivePane(CWnd *pOldPane, CWnd *pNewPane); 

    This function is called after the active pane is changed.

  • License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here


    Written By
    Web Developer SCA d.o.o.
    Serbia Serbia
    I am a cofounder of SCA Software, company that specializes in software for process control, visualization and communication. Programming for the last 10 years in C++, Delphi. Visual C++ for the last 6 years. Degree in Electronics Engineering and Telecommunications.

    Comments and Discussions

     
    QuestionThe dividing window failed. PView41 window did not begin Pin
    tu22m32-Mar-13 22:51
    tu22m32-Mar-13 22:51 
    QuestionProblems when using mfc feature pack Pin
    mrsilver3-Dec-11 13:20
    mrsilver3-Dec-11 13:20 
    QuestionRe: Problems when using mfc feature pack Pin
    PRMARJORAM20-Mar-13 4:46
    PRMARJORAM20-Mar-13 4:46 
    GeneralMy vote of 5 Pin
    bigbigmonkey14-Jul-10 17:07
    bigbigmonkey14-Jul-10 17:07 
    Generalwhy does the framwork can not work in vs2005 Pin
    chenjianquan29-Jan-10 21:06
    chenjianquan29-Jan-10 21:06 
    GeneralRe: why does the framwork can not work in vs2005 Pin
    chenjianquan29-Jan-10 22:00
    chenjianquan29-Jan-10 22:00 
    Questioncan tabs and views be added dynamically? Pin
    i7cppDave13-Dec-09 8:42
    i7cppDave13-Dec-09 8:42 
    AnswerRe: How can I make the tab of vista style? [modified] Pin
    johnsmith2524-May-10 8:04
    johnsmith2524-May-10 8:04 
    QuestionUsing Visual Studio 2008: All Tab labels are empty Pin
    Slauma22-Aug-09 6:49
    Slauma22-Aug-09 6:49 
    AnswerRe: Using Visual Studio 2008: All Tab labels are empty [modified] Pin
    Slauma22-Aug-09 9:49
    Slauma22-Aug-09 9:49 
    GeneralRe: Using Visual Studio 2008: All Tab labels are empty Pin
    yariv_eis20-Sep-09 10:15
    yariv_eis20-Sep-09 10:15 
    GeneralRe: Using Visual Studio 2008: All Tab labels are empty Pin
    Slauma20-Sep-09 11:04
    Slauma20-Sep-09 11:04 
    GeneralRe: Using Visual Studio 2008: All Tab labels are empty Pin
    Slauma20-Sep-09 11:35
    Slauma20-Sep-09 11:35 
    GeneralRe: Using Visual Studio 2008: All Tab labels are empty Pin
    yariv_eis21-Sep-09 3:25
    yariv_eis21-Sep-09 3:25 
    Questionhow to make a static splitter and include button inside ? Pin
    jianhwa29-Jul-09 18:48
    jianhwa29-Jul-09 18:48 
    GeneralFinally found a limitation Pin
    PRMARJORAM17-Jul-09 5:44
    PRMARJORAM17-Jul-09 5:44 
    GeneralThanks for a great piece of code Pin
    PRMARJORAM16-Jun-09 5:07
    PRMARJORAM16-Jun-09 5:07 
    Generalcrash in VS 2005 Pin
    mimosa22-Aug-08 4:29
    mimosa22-Aug-08 4:29 
    GeneralRe: crash in VS 2005 Pin
    Member 84785227-Dec-08 9:30
    Member 84785227-Dec-08 9:30 
    GeneralGreat work, very elegant! Pin
    Sam_Gong29-Jun-08 15:04
    Sam_Gong29-Jun-08 15:04 
    GeneralHelp with splitters and tabs - Please Pin
    BarryHolleran8-May-08 5:50
    BarryHolleran8-May-08 5:50 
    GeneralRe: Help with splitters and tabs - Please Pin
    BarryHolleran8-May-08 6:08
    BarryHolleran8-May-08 6:08 
    QuestionHow to handle Tab changed messages? Pin
    chocm26-Mar-08 16:43
    chocm26-Mar-08 16:43 
    GeneralBugfix for more than one TTabWnd in one SplitterWnd Pin
    zsulc17-Oct-07 3:24
    zsulc17-Oct-07 3:24 
    GeneralRe: Bugfix for more than one TTabWnd in one SplitterWnd Pin
    chenyuntian16-Dec-07 16:24
    chenyuntian16-Dec-07 16:24 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.