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;
     CMyTextButton() : m_bUse3D(true) {}
     void Use3D(bool bUse3D=true) { m_bUse3D = bUse3D; }
     void Draw(CDC* pDC, const CRect& rect, UINT state);
     afx_msg void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
     afx_msg BOOL OnEraseBkgnd(CDC* pDC);
     virtual void PreSubclassWindow();



// 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__;

// CMyTextButton


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

// CMyTextButton message handlers

void CMyTextButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) {
     CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
     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;
     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.
     } else {
          logfont.lfHeight = ::MulDiv(logfont.
     logfont.lfHeight--; // fudge factor
     if (m_bUse3D) rectClient.InflateRect(3,3);

     // create adjusted font and select
     CFont font; font.CreateFontIndirect(&logfont);
     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
     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
     // draw the text

     // restore DC

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


  • 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.


  • 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!

  • 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.

  • 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

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

    Originally posted by: E.Karthikeyan

    Better for beginner

  • 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!

  • 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.

  • 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!


  • 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 ??

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

Top White Papers and Webcasts

  • Rocket Mobile® for IBM i is an enterprise mobile application development and deployment platform for customers who rely on the IBM i system. Rocket Mobile for IBM i enables customers to leave proven applications in-place and rapidly repurpose them into new managed and secure mobile applications. Fast, easy creation of mobile, web, and hybrid mobile applications that deploy to any iOS, Android, or Windows mobile phone or tablet Built-in integration for seamless repurposing of existing IBM i applications …

  • Complex hybrid environments can make it difficult to track interdependencies, increasing the risk of disrupting critical business services. In this white paper by EMA, you'll learn how application discovery and dependency mapping can help you: Meet granular targets for availability, cost, and time-to-revenue for cloud services. Accelerate mean time to repair (MTTR) while communicating better with stakeholders. Manage even the most complex hybrid environments more efficiently and effectively Understand the …

Most Popular Programming Stories

More for Developers

RSS Feeds

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