Virtual Developer Workshop: Containerized Development with Docker


The CSeparator class is an enhancement to standard static text controls that duplicates the look of the Office 97 products' options screens, like Word (pictured).

 [Word 97 options - 13K]

This separator element is a nice alternative when you want to avoid really big or nested group boxes, or just look like you're keeping up with Microsoft's ever-changing UI designs. ;)

This class is an extension to Hans Buehler's article "Control for drawing a bevel line." One of the enhancements he mentioned was adding text to horizontal lines, so that's what I've done!

CSeparator was written with MSVC 5.0. The code will work in Unicode apps, and should compile fine with 6.0 as well.


When laying out a vertical separator, make the static control as tall as you want the line to be. The line will be drawn horizontally centered in the control, so it's a good idea to make the control the minimum width of 8 DLUs so you can judge where the line will appear. Vertical separators do not display text.

When laying out horizontal separators, place your static controls as usual, but make them as wide as you want the horizontal line to be. You can also set the alignment of the text (left, center, or right), and set the No Prefix style if you want. Those are the only static control styles supported at this time. If you do not set the No Prefix style, then you can use a shortcut key (i.e., put a & before a letter) just as with normal static text controls.

A sample dialog is pictured below, first in the resource editor, and then with the separators in action.

 [Dlg in MSVC resource editor - 14K]  [Dlg with separators drawn - 17K]

Each static control that will be used as a separator should have a real unique ID (not IDC_STATIC). Using ClassWizard, create member variables of type CStatic for each separator, and then go to the ClassWizard-generated code and change the type of the variables to CSeparator. That's it!

Future Enhancements

I tried for a little while to get vertically-drawn text, but it was pretty tricky to get the text aligned correctly over the line. Drawing the text rotated is no problem (as long as you select a TrueType font into the DC!) but the horizontal position of the text depends on the length of the text. The CSeparator class has some code to draw text vertically, although it is commented out since it doesn't work exactly right. It's just there as a starting point for anyone brave enough to take on the challenge. See the OnPaint() function for the code snippet and some comments.

Download demo project - 14KB


  • Code for disabled static text...

    Posted by Legacy on 12/11/2003 08:00am

    Originally posted by: Mouse

    This is incase the static control is disabled... it uses the DrawState() API to draw disabled text.  Just replace the whole OnPaint() routine with this code:

    void CSeparator::OnPaint()
    CPaintDC dc(this); // device context for painting
    CRect rectWnd; // RECT of the static control
    CString cstrText; // text to draw
    CFont* pfontOld;
    DWORD dwStyle = GetStyle(); // this window's style

    // Get the screen & client coords.
    GetWindowRect ( rectWnd );

    if(rectWnd.Height() > rectWnd.Width()){
    0, 2,
    rectWnd.Width(), 2,


    cstrText = ( ((dwStyle & SS_CENTER)||(dwStyle & SS_RIGHT))?_T(" "):_T("") )
    + cstrText +
    ( ((dwStyle & SS_CENTER)||!(dwStyle & SS_RIGHT))?_T(" "):_T("") );

    pfontOld = dc.SelectObject(GetFont());
    COLORREF oldBkColor = dc.SetBkColor(::GetSysColor(COLOR_BTNFACE));

    // copy over CString() to a char array so DrawState() works
    char* pszText = new char[cstrText.GetLength() + 1];
    strcpy(pszText, cstrText);

    // get the metric len of our txt
    CSize sizeTxt = dc.GetTextExtent(pszText, strlen(pszText));

    // fill in rectangle that text will fill
    CRect txtRc;
    txtRc.top = 0;
    txtRc.bottom = rectWnd.Height();
    if(dwStyle & SS_CENTER){
    txtRc.left = (rectWnd.Width()/2)-(sizeTxt.cx/2);
    }else if(dwStyle & SS_RIGHT){
    txtRc.left = rectWnd.Width() - sizeTxt.cx;
    txtRc.left = 0;
    txtRc.right = txtRc.left + sizeTxt.cx;

    // draw a solid rect
    dc.FillSolidRect(txtRc, ::GetSysColor(COLOR_BTNFACE));

    // draw text state

    // clean up
    delete pszText;

  • Excellent...

    Posted by Legacy on 12/10/2003 08:00am

    Originally posted by: Mouse

    thanks man, was just going to write this one. saved me some time. it sure was a pain laying statics over etched static frames.

  • Already Built Into MFC

    Posted by Legacy on 06/13/2003 07:00am

    Originally posted by: shaun

    this control is already built into MFC. Just make a picture box, 1 pixel wide, however tall (or vise-versa) and then set its border to "Etched".


  • Resizing and a related fix.

    Posted by Legacy on 09/16/2002 07:00am

    Originally posted by: David Pawlyk

    I use the following example in the Dialogs section for resizing:
    Flicker-Free Resizing Dialog - Andy Brown (1999/12/29)

    Add the following to the class so that the line is redrawn properly (especially when increasing the size).

    void CSeparator::OnSize(UINT nType, int cx, int cy)
    CStatic::OnSize(nType, cx, cy);


  • I have a problem if i maximize the dialog box

    Posted by Legacy on 04/07/1999 07:00am

    Originally posted by: Asha

    The class is very fine. I used it in a dialog box which has MAXIMIZE AND MINIMIZE button enable , i got a problem that if i MAXIMIZE the dialog , the line still kepps the same length..
    Can u suggest me ?? solution


  • What advantage over using the standard resource editor ?

    Posted by Legacy on 12/02/1998 08:00am

    Originally posted by: Hans Wedemeyer

    What advantage over using the standard resource editor ?

    I don't understand !

    Hans Wedemeyer

  • You must have javascript enabled in order to post comments.

Leave a Comment
  • Your email address will not be published. All fields are required.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date