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

  • With JRebel, developers get to see their code changes immediately, fine-tune their code with incremental changes, debug, explore and deploy their code with ease (both locally and remotely), and ultimately spend more time coding instead of waiting for the dreaded application redeploy to finish. Every time a developer tests a code change it takes minutes to build and deploy the application. JRebel keeps the app server running at all times, so testing is instantaneous and interactive.

  • When it comes to desktops – physical or virtual – it's all about the applications. Cloud-hosted virtual desktops are growing fast because you get local data center-class security and 24x7 access with the complete personalization and flexibility of your own desktop. Organizations make five common mistakes when it comes to planning and implementing their application management strategy. This eBook tells you what they are and how to avoid them, and offers real-life case studies on customers who didn't let …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds