Click here to Skip to main content
13,868,147 members
Click here to Skip to main content
Add your own
alternative version


54 bookmarked
Posted 9 Mar 2004
Licenced Public Domain

Controls-in-controls: An edit box with an icon

, 16 Jun 2004
Rate this:
Please Sign up or sign in to vote.
Adding controls to a CEdit, an edit box with an icon

Sample Image - editwithicon.gif


While adding controls to other controls might be a commonly desired task, and edit box with an icon is perhaps not the most exciting or useful class. It presents a few enjoyable challenges, however, and usefulness is certainly not the only criteria for diving into control subclassing in MFC.

CIconEdit is a small CEdit-derived class with an attached small icon, where the multi line edit box edit rectangle is exploited, instead of the normal handling of non-client areas.

Using the code

Include the cpp- and h-file to the project. CIconEdit can be instantiated either dynamically, by a call to Create, or from a dialog template. In the latter case, a control variable can be created and bound to the control with the class wizard, or SubclassDlgItem can be used. Call SetIcon with either a HICON or a resource id to set the icon to display.

CIconEdit uses the edit rectangle of multi line edit boxes. Basically, it modifies the edit rectangle to add a left margin wide enough to accommodate a small icon. An instance of CIconWnd - a CStatic-derived class - is used to paint the icon. Icons can be set by calling CIconEdit::SetIcon with either a HICON handle to the desired icon, or a UINT resource id. If a resource id is used, the icon is destroyed by CIconEdit, otherwise the caller will have to destroy it.

The class overrides PreSubclassWindow. This call checks the edit box style. If ES_MULTILINE is not set, SetRect will not work, so the function ASSERTs. Sadly, it is not possible to add this style after the control is created - and it is too early to destroy and recreate the it. Then the edit rectangle is established. The width of a small icon is retrieved by a call to GetSystemMetrics, and the current edit rectangle is fetched, updated and set back to the control.

As soon as an icon is set by a call to either of the two SetIcon:s, the icon window is created.

CIconWnd is a very simple CStatic-derived class, handling WM_PAINT and there drawing the icon with a call to ::DrawIconEx. The icon will be scaled to the system small icon size if necessary.

Points of interest

Instantiating this control, doing a few common operations on CEdits, displayed an understandable but annoying quirk - the edit rectangle is reset. As the rectangle is absolute for a CEdit (RTF-controls can use an offset), WM_SIZE will have to be handled anyway. More surprising was that WM_SETFONT also killed the edit rectangle. For this reason, CIconEdit handles WM_SIZE and WM_SETFONT. As SetFont is not virtual, the message itself will have to be handled.

In this case, using a separate control for the icon might seem a bit byzantine, why not just draw it in the non-client area paint handling? Well, now I got myself a small-icon control if I should ever need one (which I doubt), and the edit control and icon is thoroughly separated codewise.

But the more exciting implication is the possibility to use the edit rectangle to put other controls and/or visuals in the edit box, buddy-buttons, line-numbers etc. And as the editing rectangle is not only used by the plain vanilla edit box - the RTF-control also has one - there is the possibility to add rulers etc. this way.


15/6 2004

In an explosion of activity, this article is finally updated thanks to the feedback from David Pritchard . I'm getting the system background color using GetSysColor(COLOR_WINDOW) when clearing the background behind the icon, and SetIcon with the HICON parameter will now also create the icon control... *blushing with embarrassment*


This article, along with any associated source code and files, is licensed under A Public Domain dedication


About the Author

Johan Rosengren
Software Developer (Senior) Abstrakt Mekanik AB
Sweden Sweden
45 years old, married, three kids.

Started with computers more than 20 years ago on a CBM-64.

Read Theoretical Philosophy at the University of Lund.

Working as a C++ consultant developer.

Science-fiction freak. Enjoy vintage punkrock.

You may also be interested in...


Comments and Discussions

Questionsource code for Buddy Button "404 - File or directory not found" in Pin
ApacheHema17-Mar-14 14:05
memberApacheHema17-Mar-14 14:05 
AnswerRe: source code for Buddy Button "404 - File or directory not found" in Pin
_Flaviu14-Jan-15 23:07
member_Flaviu14-Jan-15 23:07 
QuestionScrolling ? Pin
Mattthe cooldude9-Mar-05 14:58
memberMattthe cooldude9-Mar-05 14:58 
AnswerRe: Scrolling ? Pin
Johan Rosengren10-Mar-05 6:31
memberJohan Rosengren10-Mar-05 6:31 
GeneralProblem with mouse clicks Pin
David Pritchard20-Oct-04 0:01
memberDavid Pritchard20-Oct-04 0:01 
GeneralFalse alarm? Plus non-client implementation of IconEdit Pin
David Pritchard20-Oct-04 4:47
memberDavid Pritchard20-Oct-04 4:47 
GeneralRe: False alarm? Plus non-client implementation of IconEdit Pin
Johan Rosengren20-Oct-04 7:17
memberJohan Rosengren20-Oct-04 7:17 
GeneralRe: False alarm? Plus non-client implementation of IconEdit Pin
David Pritchard20-Oct-04 10:38
memberDavid Pritchard20-Oct-04 10:38 
GeneralRe: False alarm? Plus non-client implementation of IconEdit Pin
Johan Rosengren21-Oct-04 9:17
memberJohan Rosengren21-Oct-04 9:17 
GeneralControls-in-controls: An edit box with an icon Pin
Larsson23-Sep-04 23:49
memberLarsson23-Sep-04 23:49 
GeneralRe: Controls-in-controls: An edit box with an icon Pin
Johan Rosengren24-Sep-04 0:20
memberJohan Rosengren24-Sep-04 0:20 
Generalfor an in depth discussion see also... Pin
RuskieF19-Jun-04 4:13
memberRuskieF19-Jun-04 4:13 
GeneralRe: for an in depth discussion see also... Pin
Johan Rosengren19-Jun-04 4:19
memberJohan Rosengren19-Jun-04 4:19 
GeneralA tiny, tiny painting correction Pin
David Pritchard10-Jun-04 11:12
memberDavid Pritchard10-Jun-04 11:12 
GeneralRe: A tiny, tiny painting correction Pin
Johan Rosengren10-Jun-04 11:16
memberJohan Rosengren10-Jun-04 11:16 
GeneralBug! SetIcon(HICON) Pin
David Pritchard27-May-04 4:15
memberDavid Pritchard27-May-04 4:15 
GeneralRe: Bug! SetIcon(HICON) Pin
Johan Rosengren27-May-04 4:55
memberJohan Rosengren27-May-04 4:55 
GeneralRe: Bug! SetIcon(HICON) Pin
David Pritchard27-May-04 11:44
memberDavid Pritchard27-May-04 11:44 
GeneralRe: Bug! SetIcon(HICON) Pin
Johan Rosengren27-May-04 20:09
memberJohan Rosengren27-May-04 20:09 
GeneralRe: Bug! SetIcon(HICON) Pin
David Pritchard28-May-04 13:02
memberDavid Pritchard28-May-04 13:02 
GeneralRe: Bug! SetIcon(HICON) Pin
Johan Rosengren28-May-04 22:38
memberJohan Rosengren28-May-04 22:38 
GeneralRe: Bug! SetIcon(HICON) Pin
David Pritchard29-May-04 5:01
memberDavid Pritchard29-May-04 5:01 
GeneralRe: Bug! SetIcon(HICON) Pin
Johan Rosengren29-May-04 5:27
memberJohan Rosengren29-May-04 5:27 
David Pritchard wrote:
I haven't looked at any alternative implementations of the icon-in-edit combo, but I did notice comments from people saying that they handled it through non-client painting. Might that be simpler than the CWnd/Edit/icon approach in this case?

As a matter of fact, I think it is. I made an investigation on what was necessary for a password implementation. Trapping keypresses, pasting, SetWindowText... keep an internal string with the actual contents. Also, copy/cut will have to copy/cut from the internal string instead. Create a dummy password edit and get the default password character.

This is not exactly rocket science, but the big problem is replacing the character. How is the class supposed, when handling WM_SETTEXT, to know if the string is supposed to be added to the internal string or to the control itself? Imagine the case where a user types password characters into the edit... No, the non-client rect would probably be a better choice.
GeneralRe: Some comments Pin
Johan Rosengren10-Mar-04 9:23
memberJohan Rosengren10-Mar-04 9:23 
Generalthe ES_MULTILINE issue Pin
.dan.g.10-Mar-04 0:47
professional.dan.g.10-Mar-04 0:47 

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

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

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web03 | 2.8.190214.1 | Last Updated 17 Jun 2004
Article Copyright 2004 by Johan Rosengren
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid