Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

The Ultimate Toolbox Graphical User Interface Classes

0.00/5 (No votes)
25 Aug 2007 1  
The Ultimate Toolbox GUI classes offer a wide range of MFC control extensions.

Visit the Ultimate Toolbox main page for an overview and configuration guide to the Ultimate Toolbox library.

Contents

Introduction

The Graphical User Interface classes have been among the most popular MFC extensions available in the Ultimate Toolbox library.

Background Painter

The COXBackgroundPainter class is designed to simplify the process of window background painting. This class hooks the underlying WindowProc of the attached window and implements WM_ERASEBKGND processing:

int CBackgroundPainterView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if (CView::OnCreate(lpCreateStruct) == -1)
        return -1;
    ((CMainFrame*)AfxGetMainWnd())->GetPainter()->Attach(
        this,IDB_WALLPAPER);        // IDB_WALLPAPER specifies the bitmap 


                                    // resource to use


    return 0;
}

Bitmap Enhanced Controls

COXRoundedButton is derived from COXBitMapButton, and can be shaped and shaded to add a bit of splash to your app:

    m_btnRound.SetAmbientCoef(m_fAmbient/10,FALSE);
    m_btnRound.SetDiffuseCoef(m_fDiffuse/10,FALSE);
    m_btnRound.SetLightIntensityCoef(m_fLightIntensityCoef/10,FALSE);
    m_btnRound.SetMirrorCoef(m_fMirror/10,FALSE);
    m_btnRound.SetPhi(m_fPhi,FALSE);
    m_btnRound.SetPhong(m_nPhong,FALSE);
    m_btnRound.SetSphereExternalRadius(m_nSphereExtRadius,FALSE);
    m_btnRound.SetSphereInternalRadius(m_nSphereIntRadius,FALSE);
    m_btnRound.SetThetta(m_fThetta,FALSE);
    m_btnRound.SetButtonColor(m_clrButton,FALSE);
    m_btnRound.SetLightColor(m_clrLight,FALSE);

    m_btnRound.RedrawWindow();

COXColorPickerButton, and COXFontPickerButton are derived from COXBitMapButton as well.

The Font Pickers article shows the use of a bitmap button in in the COXFontPickerButton class.

Calculator

COXCalculatorPopup and COXCalculatorEdit provide a quick and easy way to add a calculator facility to your app.

void CCalculatorCtrlDlg::OnBnClickedCalculator()
{
    UpdateData();

    CRect rc;
    GetDlgItem(IDC_BUTTON_CALCULATOR)->GetWindowRect(&rc);
    
    if (m_calc.Pick(m_fValue, ID_OXCALCULATOR_ALIGNBOTTOM, rc))
    {
        // OK was pressed


        m_fValue = m_calc.GetCalculatorCtrl()->GetResult();
        UpdateData(FALSE);
    }
}

Caption (Title Bar) Customization

COXCaptionPainter provides gradient and text options for Windows title bars.

     // Install caption painter


     m_Caption.Attach(this);
     COXCaptionInfo* pCI=m_Caption.GetCaptionInfo(TRUE);
     pCI->SetBackgroundColor(RGB(128,255,255));
     pCI=m_Caption.GetCaptionInfo(FALSE);
     pCI->SetBackgroundColor(RGB(255,255,128));
     SendMessage(WM_NCPAINT);

Color Picker

A customized color picker control.

See the Color Picker article for more information on COXColorPickerCtrl and COXColorPickerButton.

Combo Boxes

CComboBox based controls

COXHistoryCombo and COXMultiComboBox are CComboBox derived controls.

COXHistoryCombo can track a history of previously entered values.


The samples\gui\HistCombo sample in action.

The COXMultiComboBox defines a combo with a multiple column list. More info on COXMultiComboBox can be found here.

Templated Combo Box Controls

The Ultimate Toolbox also provides for the creation of customized combo boxes through the use of COXBaseSubclassedComboBox, which allows for the specification of the combo, list and edit classes to be used in the resulting control. COXFontComboBox is an example of this usage, which combines an MFC CComboBox with a COXFontListBoxHelper and a standard CEdit in specifying the control.

COXBaseSubclassedComboBox is a templated class declaration taking these components as parameters:

template<class PARENTCOMBOBOX, class PARENTLISTBOX, class PARENTEDIT>
class OX_CLASS_DECL COXBaseSubclassedComboBox : public PARENTCOMBOBOX { ... }

So, for example, you could create a CHistoryMaskedComboBox combining the functionality of the COXHistoryCombo and a COXMaskedEdit in the same control thuswise:

class CHistoryMaskedComboBox :
public COXBaseSubclassedComboBox<COXHistoryCombo, CListBox, 
    COXMaskedEdit> { ... }

The COXFontComboBox described in the Font Picker article is a COXBaseSubclassedComboBox based class.

Context Sensitive Help

The COXContextHelpDialog, COXContextHelpPropertyPage, and COXContextHelpPropertySheet classes provide context sensitive help and tooltip support for all child controls.

The COXContextHelpDialog and COXContextHelpPropertyPage classes provide context sensitive help and tooltip support for all child controls. Classes derived from COXContextHelpDialog or COXContextHelpPropertySheet have a small question mark in the upper right-hand corner of the their caption bars. The user can either press this question mark icon and then click and item for help or press F1 on the child control (when it has the input focus) to get help on an item.COXContextHelpPropertySheet.

To enable context-sensitive help in your application's dialogs, property pages and property sheets, you must derive your classes from COXContextHelpDialogCOXContextHelpPropertyPage and COXContextHelpPropertySheetinstead of CDialogCPropertyPage, and CPropertySheet respectively. Also, you must override the GetHelpIDs pure virtual function to return a pointer to an array of help IDs that correspond to child controls in the window. Moreover, you should override the AdjustToolTips virtual member function to provide the embedded tooltip control with information about each child control.

    static const DWORD m_nHelpIDs[];
    virtual const DWORD* GetHelpIDs() {return m_nHelpIDs;}
const DWORD CTest2Page::m_nHelpIDs[] = 
{
    IDC_TESTCHECK1,   IDH_TESTCHECK1,
    IDC_TESTCOMBO1,   IDH_TESTCOMBO1,
    IDC_TESTBUTTON2,  IDH_TESTBUTTON2,
    IDC_LIST1,        IDH_LIST1,
    IDC_SCROLLBAR1,   IDH_SCROLLBAR1,
    IDD_COLOR,        IDH_COLOR,
    0, 0
};
/////////////////////////////////////////////////////////////////////////////


// CTest2Page message handlers



BOOL CTest2Page::AdjustToolTips() 
{
    //Set up the Tooltip


    BOOL rt = m_Tooltip.AddTool(&m_scroll1, _T("A Scroll Bar"));
    ASSERT(rt != 0) ;
    rt = m_Tooltip.AddTool(&m_combo1, _T("A Combo Box"));
    ASSERT(rt != 0) ;
    rt = m_Tooltip.AddTool(&m_check1, _T("A Check Box"));
    ASSERT(rt != 0) ;
    rt = m_Tooltip.AddTool(&m_button2, _T("A Button"));
    ASSERT(rt != 0) ;
    rt = m_Tooltip.AddTool(&m_list, _T("A List Box"));
    ASSERT(rt != 0) ;

    return rt;
}

Cool Controls

Various controls can be given the 'cool' look with the COXCoolCtrl template class.


Cool toolbars...


Cool combos...


More cool stuff...

Implementing cool controls in your application is as easy as subclassing MFC member variables, and you can elect to apply the template to existing controls or use some of the Ultimate Toolbox's built in implementations:

// Dialog Data


     //{{AFX_DATA(CPropertyPageListTree)


     enum { IDD = IDD_DIALOG_LISTTREE };
     COXCoolCtrl<CTreeCtrl> m_tree;
     COXCoolCtrl<CListCtrl> m_list;
     COXCoolCtrl<CListBox> m_listbox;
     COXCoolButton m_btnDisable;
     COXCoolCtrl<CHotKeyCtrl> m_hotKey;
     COXCoolSpinButtonCtrl m_spinUnattached;
     COXCoolSpinButtonCtrl m_spinRight;
     COXCoolSpinButtonCtrl m_spinLeft;
     COXCoolCtrl<CRichEditCtrl> m_richeditMultiline;
     COXCoolCtrl<CEdit> m_editSpinUnattached;
     COXCoolCtrl<CEdit> m_editSpinRight;
     COXCoolCtrl<CEdit> m_editSpinLeft;
     COXCoolCtrl<CEdit> m_editPlain;
     COXCoolCtrl<COXEdit> m_editExtended;
     COXCoolCtrl<COXNumericEdit> m_editNumeric;
     COXCoolCtrl<CEdit> m_editMultiline;
     COXCoolCtrl<COXMaskedEdit> m_editMasked;
     COXCoolCtrl<COXCurrencyEdit> m_editCurrency;
     COXCoolButton m_btnDisable;

DateTime Controls

COXCalendar, COXDateTimeControl, and COXMonthCalControl.

See the Date Time Picker article for more on these classes and their usage.

Directory Picker

COXBrowseDirEdit16 and COXBrowseDirEdit offer drop down edit controls featuring a directory browser.

Drag and Drop

COXSHBDropSource and COXSHBDropTarget provide handling of OLE drag/drop operations in any window.

The 'SHB' in the name of these classes stems from the fact that it was originally intended to be used with a short cut bar, specifically the COXSHBListControl and COXShortcutBar classes - its usage has since been extended to apply to any window.

For more on these classes, please see the overviews in the Graphical User Interface | Drag and Drop section of the compiled HTML help documentation.

Edit Controls

Dropdown and various specific masked edit classes.


Extended edit controls...

More information can be found in the Edit Extensions, Physical Unit Edit Classes, and Masked Edit articles.

File Picker

COXBrowseFileEdit implements a dropdown edit control featuring a file browser.

File Preview Dialog

The COXFileViewer class allows COXPreviewDialog to organize the previewing process in a generic way. The COXPreviewDialog class is required to provide the functionality for previewing as many standard file types as possible while giving the flexibility of previewing only designated file types (e.g. only image files or only text files) and allowing a programmer to easily update the functionality of the class in order to preview proprietary file types.

COXPreviewDialog and COXBmpFileDialog allow for thumbnail type previews of bmp and jpeg files.

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


// CDIBManagerApp commands


CFileDialog* CDIBManagerApp::NewFileDialog(BOOL bOpenFileDialog, DWORD lFlags)
{
    // we provide functionality to open more than one file simultenuosly


    lFlags|=OFN_ALLOWMULTISELECT;
    // create the dialog with Preview capability


    return new COXPreviewDialog(bOpenFileDialog,NULL,NULL,
        OFN_ALLOWMULTISELECT|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|
        OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT);
}

History/Output Log

The COXHistoryCtrl class is a COXScrollWnd based class which is designed to provide facilities to display and save log info (history info).

protected:
    COXTabViewPage<coxhistoryctrl /> m_build;
    COXTabViewPage<coxhistoryctrl /> m_debug;
    COXTabViewPage<coxhistoryctrl /> m_find1;
    COXTabViewPage<coxhistoryctrl /> m_find2;
    COXTabViewPage<coxhistoryctrl /> m_results;
    COXTabViewPage<coxhistoryctrl /> m_SQLdebug;

    // build page


    if(!m_build.Create(NULL,NULL,WS_CHILD,CRect(0,0,0,0),
        &m_TabViewContainer,1))
        return -1;
    m_TabViewContainer.AddPage(&m_build,_T("Build"));

    m_build.AddLine(_T("Generating Code..."));
    m_build.AddLine(_T("Linking..."));
    m_build.AddLine(_T(""));
    m_build.SetTextColor(RGB(255,0,0));
    m_build.AddLine(_T("VisualStudioLikeDemo.exe - 0 error(s), 
        0 warning(s)"));

HyperBar

New in version 9.3, the hyperbar control is an MFC control, derived principally from CToolbar, which can be added to any project and which will give the floating toolbar look seen in the Microsoft Expression 'Hyperbar' sample.

See the HyperBar article for more on using this class in your application.

List Controls

COXGridList, COXEditList, COXImageListBox, COXListBoxEx, and COXFontList MFC extensions.

See the Extended List Box article for more on these classes.

Layout Manager

COXLayoutManager can be attached to a container window to manage the layout of its child windows.

    m_LayoutManager.TieChild(IDC_OX_GROUP_PAINT_TYPE,
        OX_LMS_LEFT|OX_LMS_RIGHT,OX_LMT_SAME);
    m_LayoutManager.TieChild(IDC_OX_ALIGN_STRETCH,OX_LMS_RIGHT,OX_LMT_SAME);
    m_LayoutManager.TieChild(IDC_OX_ALIGN_TOPRIGHT,OX_LMS_RIGHT,OX_LMT_SAME);
    m_LayoutManager.TieChild(IDC_OX_ALIGN_CENTERRIGHT,OX_LMS_RIGHT,
        OX_LMT_SAME);
    m_LayoutManager.TieChild(IDC_OX_ALIGN_BOTTOMRIGHT,OX_LMS_RIGHT,
        OX_LMT_SAME);

See the Layout Manager article for more on structure and usage of this class.

Menu

COXBitmapMenu and COXBitmapMenuOrganizer allow for bitmap enhanced menu items.

    // Let the menu organizer fix our menus


    Organizer.AttachFrameWnd(this);
    // Set images from toolbar to use with corresponding menu items


    Organizer.AutoSetMenuImage();
    // explicitly designate images to use with menu items


    Organizer.SetMenuBitmap(ID_TEST_PAGE, MAKEINTRESOURCE(IDB_PAGE));
    Organizer.SetMenuBitmap(ID_TEST_HELLO, MAKEINTRESOURCE(IDB_HELLO));
    Organizer.SetMenuBitmap(ID_TEST_MARKEDPAGE, MAKEINTRESOURCE(
        IDB_MARKEDPAGE));
    Organizer.SetMenuBitmap(ID_TEST_DISABLED, MAKEINTRESOURCE(IDB_EXPLORE));
    Organizer.SetMenuBitmap(ID_TEST_ENABLED, MAKEINTRESOURCE(IDB_EXPLORE));

Menu Bar

COXMenuBarFrame, COXMenuDockBar and COXMenuBar provide a framework of classes that support dockable menu bars.


Dockable menu bars in action in the samples\advanced\VisualStudioLikeDemo project.

To automagically enable these menu bars in your application, simply derive your main frame window from COXMenuBarFrame:

class CMainFrame : public COXMenuBarFrame<CFrameWnd,CDockBar>

or

class CMainFrame : public COXMenuBarFrame<CMDIFrameWnd,CDockBar>

Popup Bar

COXPopupBarCtrl is a generic class designed specifically as a base class to provide basic functionality of any Popup Bar control.


The samples\gui\popupbar sample in action.

The Popup Bar control is a top most popup window with items on it that can be chosen using the mouse or keyboard. For example, standard Popup Menu Bar or Color Picker from Word 97 are Popup Bar controls. Below is one example of how our Popup Bar can be graphically represented:

  • "Default" button. Always located on the top. The size of this button is calculated automatically.
  • "Common" buttons. You can set the number of common buttons and their sizes. You can also set the number of rows used to display them.
  • "Custom" button. Always located at the bottom. The size of this button is calculated automatically.

On display, the Popup Bar control captures all mouse messages and hides itself if any mouse button is clicked or the user presses ESC, ENTER or SPACE buttons. If, when clicked the mouse wasn't over any button within the Popup Bar, or the user pressed ESC, then nothing is chosen and the Pick function returns FALSE.

In this handler for the toolbar's TBN_DROPDOWN notification, the specific popup is displayed through a call to the Pick method:

void CMainFrame::OnDropDownCustomizeToolbar(NMHDR* pNotifyStruct, 
    LRESULT* pResult)
{
    CFrameWnd* pFrame=GetActiveFrame();
    ASSERT(pFrame);
    CPopupBarDoc* pDoc = (CPopupBarDoc*)pFrame->GetActiveDocument();
    ASSERT(pDoc);
    ASSERT_VALID(pDoc);

    // this function handles the dropdown menus from the toolbar


    NMTOOLBAR* pNMToolBar = (NMTOOLBAR*)pNotifyStruct;
    CRect rect;

    COXCoolToolBar* pToolBar=GetCustomizeToolBar();

    // translate the current toolbar item rectangle into screen coordinates


    // so that we'll know where to pop up the menu


    pToolBar->GetItemRect(pToolBar->CommandToIndex(
        pNMToolBar->iItem), &rect);
    ::ClientToScreen(pNMToolBar->hdr.hwndFrom, &rect.TopLeft());
    ::ClientToScreen(pNMToolBar->hdr.hwndFrom, &rect.BottomRight());

    COLORREF clr;
    COXColorPickerCtrl colorPicker;
    switch(pNMToolBar->iItem)
    {
    case ID_CUSTOMIZE_TEXT_COLOR:
        {
            if(::IsWindow(colorPicker.m_hWnd) || colorPicker.Create(pToolBar))
            {
                clr=pDoc->GetTextColor();
                colorPicker.SetSelectedColor(clr);
                colorPicker.SetDefaultColor(pDoc->GetDefaultTextColor());
                if(colorPicker.Pick(ID_POPUPBAR_ALIGNBOTTOM,&rect))
                {
                    clr=colorPicker.GetSelectedColor();
                    pDoc->SetTextColor(clr);
                }
            }
            break;
        }
    case ID_CUSTOMIZE_FILL_COLOR:
     ...
    case ID_CUSTOMIZE_BORDER_COLOR:
     ...
    case ID_CUSTOMIZE_BORDER_STYLE:
     ...
    case ID_CUSTOMIZE_LINE_STYLE:
     ...
    case ID_CUSTOMIZE_DASH_STYLE:
    }
    pToolBar->InvalidateRect(rect);

    pDoc->UpdateAllViews(NULL);

    *pResult = TBDDRET_DEFAULT; 
}

See the COXPopupBarCtrl class reference for more on the creation and usage of this class.

Rollup Windows

The COXRollup& classes work together to bring the magic of rollup windows to your MFC application.COXTitleBar

The samples\gui\rollup sample derives CMaxVirtDialog from COXRollup:

void CRoll32View::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
    UNREFERENCED_PARAMETER(nFlags);
    CMaxVirtDialog *pMaxVirt = new CMaxVirtDialog(this);
    
    TCHAR achBuffer[64];
    UTBStr::stprintf(achBuffer, 64,_T("MVT: %ld"),::GetTickCount());

    pMaxVirt->CreateRollUp(this,15,achBuffer);
    ClientToScreen(&point);
    pMaxVirt->SetWindowPos(
        NULL,point.x,point.y,0,0,SWP_NOZORDER|SWP_NOSIZE);
    pMaxVirt->ShowWindow(SW_SHOWNORMAL);

    // if you�re searching for the delete, see maxvirtd.cpp PostNcDestroy


    // and OnCloseRollup


}

Ruler Bar

COXRulerBar and COXRulerBarOrganizer allow for the display of horizontal and/or vertical ruler bars in any window.

The samples\graphics\ImageViewer sample shows the ruler bar classes in action, through the COXScrollWnd class:

#ifdef OXSCRLWND_USE_RULER
    // --- In  :    bHorzRuler    -  horizontal ruler band will be displayed


    //              bVertRuler    -  vertical ruler band will be displayed


    // --- Out : 


    // --- Returns: TRUE if COXRulerOrganizer object was successfully 


    //              attached


    // --- Effect:  attaches to COXRulerOrganizer object which is 


    //              responsible for displaying ruler bars


    inline BOOL AttachRuler(BOOL bHorzRuler=TRUE, BOOL bVertRuler=TRUE) { 
        if(m_ruler.IsAttached())
        {
            SetShowHorzRulerBar(bHorzRuler);
            SetShowVertRulerBar(bVertRuler);
            return TRUE;
        }
        return m_ruler.Attach(this,bHorzRuler,bVertRuler);
    }

Scrolling and Scaling Windows

COXScrollWnd and COXZoomView provide scrolling and scaling functionality.


The DIBManager sample implements a COXZoomView derived CDIBManagerView view.

COXZoomView features:

  • Handles MM_ANISOTROPIC.

  • Scrollsizes now definable in percent of the client area, updated on resizing.

  • ScrollToPosition allows the anchor to be the upper left corner, or additionally the lower left corner or the center of the window.

  • Accepts a CRect for the document size, so the origin can be located in the lower left corner or the center or any arbitrary point of the document. You don't need to handle negative y-coords any more !

  • Zoom level can vary between 10% and 1000%

  • When zooming, either keeps the upper left window corner, the lower left window corner or keeps the center.

  • Allows zooming up to a rectangle ( in client coords ).

  • After zooming, the rectangle can be justified to either the upper left or lower left corner or to the window center.

  • Allows zooming to the window size (so the scrollbars just disappear).

  • Output can be aligned to the bottom of the view, when the view's height is bigger than the document's.
void CDIBManagerView::OnViewZoomIn() 
{
    // TODO: Add your command handler code here



    // up current zoom level on 100% if it is more than 100% already


    // or on 10% otherwise


    int nZoomLevel=GetZoomLevel();
    if(nZoomLevel"code-string" nmargin="<span" />"nZoomLevel" />=100 ? 100 : 10;
        nZoomLevel+=nMargin;
        SetZoomLevel(nZoomLevel);
        if(GetZoomLevel()>ID_MAX_ZOOM_LEVEL)
        {
            SetZoomLevel(ID_MAX_ZOOM_LEVEL);
        }
        // if roll-up ZoomLevel dialog is active then


        // notify it that current zoom level is changed


        NotifyZoomChanged();
    }
}

The COXImageViewer class is derived from COXScrollWnd, shown here in action in the samples\graphics\imageviewer example.

COXScrollWnd features mirror some of the features of COXZoomView. COXScrollWnd is a virtual base class designed to provide basic scrolling and scaling functionality.

  • Supports MM_ANISOTROPIC mapping mode.

  • Scroll sizes can be defined in percent of the client area

  • ScrollToPosition() allows the anchor to be the upper left corner, or additionally the lower left corner or the center of the window.

  • Accepts a CRect for the contents size, so the origin can be located in the lower left corner or the center or any arbitrary point of the control.

  • You don't need to handle negative y-coords

  • Zoom level can vary between 10% and 1000%

  • When zooming, either keeps the upper left window corner, the lower left window corner or keeps the center.

  • Allows zooming up to a rectangle (in client coords).

  • After zooming, the rectangle can be justified to either the upper left or lower left corner or to the window center.

  • Allows zooming to the window size (so the scrollbars just disappear).

  • Output can be aligned vertically and horizontally.

  • Supports smooth scrolling which means that the process of scrolling of the contents from one position to another is divided in a number of smaller scrolling processes

  • Supports 'Always fit to window' option that if set will scale the contents of the control to its size whenever it is resized

  • Context menu can be displayed that allows a user easily set most used zoom levels

  • Track zooming option is supported which means that when a user left clicks and drag the mouse cursor the tracker will be displayed so a user can choose the rectangle to which the contents must be zoomed

  • Scrolling using mouse wheel is supported

  • Optional support for ruler bars (using the COXRulerBarOrganizer class)

See the compiled HTML help documentation for complete class references for COXZoomView and COXScrollWnd.

Separator

COXSeparator is a simple control that placed in the right position in a dialog or form view can greatly improve the way your applications look.

    // setup vertically oriented separators


    static CFont fontVertEnabled;
    VERIFY(fontVertEnabled.CreatePointFont(120,_T("Times New Roman")));
    m_ctlSepVertRight.SetVertOriented();
    m_ctlSepVertRight.SetFont(&fontVertEnabled);
    m_ctlSepVertPlain.SetVertOriented();
    m_ctlSepVertLeft.SetVertOriented();
    m_ctlSepVertLeft.SetFont(&fontVertEnabled);
    m_ctlSepVertCenter.SetVertOriented();
    m_ctlSepVertCenter.SetFont(&fontVertEnabled);

Spin Control

COXSpinCtrlextends, the MFC CSpinButtonCtrl class; it extends the functionality of the common control that MFC wraps. Apart from the two buttons (up and down) it shows a small rectangle (called "the spin thumb") inbetween these two buttons. When the user clicks and holds this rectangle, the mouse cursor will change shape, and the user can drag the mouse to increase or decrease the value.

Static Controls

COXStatic, COXStaticText and COXStaticHyperLink controls.

See the Static Hyperlink and Static Text articles for more on these classes.

Status Bar

An enhanced CStatusBar implementation.

    wsprintf(buffer, _T("%02.2d:%02.2d:%02.2d"), 
        datetime.tm_hour, datetime.tm_min, datetime.tm_sec);

    if (datetime.tm_sec == 0 || datetime.tm_sec == 30)
    {
        m_wndStatusBar.ResetBar(1);
        m_wndStatusBar.SetBarProgress(1, TRUE, 30, 0);
    }
    else
    {
        m_wndStatusBar.SetBarProgress(1, TRUE, 31, datetime.tm_sec % 30);
    }


    if((datetime.tm_sec % 2) == 0)
        m_wndStatusBar.SetPaneText( 5, (LPCTSTR)buffer, RGB(255,0,0), 
            TRUE);
    else
        m_wndStatusBar.SetPaneText( 5, (LPCTSTR)buffer);  
    }

Shortcut Bar (Outlook Style)

A popular Outlook style shortcut bar.

    // outlook group


    sText=_T("Outlook");
    shbGroup.nMask=SHBIF_TEXT;
    shbGroup.nTextMax=sText.GetLength();
    shbGroup.pszText=sText.GetBuffer(shbGroup.nTextMax);
    sText.ReleaseBuffer();
    m_ctlShortcutBar.InsertGroup(&shbGroup);

    // mail group


    sText=_T("Mail");
    shbGroup.nMask=SHBIF_TEXT;
    shbGroup.nTextMax=sText.GetLength();
    shbGroup.pszText=sText.GetBuffer(shbGroup.nTextMax);
    sText.ReleaseBuffer();
    m_ctlShortcutBar.InsertGroup(&shbGroup);

Specially Shaped Window

The COXShape class defines an abstract C++ class to encapsulate the Windows SetWindowsRgn API.

    for(nID = IDC_0; nID <= IDC_9; nID++)
    {
        pKey = (CCalcKey*) GetDlgItem(nID);
        ASSERT(pKey != NULL);

        // Make them star shaped


        pKey->SetStarShape();

        // Set color to yellow when not pressed, red when pressed


        pKey->SetColors(RGB(0,0,0),RGB(255,255,0),RGB(0,0,0),RGB(255,0,0));
    }

Tabbed Views

COXTabViewContainer and COX3dTabViewContainer implements two types of widows supporting multiple tabs.

See the 3D Tab Views article for more on these classes.

Tabbed MDI

COXTabWorkspace and COXTabClientWnd are used to implement a frame work that implements a tabbed MDI architecture.


The samples\gui\CoolToolBar\Multipad2 sample shows the tabbed MDI framework in action.

Implementing a tabbed MDI application is quite simple:

  • Create a standard MDI application (or use an existing one).
  • Define a COXTabClientWnd object in your CMDIFrameWnd derived class (usually CMainFrame).
// MTI client window


COXTabClientWnd m_MTIClientWnd;
  • In the OnCreate() function of your CMDIFrameWnd derived class call the COXTabClientWnd::Attach function
m_MTIClientWnd.Attach(this);

That's it! You can learn more about the classes in the compiled HTML help documentation.

Tree Controls

COXTreeControl, COXTreeItem, COXOptionTreeControl and COXNetBrowseTree.

See the articles on the Network Browser and Option Tree controls for more information on these extensions.

Tooltips

COXToolTipCtrl is an extended tooltip control that allows multiline tooltips, plus extended tooltip text.

Please see the COXToolTipCtrl article for more information.

User Customizable Menu

COXUserTool provides a way of implementing a special menu in your application where users can insert their own tools.

This class provides a way of implementing a special menu in your application where users can insert their own tools. These tools can then be executed from within your application. (Similar to the Tools menu in the Developer Studio IDE). This class features:

  • The same set of parameters the VisualC++ IDE uses, like MenuText, Command, Arguments and Initial Directory

  • Built-in functionality to work with your own symbolic arguments like the $(FileName) or $(FileDir) variables.

  • Some helper functions to read and write ToolSets to file

  • Ability to append an array of Usertools to an existing Menu

To use the COXUserTool class you must determine in which menu the UserTools will be located. This menu can be your CMainFrame menus or a menu from another window. Next, select a range of MenuIDs big enough to cover your maximum number of Usertools so as to enable your CMainFrame (or other window) to route the command messages coming from the menu selections of your usertools.

const UINT ID_TOOLS_USER_1 = 32771;
const UINT MAX_TOOLS_USER = 10;

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)


// NOTE - the ClassWizard will add and remove mapping macros here.


// DO NOT EDIT what you see in these blocks of generated code !


ON_WM_CREATE()
ON_COMMAND(ID_TOOLS_CUSTOMIZE, OnToolsCustomize)
ON_COMMAND_RANGE(ID_TOOLS_USER_1, ID_TOOLS_USER_1 + MAX_TOOLS_USER, 
    OnToolsExecute)
//}}AFX_MSG_MAP


END_MESSAGE_MAP()

The ON_COMMAND_RANGE macro is particularly suitable for catching the complete range of command messages fired by the Usertool menu selections. The OnToolsExecute function has an input parameter nID in which the Command ID of a menu selection is trapped.

void CMainFrame::OnToolsExecute(UINT nID) 
{
     int iIndex = (int)( nID - ID_TOOLS_USER_1 );

     if ( -1 < iIndex && iIndex < m_ToolArray.GetSize() )
     { 
          COXUserTool* pTool = (COXUserTool*)m_ToolArray.GetAt( iIndex );
          ASSERT( pTool != NULL );

          CStringList Replacements;

          // ....(fill up a Replacements list)



          BOOL bOk = pTool->Execute( &Replacements );
          ASSERT(bOk);

          if (!bOk)
               AfxMessageBox( 
               "Could not execute Tool", MB_OK | MB_ICONEXCLAMATION);
}

Usertools are created and initialized by newly selecting and assigning the 4 member variables. Note that to keep track of the tools created, a CObArray is used. This is the preferred method because there are 4 helper functions in COXUserTool that work with a CObArray. Thus the CObArray contains a collection of COXUserTools. More on that later.

// add some user tools to the UserToolArray


COXUserTool* pNewTool = new COXUserTool();
pNewTool->SetMenuText("NotePad");
pNewTool->SetCommand("c:\\winnt35\\NotePad.exe");
pNewTool->SetArgs("README.TXT");
pNewTool->SetDirectory("c:\\decoder");

m_ToolArray.Add(pNewTool);

The 4 helper functions are :

  • BOOL ReadUserToolFile( LPCTSTR pcszFilename, CObArray& a ) : Gets a reference to a CObArray and name of a diskfile. Reads the diskfile into the CObArray.

  • BOOL WriteUserToolFile( LPCTSTR pcszFilename, CObArray& a ) : Gets a reference to a CObArray and name of a diskfile. Writes the diskfile while iterating the usertools in the CObArray.

  • BOOL AppendUserTools( CMenu* pMenu, UINT uiFirstID, const CObArray& a ) : Searches in pMenu for a MenuItem with ID uiFirstID and starts appending all UserTools contained in the CObArray to this MenuItem.
CMenu* pMenu = NULL;
pMenu = GetMenu(); // get a pointer to the main menu


if (pMenu != NULL)
{
     // The tools menu is the fourth menu in the main menu


     // after File, Edit an View (see resource editor)



     CMenu* pSubMenu = pMenu->GetSubMenu(3);
     if (pSubMenu != NULL)
          AppendUserTools(pSubMenu ,ID_TOOLS_USER_1, m_ToolArray);
}
  • void EmptyUserToolArray( CObArray& a ) : No need for a FOR loop to clean-up the allocated COXUserTools in the CObArray, this function does it for you.

See the compiled HTML help documentation for a complete COXUserTool class reference.

Window Hook

COXHookWnd and COXHookWndMap allow for hooking a window's default WindowProc.

COXHookWnd is a generic class to allow you to intercept messages that are targeted at a CWnd. Once hooked, all messages first route through COXHookWnd::WindowProc before going to the window they were originally intended for. Specific subclasses of COXHookWnd can trap messages and perform custom handling for those messages. To use the hook simply follow these steps:

  • Derive a class from COXHookWnd.
  • Override the COXHookWnd::WindowProc virtual function to handle all the incoming messages. Be sure to call the base class implementation of COXHookWnd::WindowProc if the message is not handled, or the window for which the messages were intended will never be notified of the messages. If you write separate message handlers, you can call COXHookWnd::Default to pass the messages back to the window.
    NOTE: COXHookWnd::Default calls the CWnd::Default function to pass the notification back to the CWnd.
  • Instantiate your derived class and call the COXHookWnd::HookWindow function to hook your window, after it has been created. To unhook the window, call COXHookWnd::UnhookWindow.

The message hook map (class COXHookWndMap) is derived from CMapPtrToPtr, which associates a pointer with another pointer. It maps an HWND to a COXHookWnd, like the way MFC's internal maps map HWNDs to CWnds. The first hook attached to a window is stored in the map; all other hooks for that window are then chained via COXHookWnd::m_pNext.

The purpose of these classes is to create an effective object oriented solution to the "inheritance message handling problem". Let's assume we have an application with many CView derived objects, such as CFormView, CListView, CTreeView, etc. Furthermore, let's assume that these windows all need to exhibit some common functionality upon receipt of a particular message. Ideally, we would change the CView base class to intercept this message and provide the custom handling. In that case, any CView derived class would exhibit the same functionality for that given message. Unfortunately, however, we cannot change the CView base class as it lies deep within MFC code and would force us to recompile the MFC library. Also, we're not willing to rewrite the CFormView, CListView, CTreeView, etc. classes to use a our own custom CView class. But how do we get the common message handling without intercepting the message in every class? The solution is quite simple using the COXHookWnd class.

To provide this custom handling across all windows, derive a class from COXHookWnd, say CMyCustomHook, and override the COXHookWnd::WindowProc virtual function to handle the message. Then for every window that requires the custom message handling, instantiate a CMyCustomHook object and hook the window to the object using the COXHookWnd::HookWindow function. You will need to instantiate a CMyCustomHook object for every window you wish to hook. Then, every window hooked with the CMyCustomHook hook will first allow that COXHookWnd object to examine the messages before re-routing them to the owned window. Be sure to call COXHookWnd::UnhookWindow when you no longer with to have a window's messages hooked or when the window is being destroyed.

The COXHookWnd class provides the backbone functionality for several of the Ultimate Toolbox's classes. These classes include: COXBackgroundPainter, COXCaptionInfo, COXIntelliMouse, COXItemTip, COXRulerBar, and COXSoundEffectManager. Because of the COXHookWnd & COXHookWndMap classes, these objects can get "first rights" to particular messages. That is, before a window that exploits the sound manager object, for example, the COXSoundEffectManager must determine if a sound file should be played. To do this, The COXSoundEffectManager class overrides the COXHookWnd::WindowProc virtual function to provide its custom handling (playing of a sound file) for those messages registered with the object.

History

Initial CodeProject release August 2007.

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