Hide

SftTabs/DLL 6.5 - Tab Control

Display
Print

MDI Sample (C++/MFC)

This sample illustrates an MDI application with a tab control to select the active document.

The source code is located at C:\Program Files (x86)\Softelvdm\SftTabs DLL 6.5\Samples\MFC\MDI\MainFrm.cpp or C:\Program Files\Softelvdm\SftTabs DLL 6.5\Samples\MFC\MDI\MainFrm.cpp (on 32-bit Windows versions).

/****************************************************************************/
/* SftTabs/DLL 6.5 - Tab Control for C/C++                                  */
/* Copyright (C) 1994, 2017  Softel vdm, Inc. All Rights Reserved.          */
/****************************************************************************/

#include "stdafx.h"


IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define IDC_MDITAB 200                  // tab control ID

/*- Tab Control Initialization Data --------------------------------------------*/

static const SFTTABS_CONTROL CtlInit = {
    SFTTABSSTYLE_LSQUARE,                /* tab style */
    1,                                   /* number of rows */
    0,                                   /* number of tabs per row (if fFixed) */
    0,                                   /* width of left margin */
    0,                                   /* width of right margin */
    FALSE,                               /* same width for all tabs */
    FALSE,                               /* Client area wanted */
    FALSE,                               /* allow multiline label text */
    TRUE,                                /* use with dialog */
    FALSE,                               /* use specified background color only for text */
    TRUE,                                /* scrollable tabs */
    FALSE,                               /* hide scroll buttons */
    TRUE,                                /* bold font for active tab wanted */
    FALSE,                               /* fill rows completely */
    NULL,                                /* scroll button bitmap */
    NULL,                                /* Dialog data associated with active tab */
    NULL,                                /* Dialog window handle associated with active tab */
    NULL,                                /* Frame, used as client area */
    TRUE,                                /* Tooltips wanted */
    FALSE,                               /* drop text if it doesn't fit */
    FALSE,                               /* conditional scroll buttons */
    BMBUTTONSTYLE_HOVER_BUTTON,          /* scroll button style */
    TRUE,                                /* display ... if truncated */
    TRUE,                                /* Flyby highlighting */
    TRUE,                                /* use client area colors in partially obscured frames */
    FALSE,                               /* scroll buttons on left side */
    0,                                   /* row indentation */
    TRUE,                                /* don't show truncated pattern for clipped tab */
    FALSE,                               /* full size scroll buttons */
    FALSE,                               /* use themes on Windows XP */
    FALSE,                               /* use exact window region */
    FALSE,                               /* always show prefix _ */
    0,0,0,0,                             /* animation values */
    NULL,                                /* disabled button bitmap */
    TRUE,                                /* focus rectangle if the control has i/p focus */
    TRUE,                                /* TRUE if Close button wanted */
    FALSE,                               /* TRUE if Close button disabled */
    FALSE,                               /* TRUE if WM_CLOSE message wanted */
    FALSE,                               /* TRUE if Minimize, Restore, Close buttons are full size */
    SFTTABS_BUTTON_NEAR,                 /* scroll button alignment */
    SFTTABS_BUTTON_NEAR,                 /* Minimize, Restore, Close button alignment */
    FALSE,                               /* TRUE if Minimize button wanted */
    FALSE,                               /* TRUE if Minimize button disabled */
    FALSE,                               /* TRUE if Restore button wanted */
    FALSE,                               /* TRUE if Restore button disabled */
    NULL,                                /* Close, Minimize, Restore button bitmap */
    NULL,                                /* Close, Minimize, Restore disabled button bitmap */
    TEXT("Scroll Left"),                 /* scroll left button tooltip */
    TEXT("Scroll Right"),                /* scroll button tooltip */
    TEXT("Close"),                       /* Close button tooltip */
    TEXT("Minimize"),                    /* Minimize button tooltip */
    TEXT("Restore"),                     /* Restore button tooltip */
    0,                                   /* custom modifications */
    0,                                   /* forced height/width depending on tab style - 0 to ignore */
    FALSE,                               /* switch tabs on button release (or down if FALSE) */
    FALSE,                               /* Rendering compatible with pre-6.0 */
    FALSE,                               /* don't display clientarea border - select styles only */
    SFTTABS_TABS_LEFT,                   /* alignment of tabs on all rows */
    SFTTABS_LAYOUT_DISTRIBUTE,           /* distribution of tabs on rows */
    0, 0,                                /* minimum and maximum number of rows for autoflow layout (none specified) */
    TRUE,                                /* reorderable tabs */
    FALSE,                               /* drag & drop */
};

static const SFTTABS_TAB Tab0 = {   /*&Dummy, not used */
    SFTTABS_NOCOLOR, SFTTABS_NOCOLOR,    /* background, foreground color */
    SFTTABS_NOCOLOR, SFTTABS_NOCOLOR,    /* background, foreground color (when selected) */
    { SFTTABS_GRAPH_NONE, 0 },           /* location */
    TRUE,                                /* enabled/disabled */
    0,                                   /* userdata */
    0,                                   /* reserved */
    NULL,                                /* reserved */
    SFTTABS_NOCOLOR,                     /* Flyby foreground color */
    SFTTABS_NOCOLOR,                     /* Client area background color */
    0,0,0,0,                             /* animation values */
    NULL,                                /* tab-specific ImageList handle*/
    FALSE,                               /* hidden tab */
    SFTTABS_NOCOLOR,                     /* gradient fill background color */
    SFTTABS_NOCOLOR, 
    SFTTABS_NOCOLOR,                     /* gradient fill background color, active tab */
    SFTTABS_NOCOLOR, 
    SFTTABS_NOCOLOR,                     /* gradient fill client area color */
    SFTTABS_NOCOLOR, 
    0,0,0,                         /* TabPicture, TabPictureDisabled and TabPictureHot */
    TRUE,                                /* has tab close button */
    0,0,0,0,0,                   /* gap2, TabPicture2, TabPicture2Active, TabPicture2Disabled, TabPicture2Hot */
};

/////////////////////////////////////////////////////////////////////////////
// CMainFrame

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
    //{{AFX_MSG_MAP(CMainFrame)
    ON_WM_CREATE()
    ON_WM_DESTROY()
    //}}AFX_MSG_MAP
    ON_SFTTABSN_SWITCHED(IDC_MDITAB, OnTabSwitched)
    ON_SFTTABSN_CLOSEBUTTON(IDC_MDITAB, OnCloseClicked)
    ON_SFTTABSN_LBUTTONDOWN_IMAGE2(IDC_MDITAB, OnTabCloseClicked)
    ON_SFTTABSN_DRAGDROP(IDC_MDITAB, OnTabsReordered)
END_MESSAGE_MAP()

static UINT indicators[] =
{
    ID_SEPARATOR,           // status line indicator
    ID_INDICATOR_CAPS,
    ID_INDICATOR_NUM,
    ID_INDICATOR_SCRL,
};

// toolbar buttons - IDs are command buttons
static UINT BASED_CODE buttons[] =
{
    // same order as in the bitmap 'toolbar.bmp'
    ID_FILE_NEW,
    ID_FILE_OPEN,
    ID_FILE_SAVE,
        ID_SEPARATOR,
    ID_EDIT_CUT,
    ID_EDIT_COPY,
    ID_EDIT_PASTE,
        ID_SEPARATOR,
    ID_FILE_PRINT_PREVIEW,
    ID_FILE_PRINT,
        ID_SEPARATOR,
    ID_APP_ABOUT,
};

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
    HDC hDC = ::GetDC(NULL);             // Get a device context
    int height = MulDiv(10, ::GetDeviceCaps(hDC, LOGPIXELSY), 72);
                                         /* Convert point-size to pixels */
    m_Font.CreateFont(-height, 0, 0, 0, FW_NORMAL, 0, 0, 0, 0, 0, 0, 0, 0, _T("Arial"));
    ::ReleaseDC(NULL, hDC);              // Release device context
}

CMainFrame::~CMainFrame()
{
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    
    if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
        | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
        !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
    {
        TRACE0("Failed to create toolbar\n");
        return -1;      // fail to create
    }
    if (!m_wndStatusBar.Create(this) ||
        !m_wndStatusBar.SetIndicators(indicators,
          sizeof(indicators)/sizeof(UINT)))
    {
        TRACE0("Failed to create status bar\n");
        return -1;      // fail to create
    }

    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    EnableDocking(CBRS_ALIGN_ANY);
    DockControlBar(&m_wndToolBar);
    
    if (!m_MDITab.Create(
        WS_VISIBLE | WS_CHILD |          // Visible, child window
            WS_CLIPCHILDREN | WS_TABSTOP | // Clip child windows, tabstop
            WS_GROUP,                    // Group
        CRect(0, 200, 200, 220),          // Location
        this,                             // Parent window
        IDC_MDITAB)) {                     // tab control ID
        TRACE0("Failed to create tab control\n");
        return -1;      // fail to create
    }

    /* Initialization is faster if we set redraw off */
    m_MDITab.SetRedraw(FALSE);

    m_MDITab.SetFont(&m_Font, FALSE);   // Set tab control font

    /* We are using new features */
    m_MDITab.SetVersion(SFTTABS_6_5);

    m_MDITab.SetControlInfo(&CtlInit);

    m_MDITab.SetAllowAllInactive(TRUE);  // Allow all tabs to become inactive

    // Make sure to turn redraw back on
    m_MDITab.SetRedraw(TRUE);
    m_MDITab.InvalidateRect(NULL, TRUE);

    // Mark the view as a main, tabbed window (so accel. keys work) by registering it.
    SftTabs_RegisterWindow(m_hWnd);

    return 0;
}

void CMainFrame::AddTab(CChildFrame *pChildFrame)
{
    int index;

    // check if already added
    int total = m_MDITab.GetCount();
    for (index = 0 ; index < total ; ++index) {
        SFTTABS_TAB Tab;
        m_MDITab.GetTabInfo(index, &Tab);
        if (Tab.userData == (SFTTABS_DWORD_PTR)(LPVOID) pChildFrame) {
            m_MDITab.SetCurrentTab(index);
            return; // already added
        }
    }

    // New, add the window title as tab title
    CString str;
    pChildFrame->GetWindowText(str);
    index = m_MDITab.AddTab(str);
    ASSERT(index >= 0);

    // get the document name and add it as a tooltip
    CDocument* pDoc = pChildFrame->GetActiveDocument();
    if (pDoc) {
        str = pDoc->GetPathName();
        if (str == _T(""))
            str = _T("New document, no file name available");
        m_MDITab.SetToolTip(index, str);
    }

    // Save a pointer to the frame window object as userdata
    SFTTABS_TAB Tab;
    m_MDITab.GetTabInfo(index, &Tab);
    Tab.userData = (SFTTABS_DWORD_PTR)(LPVOID) pChildFrame;
    Tab.fHasCloseButton = TRUE;
    m_MDITab.SetTabInfo(index, &Tab);

    // make it the current tab
    m_MDITab.SetCurrentTab(index);
}

void CMainFrame::RemoveTab(CChildFrame *pChildFrame)
{
    int index;

    // check if already added
    int iTab = m_MDITab.GetCurrentTab();

    int total = m_MDITab.GetCount();
    for (index = 0 ; index < total ; ++index) {
        SFTTABS_TAB Tab;
        m_MDITab.GetTabInfo(index, &Tab);
        if (Tab.userData == (SFTTABS_DWORD_PTR)(LPVOID) pChildFrame) {
            m_MDITab.DeleteTab(index);
            // adjust current tab if necessary
            if (iTab > index) {
                m_MDITab.SetCurrentTab(iTab-1);
            } else if (iTab == index) {
                m_MDITab.SetCurrentTab(-1);
            }
            return;
        }
    }
}

void CMainFrame::OnSetPreviewMode(BOOL bPreview, CPrintPreviewState* pState) 
{
    // We don't want to see the tab control in Print Preview mode
    m_MDITab.ShowWindow(bPreview ? SW_HIDE : SW_SHOW);  
    CMDIFrameWnd::OnSetPreviewMode(bPreview, pState);
}

void CMainFrame::OnTabSwitched()
{
    // A new tab is active
    // Get the current tab
    int index = m_MDITab.GetCurrentTab();
    if (index < 0)
        return;

    // retrieve child window
    SFTTABS_TAB Tab;
    m_MDITab.GetTabInfo(index, &Tab);
    CChildFrame* pChildFrame = (CChildFrame*) Tab.userData;

    // Activate the MDI child window
    MDIActivate(pChildFrame);
}

void CMainFrame::OnCloseClicked()
{
    // Get the current tab
    int index = m_MDITab.GetCurrentTab();
    if (index < 0)
        return;

    // retrieve child window
    SFTTABS_TAB Tab;
    m_MDITab.GetTabInfo(index, &Tab);
    CChildFrame* pChildFrame = (CChildFrame*) Tab.userData;

    // select next window (so we have a new active tab)
    MDINext();

    // Destroy the MDI child window
    pChildFrame->DestroyWindow();
}

void CMainFrame::OnTabCloseClicked()
{
    // Get the tab whose tab close button was clicked (this is not necessarily the active tab)
    int index = m_MDITab.GetNextTab();
    if (index < 0)
        return;

    // retrieve child window
    SFTTABS_TAB Tab;
    m_MDITab.GetTabInfo(index, &Tab);
    CChildFrame* pChildFrame = (CChildFrame*) Tab.userData;

    // select next window (so we have a new active tab)
    if (index == m_MDITab.GetCurrentTab())
        MDINext();

    // Destroy the MDI child window
    pChildFrame->DestroyWindow();
}

void CMainFrame::OnTabsReordered()
{
    SFTTABS_DRAGINFO dragInfo;
    m_MDITab.GetDragInfo(&dragInfo);
    if (dragInfo.targetAllowed)
        m_MDITab.MoveTab(dragInfo.reorderTab, dragInfo.targetTab);
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    if( !CMDIFrameWnd::PreCreateWindow(cs) )
        return FALSE;
    return TRUE;
}

void CMainFrame::OnDestroy() 
{
    // Unregister, or the window properties used won't be removed
    SftTabs_UnregisterWindow(m_hWnd);

    CMDIFrameWnd::OnDestroy();
}

/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
    CMDIFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
    CMDIFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

Last Updated 08/13/2020 - (email)
© 2024 Softel vdm, Inc.