Click here to Skip to main content
11,478,174 members (77,286 online)
Click here to Skip to main content

Custom Captions (including multi-line captions)

, 15 Jul 2000 CPOL 165.4K 4.5K 61
Rate this:
Please Sign up or sign in to vote.
Simple customised Window captions, including multi-line captions

Miscellaneous Captions Image Bitmap Caption Image

Overview

This article presents some classes that make customising window captions really quick and easy.

Using these classes you can change the background colour and the text font and colour of both the active and inactive window captions independently for any windows you choose. I also provide an example class that allows a bitmap to be used as the caption background, e.g. for logos, or wood or stone effects.

More unusually, you can have your child window captions automatically wrap onto more than one line to accommodate extra long titles. This caption auto-sizing facility also allows extra large fonts and bitmaps to be used as banner captions on selected windows.

Background

A couple of years ago, I was writing an VC++/MFC MDI database query application, which presented the query results as tables or lists of data in MDI child windows.

A problem arose with the display of titles based on the queries used for particular windows, such as "Productivity League Table: UK Media companies where Net Turnover > £25,000,000 and Number of Employees > 3500". Some titles would be even longer than this, and were often truncated when displayed as window captions. Things got much worse when users tiled a number of these windows, because they would end up with five or six windows titled "Productivity League Table: UK..." and "Company News Headlines: Finan...", etc. It was obviously a headache to find any particular window of interest when their captions all seemed to say the same thing!

There are several solutions to this kind of problem, such as tooltips or just relying on titles in the client area, but all seem to have irritating drawbacks. I couldn't help feeling that the caption really was the right place even for long titles like these, so you could see at a glance what the window was about. I experimented with owner-draw captions using a 1997 Microsoft Systems Journal C++ Q&A article by Paul DiLascia, that described how to draw shaded colour gradient caption backgrounds. The results were better than I'd expected, so I thought I'd rework them into something anyone could use.

The result is this little kit of classes.

The Classes

CCaption:The abstract main class, installs itself into the frame window and manages the caption painting using CCaptionBackground and CCaptionTextAttributes (see below). By default it paints a standard window caption.

CCaptionBackground: Used by CCaption. Paints the caption active and inactive background. By default it uses the system caption colours.

CCaptionTextAttributes: Used by CCaption. Provides the active and inactive caption text fonts and colours. By default it uses the system caption font and colours.

CSingleLineCaption: Derived from CCaption, this provides standard height custom captions for dialogs and other non-MDI Child windows (e.g. frames with menus).

CMultiLineCaption: Derived from CCaption, this wraps the caption onto additional lines according to the length of the title and the font size. Only suitable for windows without menus (e.g. MDI child windows), as I haven't yet found a way to modify the default position of menus...

CMultiLineCaptionEx: Derived from CMultiLineCaption and extended to fix a weird Windows 95 and WinNT 'feature' that secretly draws a standard caption when mouse activity occurs in the non-client area once the system menu has been displayed. This can spoil the clean appearance of multiline captions, but doesn't affect Windows 2000.

CGradientCaptionBackground: Used by CCaption. Derived from CCaptionBackground, paints the active background as a shaded colour gradient (shading to black).

CBmpCaptionBackground: Used by CCaption. Paints a bitmap as the active background. An example class in the CaptionDemo project to show how easy it is to derive your own custom background painters.

[Sundry helper classes are also used, notably Paul DiLascia's CSubclassWnd but are not part of the public interface].

How to Use

Declare a caption object (CSingleLineCaption, CMultiLineCaption, or CMultiLineCaptionEx) as a member of your frame window class:

#include "..\CustomCaption\MultiLineCaptionEx.h"

class CChildFrame : public CMDIChildWnd
{
    ...
private:
    ////////////
    // Declare a caption object (this one is an extended multi-line caption)
    //
    CMultiLineCaptionEx m_Caption;
    ...
};

Install the caption in the OnCreate() method of your frame window class (you may need to use the ClassWizard to insert this function. Note: select the 'WM_CREATE' message, not the 'Create' message):

int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
   if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
       return -1;
    
    // TODO: Add your specialized creation code here

   ///////
   // Install caption into frame
   //
   m_Caption.Install(this);

   return 0;
}
That's all there is to it! If you install a Multi-line Caption as above, caption titles too long to fit on a single line will automatically wrap onto new lines. You can change the maximum number of lines the caption will allow, using the SetMaxLines() method.

You can now use the caption object to set the colours and fonts of your caption. To do this, use the CCaption methods to access the CCaptionBackground and CCaptionTextAttributes objects, and modify their contents, e.g:

/////////////////
// Set active text and background colours
//
COLORREF colorText = RGB(txt_red, txt_green, txt_blue);
COLORREF colorBk = RGB(bk_red, bk_green, bk_blue);

m_caption.GetTextAttributes()->SetActiveColor(colorTxt);
m_caption.GetBackground()->SetActiveColor(colorBk);

/////////////////////
// Get active font and change it to Arial italic
//
LOGFONT lf;
m_caption.GetTextAttributes()->GetActiveFont()->GetLogFont(&lf);
lf.lfFaceName = "Arial";
lf.lfItalic = TRUE;
m_caption.GetTextAttributes()->SetActiveFont(lf);

/////////////////
// Refresh caption so changes take immediate effect
//
m_Caption.Refresh();

To change to a different background style, or to replace all the text attributes in one go, you can create a new CCaptionBackground or CCaptionTextAttributes object, initialize it as required, and set it into the caption, using the CCaption methods SetBackground() or SetTextAttributes():

//////////
// Construct a gradient background object
//
CCaptionBackground* pNewBackground = new CGradientCaptionBackground();

//////////
// Set the colours required
//
pNewBackground->SetCustomColors(ACTIVE_COLOR, INACTIVE_COLOR);

////////////
// Set the new background
//
m_Caption.SetBackground(pNewBackground);

Don't worry about deleting the background or text attributes objects, the caption will take care of that for you.

For full working code showing how to manipulate the various custom captions, see the Caption Demo source code, especially mainfrm.cpp. I have done my best to document all the source code, so it shouldn't be difficult to follow.

Odds & Ends

If anyone can throw some light on the weird WinNT/Win95 secret caption drawing 'feature' that occurs after displaying the window system menu, I'd be very interested (try installing a CMultiLineCaption, set a long window title so the caption wraps to more than one line, then click on the window icon to display the system menu, and you'll see what I mean. The normal window caption gets redrawn whenever the mouse crosses the non-client area or is clicked in the caption, without any NC_PAINT messages being sent). Why?

A tip for displaying bitmaps in captions - if you want a short title to appear at the top of a larger bitmap, append a long string of spaces to the title to persuade it to wrap over more lines.

The Downloads

  • Download demo executables - 32 Kb
    This contains the demo application executable CaptionDemo.exe and the custom caption DLL CustomCaption.dll
  • Download demo project - 75 Kb
    The demo project is actually a VC++6.0 workspace containing two projects, the Caption Demo application, and the Custom Caption DLL project. They install to separate folders, so should be unzipped using the path information.
  • Download source only - 25 Kb
    This contains just the source code for the Custom Caption classes.

Employer's Disclaimer

I am required to include the following disclaimer for my employer:

The views expressed above are those of the author alone and do not necessarily reflect the views of Financial Times Information Limited.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Dave Lorde
Web Developer
United Kingdom United Kingdom
No Biography provided

Comments and Discussions

 
Generalsuch a pain Pin
mimosa10-Apr-09 15:03
membermimosa10-Apr-09 15:03 
GeneralRe: such a pain Pin
Dave Lorde13-Apr-09 1:57
memberDave Lorde13-Apr-09 1:57 
GeneralTo the author.... (limits of usage?) Pin
Member 439186124-Sep-08 18:05
memberMember 439186124-Sep-08 18:05 
GeneralRe: To the author.... (limits of usage?) Pin
Dave Lorde25-Sep-08 3:48
memberDave Lorde25-Sep-08 3:48 
GeneralRe: To the author.... (limits of usage?) Pin
Member 439186125-Sep-08 15:44
memberMember 439186125-Sep-08 15:44 
JokeOH Pin
shouwangw200724-Nov-07 22:10
membershouwangw200724-Nov-07 22:10 
GeneralRe: OH Pin
Dave Lorde25-Nov-07 2:49
memberDave Lorde25-Nov-07 2:49 
GeneralThe proplem in SDI Pin
wzh1983122122-Dec-06 23:28
memberwzh1983122122-Dec-06 23:28 
GeneralRe: The proplem in SDI Pin
Dave Lorde23-Dec-06 4:14
memberDave Lorde23-Dec-06 4:14 
The code was written for use with MDI child windows. I didn't get time to make it work with main windows - the menus were a problem as you have discovered. If you succeed in making it work, please post the solution here for others to use - or submit your own article.
GeneralRe: The proplem in SDI Pin
wzh1983122123-Dec-06 22:46
memberwzh1983122123-Dec-06 22:46 
GeneralThank you for giving me what I really want Pin
wzh1983122122-Dec-06 18:37
memberwzh1983122122-Dec-06 18:37 
GeneralRe: Thank you for giving me what I really want Pin
Dave Lorde23-Dec-06 4:03
memberDave Lorde23-Dec-06 4:03 
GeneralRe: Thank you for giving me what I really want Pin
wzh1983122123-Dec-06 14:04
memberwzh1983122123-Dec-06 14:04 
QuestionSimple way for just changing window caption font ??? Pin
ana_v12320-May-06 8:43
memberana_v12320-May-06 8:43 
QuestionHow can I change the minimized caption height? Pin
xiaofu_yan5-Apr-05 21:40
memberxiaofu_yan5-Apr-05 21:40 
QuestionHow to remove the custom Caption Pin
pubududilena21-Mar-05 22:17
memberpubududilena21-Mar-05 22:17 
AnswerRe: How to remove the custom Caption Pin
WTL Student29-Mar-05 12:24
memberWTL Student29-Mar-05 12:24 
GeneralMDI Frame Title Bar Pin
Neel123454-Apr-04 19:52
memberNeel123454-Apr-04 19:52 
Generalbug fix for the repainting of the area of Min-Max-Close buttons Pin
baton8-Jan-04 22:34
memberbaton8-Jan-04 22:34 
QuestionCreate new Buttons ? Pin
Harald Diel6-May-03 4:09
memberHarald Diel6-May-03 4:09 
GeneralCaption height Pin
ofirc23-Jun-02 9:11
memberofirc23-Jun-02 9:11 
GeneralRe: Caption height Pin
dlorde24-Jun-02 15:08
memberdlorde24-Jun-02 15:08 
GeneralRe: Caption height Pin
ofirc26-Jun-02 0:25
memberofirc26-Jun-02 0:25 
GeneralRe: Caption height Pin
dlorde27-Jun-02 12:57
memberdlorde27-Jun-02 12:57 
GeneralRe: Caption height Pin
ofirc29-Jun-02 21:48
memberofirc29-Jun-02 21:48 
GeneralRe: Caption height Pin
Dave Lorde3-Jul-02 13:09
memberDave Lorde3-Jul-02 13:09 
GeneralProblem Painting In MainFrame Title Pin
Paras21-Aug-01 0:07
memberParas21-Aug-01 0:07 
QuestionAnyone found a solution on XP? Pin
Anonymous7-Aug-01 11:24
memberAnonymous7-Aug-01 11:24 
AnswerRe: Anyone found a solution on XP? Pin
Dave Lorde30-Oct-01 11:37
memberDave Lorde30-Oct-01 11:37 
AnswerRe: Anyone found a solution on XP? Pin
faridwidjaya12-Jul-05 9:25
memberfaridwidjaya12-Jul-05 9:25 
GeneralIt just won't work... Pin
Andreas Philipson10-Jul-01 3:07
memberAndreas Philipson10-Jul-01 3:07 
GeneralRe: It just won't work... Pin
Dave L.12-Jul-01 14:04
memberDave L.12-Jul-01 14:04 
GeneralCopying the DLL's to the Debug directory Pin
Wayne4-Aug-00 14:57
sussWayne4-Aug-00 14:57 
GeneralRe: Copying the DLL's to the Debug directory Pin
Dave Lorde4-Aug-00 16:43
sussDave Lorde4-Aug-00 16:43 
GeneralOne single question.. Pin
Maximilian Hänel22-Jul-00 15:54
sussMaximilian Hänel22-Jul-00 15:54 
GeneralRe: One single question.. Pin
Dave Lorde24-Jul-00 13:42
sussDave Lorde24-Jul-00 13:42 
GeneralRe: One single question.. Pin
nattu5-Nov-06 9:02
membernattu5-Nov-06 9:02 
GeneralFix for disabled maximize button Pin
Christian Carrillo17-Jul-00 12:03
sussChristian Carrillo17-Jul-00 12:03 
GeneralRe: Fix for disabled maximize button Pin
Dave Lorde19-Jul-00 6:32
sussDave Lorde19-Jul-00 6:32 
GeneralRe: Fix for disabled maximize button Pin
estartu_de1-Mar-06 0:27
memberestartu_de1-Mar-06 0:27 
GeneralRe: Fix for disabled maximize button Pin
Dave Lorde1-Mar-06 9:36
memberDave Lorde1-Mar-06 9:36 
GeneralAlternative source for download Pin
Dave Lorde17-Jul-00 0:35
sussDave Lorde17-Jul-00 0:35 
GeneralBroken Links! Pin
GF16-Jul-00 23:37
sussGF16-Jul-00 23:37 
GeneralRe: Broken Links! Pin
Dave Lorde17-Jul-00 0:17
sussDave Lorde17-Jul-00 0:17 
GeneralSimple half-fix for button repaint bug Pin
Christian Carrillo16-Jul-00 21:07
sussChristian Carrillo16-Jul-00 21:07 
GeneralRe: Simple half-fix for button repaint bug Pin
Dave Lorde17-Jul-00 0:15
sussDave Lorde17-Jul-00 0:15 
GeneralCFormView problems when using custom caption Pin
Peter Andersson10-Jul-00 7:55
sussPeter Andersson10-Jul-00 7:55 
GeneralRe: CFormView problems when using custom caption Pin
Dave Lorde14-Jul-00 7:28
sussDave Lorde14-Jul-00 7:28 
GeneralUsing with menubars and toolbars Pin
Bill Poitras22-May-00 8:35
sussBill Poitras22-May-00 8:35 
GeneralGreat Work Pin
Reema Poddar15-Apr-00 13:06
sussReema Poddar15-Apr-00 13:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150520.1 | Last Updated 16 Jul 2000
Article Copyright 2000 by Dave Lorde
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid