3D Text

Ever want large size text in your about box or splash screen? How about text with a raised 3D appearance? Well, this class will do it for you.

Simply add a button to your dialog. Set the button label to the text required - it will enlarge itself to fill the button, so make the button bigger for bigger 3D text.

In your dialog class, associate a control variable (say m_text3d), with the button. If you have told class wizard about CMyTextButton, you will be able to select it when you define the control variable. if not, just go for CButton and then manually edit the definition in your dialog header file, changing CButton ro CMyTextButton. If you do not like using DDX then you can just subclass the control.

In you OnInitDialog you would call the Use3D() function to set 3D effect on or off (it is on by default here). Also, you can change the text with SetWindowText().

The class uses PreSubclassWindow to ensure that the correct style bits are set, so you don't need to remember to set them in your dialog (I always do my own controls this way).

///////////////////////////////////////////////////////////////////////////
//
// MyTextButton.h interface for CMyTextButton
// (c) Roger Onslow, 1997
// use freely and enjoy
///////////////////////////////////////////////////////////////////////////
//

#ifndef _CMyTextButton_
#define _CMyTextButton_

///////////////////////////////////////////////////////////////////////////
//
// CMyTextButton control

class CMyTextButton : public CButton {
     bool m_bUse3D;
public:
     CMyTextButton() : m_bUse3D(true) {}
     void Use3D(bool bUse3D=true) { m_bUse3D = bUse3D; }
protected:
     void Draw(CDC* pDC, const CRect& rect, UINT state);
     //{{AFX_MSG(CMyTextButton)
     afx_msg void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
     afx_msg BOOL OnEraseBkgnd(CDC* pDC);
     //}}AFX_MSG
     //{{AFX_VIRTUAL(CMyTextButton)
     virtual void PreSubclassWindow();
     //}}AFX_VIRTUAL
     DECLARE_MESSAGE_MAP()
};

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

#endif



///////////////////////////////////////////////////////////////////////////
//
// MyTextButton.cpp - large text which acts as a button
// (c) Roger Onslow, 1997
// use freely and enjoy
///////////////////////////////////////////////////////////////////////////
//
#include "stdafx.h"
#include "MyTextButton.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

///////////////////////////////////////////////////////////////////////////
//
// CMyTextButton

BEGIN_MESSAGE_MAP(CMyTextButton, CButton)
     //{{AFX_MSG_MAP(CMyTextButton)
     ON_WM_DRAWITEM()
     ON_WM_ERASEBKGND()
     //}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CMyTextButton::PreSubclassWindow() {
     SetButtonStyle(GetButtonStyle() | BS_OWNERDRAW);
}

///////////////////////////////////////////////////////////////////////////
//
// CMyTextButton message handlers

void CMyTextButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) {
     CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
     ASSERT_VALID(pDC);
     CRect rectClient = lpDrawItemStruct->rcItem;
     Draw(pDC,rectClient, lpDrawItemStruct->itemState);
}

void CMyTextButton::Draw(CDC* pDC, const CRect& rect, UINT state) {
     CString text; GetWindowText(text);
     int l = text.GetLength();
     CRect rectClient = rect;

     // get font from control
     CFont* pFont = GetFont();

     // ensure we have a valid height and width and select the font
     LOGFONT logfont;
     pFont->GetObject(sizeof(LOGFONT),&logfont);
     if (logfont.lfHeight == 0) logfont.lfHeight = 20;
     logfont.lfWidth = 0;     // 0 so it will be calculated
     logfont.lfWeight = 1000;
     logfont.lfEscapement = logfont.lfOrientation = 0;
     CFont tryfont; VERIFY(tryfont.CreateFontIndirect(&logfont));
     CFont* pFontOld = pDC->SelectObject(&tryfont);

     // get the control size and adjust font width & height accordingly
     if (m_bUse3D) rectClient.DeflateRect(3,3);
     CSize textSizeClient = pDC->GetTextExtent(text,l);
     if (rectClient.Width()*textSizeClient.cy >
rectClient.Height()*textSizeClient.cx) {
          logfont.lfHeight = ::MulDiv(logfont.
lfHeight,rectClient.Height(),textSizeClient.cy);
     } else {
          logfont.lfHeight = ::MulDiv(logfont.
lfHeight,rectClient.Width(),textSizeClient.cx);
     }
     logfont.lfHeight--; // fudge factor
     if (m_bUse3D) rectClient.InflateRect(3,3);

     // create adjusted font and select
     CFont font; font.CreateFontIndirect(&logfont);
     pDC->SelectObject(&font);
     textSizeClient = pDC->GetTextExtent(text,l);

     int minx = rectClient.left+(rectClient.Width()-textSizeClient.cx)/2;
     int miny = rectClient.top+(rectClient.Height()-textSizeClient.cy)/2;

     int oldBkMode = pDC->SetBkMode(TRANSPARENT);
     COLORREF textcol = ::GetSysColor((state & ODS_FOCUS) ? COLOR_GRAYTEXT
: COLOR_BTNTEXT);
     COLORREF oldTextColor = pDC->SetTextColor(textcol);

     int cx = minx;
     int cy = miny;
     if (m_bUse3D) {
          int s = (state & ODS_SELECTED) ? -1 : +1;
          cx += 3; cy += 3;

          // draw 3D highlights
          pDC->SetTextColor(::GetSysColor(COLOR_3DDKSHADOW));
          pDC->TextOut(cx-s*2,cy+s*2,text);
          pDC->TextOut(cx+s*2,cy-s*2,text);
          pDC->TextOut(cx+s*2,cy+s*2,text);
          pDC->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
          pDC->TextOut(cx+s*1,cy-s*2,text);
          pDC->TextOut(cx-s*2,cy+s*1,text);
          pDC->TextOut(cx-s*2,cy-s*2,text);
          pDC->SetTextColor(::GetSysColor(COLOR_3DSHADOW));
          pDC->TextOut(cx-s*1,cy+s*1,text);
          pDC->TextOut(cx+s*1,cy-s*1,text);
          pDC->TextOut(cx+s*1,cy+s*1,text);
          pDC->SetTextColor(::GetSysColor(COLOR_3DLIGHT));
          pDC->TextOut(cx,cy-s*1,text);
          pDC->TextOut(cx-s*1,cy,text);
          pDC->TextOut(cx-s*1,cy-s*1,text);
          pDC->SetTextColor(textcol);
     }
     // draw the text
     pDC->TextOut(cx,cy,text);

     // restore DC
     pDC->SetTextColor(oldTextColor);
     pDC->SetBkMode(oldBkMode);
     pDC->SelectObject(pFontOld);
}

BOOL CMyTextButton::OnEraseBkgnd(CDC*) {
     return true;    // we don't do any erasing...
}



Comments

  • Is this possible for CStatic

    Posted by Legacy on 07/21/2003 12:00am

    Originally posted by: R Tamilarasan

    Can same thing be done for CStatic class.

    Regards,
    Tamilarasan.

    Reply
  • we can further split this up

    Posted by Legacy on 06/27/2002 12:00am

    Originally posted by: Prashantha Shet

    I think it is better to split this functionality in two parts. One is drawing the 3D text and the other is using it in a button. By doing this we can use the text portion wherever we want, not necessarily in a button, as it is now. We can then create a static control, a list box etc with this text drawing function.
    Good try!

    Reply
  • change color

    Posted by Legacy on 04/10/2002 12:00am

    Originally posted by: Syed Naseer Abbas

    i like it.if u can add that the 3d text changes color randomly then it will fun and nice to see.
    Thanks...

    Reply
  • Very god stuf

    Posted by Legacy on 11/21/2001 12:00am

    Originally posted by: Picasso

    I have ver much code of you see and it had me very much help
    Thank�s and tahe care.....

    Reply
  • Reply

    Posted by Legacy on 07/20/2001 12:00am

    Originally posted by: E.Karthikeyan

    Better for beginner

    Reply
  • You are best!

    Posted by Legacy on 09/30/2000 12:00am

    Originally posted by: Error Free

    Nice! I need it! Thank you very much! High hand!

    Reply
  • How to turn off or on the show none at run time

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

    Originally posted by: Lewis Valentine

    The microsoft example CmnCtrl1 turns on or off the show none at run time.

    This does have one problem though. It will mess up the tab order of the dialog.
    As long as the control is the first or last control in the dialog or is not in the tab order it will not show.

    If any body has any ideas how to get around this let me know.

    Reply
  • Something technical...

    Posted by Legacy on 02/28/1999 12:00am

    Originally posted by: George

    I only have one technical note. There is a small difference between the bool and BOOL types. The first one (bool) is an integral type, while the other (BOOL) is more like an integer. According to the MSDN docs in VC4.2 bool will still go int, VC5.0 and later, bool is a built-in type with a size of 1 byte. Thus, better don't mix both together. In general, I think to use BOOL is much more 'MFC', and then use TRUE not true and FALSE not false. In OnEraseBkgnd it is mixed somehow... Anyway, just a note, take it easy, OK? Good work!

    BR

    Reply
  • Use in Formview

    Posted by Legacy on 01/11/1999 12:00am

    Originally posted by: Hyou Joo Kim

    This class is only useful in dialog class.
    
    

    but i want to use this class in formview..

    How ??

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

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • On-demand Event Event Date: October 23, 2014 Despite the current "virtualize everything" mentality, there are advantages to utilizing physical hardware for certain tasks. This is especially true for backups. In many cases, it is clearly in an organization's best interest to make use of physical, purpose-built backup appliances rather than relying on virtual backup software (VBA - Virtual Backup Appliances). Join us for this webcast to learn why physical appliances are preferable to virtual backup appliances, …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds