Control for drawing a bevelline (2)


Overview

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.

Example

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



Comments

  • Code for disabled static text...

    Posted by Legacy on 12/11/2003 12: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()){
    dc.Draw3dRect(rectWnd.Width()/2,
    0, 2,
    rectWnd.Height(),
    ::GetSysColor(COLOR_3DSHADOW),
    ::GetSysColor(COLOR_3DHIGHLIGHT));
    }else{
    dc.Draw3dRect(0,
    rectWnd.Height()/2,
    rectWnd.Width(), 2,
    ::GetSysColor(COLOR_3DSHADOW),
    ::GetSysColor(COLOR_3DHIGHLIGHT));

    GetWindowText(cstrText);

    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;
    }else{
    txtRc.left = 0;
    }
    txtRc.right = txtRc.left + sizeTxt.cx;

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

    // draw text state
    DrawState(dc.GetSafeHdc(),
    NULL,NULL,
    (long)pszText,
    strlen(pszText),
    txtRc.left,
    txtRc.top,
    txtRc.right,
    txtRc.bottom,
    ((dwStyle & SS_NOPREFIX)?DST_TEXT:DST_PREFIXTEXT) | (IsWindowEnabled()?DSS_NORMAL:DSS_DISABLED));

    // clean up
    delete pszText;
    dc.SetBkColor(oldBkColor);
    dc.SelectObject(pfontOld);
    }
    }

    Reply
  • Excellent...

    Posted by Legacy on 12/10/2003 12: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.

    Reply
  • Already Built Into MFC

    Posted by Legacy on 06/13/2003 12: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".

    Shaun

    Reply
  • Resizing and a related fix.

    Posted by Legacy on 09/16/2002 12: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);

    Invalidate();
    }

    Reply
  • I have a problem if i maximize the dialog box

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

    Originally posted by: Asha


    Hai,
    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

    Bye
    Asha

    Reply
  • What advantage over using the standard resource editor ?

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

    Originally posted by: Hans Wedemeyer

    What advantage over using the standard resource editor ?

    I don't understand !

    Hans Wedemeyer

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

Top White Papers and Webcasts

  • 10 Rules that Make or Break Enterprise App Development Projects In today's app-driven world, application development is a top priority. Even so, 68% of enterprise application delivery projects fail. Designing and building applications that pay for themselves and adapt to future needs is incredibly difficult. Executing one successful project is lucky, but making it a repeatable process and strategic advantage? That's where the money is. With help from our most experienced project leads and software engineers, …

  • As everyone scrambles to protect customers and consumers from the Heartbleed virus, there will be a variety of mitigating solutions offered up to address this pesky bug. There are a variety of points within the data path where solutions could be put into place to mitigate this (and similar) vulnerabilities and customers must choose the most strategic point in the network at which to deploy their selected mitigation. Read this white paper to learn the ins and outs of mitigating the risk of Heartbleed and the …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds