Solved

How do I display a bitmap over a button.

Posted on 2001-06-12
14
466 Views
Last Modified: 2013-12-02

I would like to add a bitmap to a button dynamically. I know that with the help of LoadBitmap we can add load the bitmap on to the button control. But there is a problem with that approach. When I change the system fonts from small to large then only the button on the dialog will get enlarged and the bitmap is not scaling to the size of the button.

I want the bitmap to get enlarged or I will put it this way. I want the display of the bitmap to be same even when the system wide fonts are changed from small to large.

If some can give me some idea regarding this it would be very much helpful to me.


Thanks in advance.
Gangisetti.
0
Comment
Question by:gangisetti
  • 6
  • 3
  • 2
  • +3
14 Comments
 
LVL 6

Expert Comment

by:MichaelS
ID: 6181819
May be it's easy to catch when display setting got changed and than resize your bitmap?
0
 

Expert Comment

by:ganeshramaswamy
ID: 6182382
please refer www.codeproject.com.
Bitmap button wrapper classes are provided there.
0
 

Accepted Solution

by:
SrinivasaRao earned 100 total points
ID: 6185741
You can use CBitmapButton in MFC . Follow the below steps:

1 . Select a button from the resources and set the         property "OWNERDRAW" in the style propertysheet.
 2.The Id name for the control should be same for bitmap.For example ID_MYBUTTON
 3. The bitmap id must be between double quotes. eg : "MYBUTTONU".You will be wondering what is this 'U' at the end of the bitmap name. Rest can be found in MSDN.

All the Best
BSR

0
 
LVL 1

Author Comment

by:gangisetti
ID: 6186426
srinivas,

can u send me the URL of that MSDN link..
0
 
LVL 1

Author Comment

by:gangisetti
ID: 6186430
thanks srinivas,

can u please send me the URL of that MSDN link..
0
 

Expert Comment

by:SrinivasaRao
ID: 6189523
Hai,
  I am sorry, that I am not aware of link. I installed msdn in my system. Here i am providing the whole information. Please go through it. Bye
BSR

************************
CBitmapButton


Use the CBitmapButton class to create pushbutton controls labeled with bitmapped images instead of text. CBitmapButton objects contain up to four bitmaps, which contain images for the different states a button can assume: up (or normal), down (or selected), focused, and disabled. Only the first bitmap is required; the others are optional.

Bitmap-button images include the border around the image as well as the image itself. The border typically plays a part in showing the state of the button. For example, the bitmap for the focused state usually is like the one for the up state but with a dashed rectangle inset from the border or a thick solid line at the border. The bitmap for the disabled state usually resembles the one for the up state but has lower contrast (like a dimmed or grayed menu selection).

These bitmaps can be of any size, but all are treated as if they were the same size as the bitmap for the up state.

Various applications demand different combinations of bitmap images:

Up Down Focused Disabled Application
?    Bitmap
? ?   Button without WS_TABSTOP style
? ? ? ? Dialog button with all states
? ? ?  Dialog button with WS_TABSTOP style


When creating a bitmap-button control, set the BS_OWNERDRAW style to specify that the button is owner-drawn.  This causes Windows to send the WM_MEASUREITEM and WM_DRAWITEM messages for the button; the framework handles these messages and manages the appearance of the button for you.

To create a bitmap-button control in a window?s client area, follow these steps:

Create one to four bitmap images for the button.


Construct the CBitmapButton object.


Call the Create function to create the Windows button control and attach it to the CBitmapButton object.


Call the LoadBitmaps member function to load the bitmap resources after the bitmap button is constructed.
To include a bitmap-button control in a dialog box, follow these steps:

Create one to four bitmap images for the button.


Create a dialog template with an owner-draw button positioned where you want the bitmap button. The size of the button in the template does not matter.


Set the button?s caption to a value such as ?MYIMAGE? and define a symbol for the button such as IDC_MYIMAGE.


In your application?s resource script, give each of the images created for the button an ID constructed by appending one of the letters ?U,? ?D,? ?F,? or ?X? (for up, down, focused, and disabled) to the string used for the button caption in step 3. For the button caption ?MYIMAGE,? for example, the IDs would be ?MYIMAGEU,? ?MYIMAGED,? ?MYIMAGEF,? and ?MYIMAGEX.? You must specify the ID of your bitmaps within double quotes. Otherwise the resource editor will assign an integer to the resource and MFC will fail when loading the image.


In your application?s dialog class (derived from CDialog), add a CBitmapButton member object.


In the CDialog object?s OnInitDialog routine, call the CBitmapButton object?s AutoLoad function, using as parameters the button?s control ID and the CDialog object?s this pointer.
If you want to handle Windows notification messages, such as BN_CLICKED, sent by a bitmap-button control to its parent (usually a class derived from CDialog), add to the CDialog-derived object a message-map entry and message-handler member function for each message. The notifications sent by a CBitmapButton object are the same as those sent by a CButton object.

The class CToolBar takes a different approach to bitmap buttons.

For more information on CBitmapButton, seeControl Topics in Visual C++ Programmer's Guide.

#include <afxext.h>

Class Members |  Base Class |  Hierarchy Chart

Sample   MFC Sample CTRLTEST
-----------------------CBitmapButton Class Members
Construction

CBitmapButton Constructs a CBitmapButton object.
LoadBitmaps Initializes the object by loading one or more named bitmap resources from the application?s resource file and attaching the bitmaps to the object.
AutoLoad Associates a button in a dialog box with an object of the CBitmapButton class, loads the bitmap(s) by name, and sizes the button to fit the bitmap.


Operations

SizeToContent Sizes the button to accommodate the bitmap.


CBitmapButton Overview |  Base Class Members |  Hierarchy Chart
--------------------------
CBitmapButton::CBitmapButton
CBitmapButton( );

Remarks

Creates a CBitmapButton object.

After creating the C++ CBitmapButton object, call CButton::Create to create the Windows button control and attach it to the CBitmapButton object.

CBitmapButton Overview |  Class Members |  Hierarchy Chart

See Also   CBitmapButton::LoadBitmaps, CBitmapButton::AutoLoad, CBitmapButton::SizeToContent, CButton::Create
---------------------------------

CBitmapButton::LoadBitmaps
BOOL LoadBitmaps( LPCTSTR lpszBitmapResource, LPCTSTR lpszBitmapResourceSel = NULL, LPCTSTR lpszBitmapResourceFocus = NULL, LPCTSTR lpszBitmapResourceDisabled = NULL );

BOOL LoadBitmaps( UINT nIDBitmapResource, UINT nIDBitmapResourceSel = 0, UINT nIDBitmapResourceFocus = 0, UINT nIDBitmapResourceDisabled = 0 );

Return Value

Nonzero if successful; otherwise 0.

Parameters

lpszBitmapResource

Points to the null-terminated string that contains the name of the bitmap for a bitmap button?s normal or ?up? state. Required.

lpszBitmapResourceSel

Points to the null-terminated string that contains the name of the bitmap for a bitmap button?s selected or ?down? state. May be NULL.

lpszBitmapResourceFocus

Points to the null-terminated string that contains the name of the bitmap for a bitmap button?s focused state. May be NULL.

lpszBitmapResourceDisabled

Points to the null-terminated string that contains the name of the bitmap for a bitmap button?s disabled state. May be NULL.

nIDBitmapResource

Specifies the resource ID number of the bitmap resource for a bitmap button?s normal or ?up? state. Required.

nIDBitmapResourceSel

Specifies the resource ID number of the bitmap resource for a bitmap button?s selected or ?down? state. May be 0.

nIDBitmapResourceFocus

Specifies the resource ID number of the bitmap resource for a bitmap button?s focused state. May be 0.

nIDBitmapResourceDisabled

Specifies the resource ID number of the bitmap resource for a bitmap button?s disabled state. May be 0.

Remarks

Use this function when you want to load bitmap images identified by their resource names or ID numbers, or when you cannot use the AutoLoad function because, for example, you are creating a bitmap button that is not part of a dialog box.

CBitmapButton Overview |  Class Members |  Hierarchy Chart

See Also   CBitmapButton::AutoLoad, CBitmapButton::SizeToContent, CButton::Create, CBitmap::LoadBitmap
-------------------------------------
CBitmapButton::AutoLoad
BOOL AutoLoad( UINT nID, CWnd* pParent );

Return Value

Nonzero if successful; otherwise 0.

Parameters

nID

The button?s control ID.

pParent

Pointer to the object that owns the button.

Remarks

Associates a button in a dialog box with an object of the CBitmapButton class, loads the bitmap(s) by name, and sizes the button to fit the bitmap.

Use the AutoLoad function to initialize an owner-draw button in a dialog box as a bitmap button. Instructions for using this function are in the remarks for the CBitmapButton class.

CBitmapButton Overview |  Class Members |  Hierarchy Chart

See Also   CBitmapButton::LoadBitmaps, CBitmapButton::SizeToContent
--------------------------------

CBitmapButton::SizeToContent
void SizeToContent( );

Remarks

Call this function to resize a bitmap button to the size of the bitmap.

CBitmapButton Overview |  Class Members |  Hierarchy Chart

See Also   CBitmapButton::LoadBitmaps, CBitmapButton::AutoLoad
--------------------------------
TN062: Message Reflection for Windows Controls
This technical note describes message reflection, a new feature in MFC 4.0. It also contains directions for creating a simple reusable control that uses message reflection.

This technical note does not discuss message reflection as it applies to ActiveX controls (formerly called OLE controls). Please see the articleActiveX Controls: Subclassing a Windows Control in Visual C++ Programmer's Guide.

What Is Message Reflection?

Windows controls frequently send notification messages to their parent windows. For instance, many controls send a control color notification message (WM_CTLCOLOR or one of its variants) to their parent to allow the parent to supply a brush for painting the background of the control.

In Windows and in MFC prior to version 4.0, the parent window, often a dialog box, is responsible for handling these messages. This means that the code for handling the message needs to be in the parent window?s class and that it has to be duplicated in every class that needs to handle that message. In the case above, every dialog box that wanted controls with custom backgrounds would have to handle the control color notification message. It would be much easier to reuse code if a control class could be written that would handle its own background color.

In MFC 4.0, the old mechanism still works?parent windows can handle notification messages. In addition, however, MFC 4.0 facilitates reuse by providing a feature called ?message reflection? that allows these notification messages to be handled in either the child control window or the parent window, or in both. In the control background color example, you can now write a control class that sets its own background color by handling the reflected WM_CTLCOLOR message?all without relying on the parent. (Note that since message reflection is implemented by MFC, not by Windows, the parent window class must be derived from CWnd for message reflection to work.)

Older versions of MFC did something similar to message reflection by providing virtual functions for a few messages, such as messages for owner-drawn list boxes (WM_DRAWITEM, and so on). The new message reflection mechanism is generalized and consistent.

Message reflection is backward compatible with code written for versions of MFC previous to 4.0.

If you have supplied a handler for a specific message, or for a range of messages, in your parent window's class, it will override reflected message handlers for the same message provided you don't call the base class handler function in your own handler. For example, if you handle WM_CTLCOLOR in your dialog box class, your handling will override any reflected message handlers.

If, in your parent window class, you supply a handler for a specific WM_NOTIFY message or a range of WM_NOTIFY messages, your handler will be called only if the child control sending those messages does not have a reflected message handler through ON_NOTIFY_REFLECT(). If you use ON_NOTIFY_REFLECT_EX() in your message map, your message handler may or may not allow the parent window to handle the message. If the handler returns TRUE, the message will be handled by the parent as well, while a call that returns FALSE does not allow the parent to handle it. Note that the reflected message is handled before the notification message.

When a WM_NOTIFY message is sent, the control is offered the first chance to handle it. If any other reflected message is sent, the parent window has the first chance to handle it and the control will receive the reflected message. To do so, it will need a handler function and an appropriate entry in the control's class message map.

The message-map macro for reflected messages is slightly different than for regular notifications: it has _REFLECT appended to its usual name. For instance, to handle a WM_NOTIFY message in the parent, you use the macro ON_NOTIFY in the parent?s message map. To handle the reflected message in the child control, use the ON_NOTIFY_REFLECT macro in the child control?s message map. In some cases, the parameters are different, as well. Note that ClassWizard can usually add the message-map entries for you and provide skeleton function implementations with correct parameters.

See TN061: ON_NOTIFY and WM_NOTIFY Messages for information on the new WM_NOTIFY message.

Message-Map Entries and Handler Function Prototypes for Reflected Messages

To handle a reflected control notification message, use the message-map macros and function prototypes listed in the table below.

ClassWizard can usually add these message-map entries for you and provide skeleton function implementations. SeeDefining a Message Handler for a Reflected Message in the Visual C++ Programmer's Guide for information about how to define handlers for reflected messages.

To convert from the message name to the reflected macro name, prepend ON_ and append _REFLECT. For example, WM_CTLCOLOR becomes ON_WM_CTLCOLOR_REFLECT. (To see which messages can be reflected, do the opposite conversion on the macro entries in the table below.)

The three exceptions to the rule above are as follows:

The macro for WM_COMMAND notifications is ON_CONTROL_REFLECT.


The macro for WM_NOTIFY reflections is ON_NOTIFY_REFLECT.


The macro for ON_UPDATE_COMMAND_UI reflections is ON_UPDATE_COMMAND_UI_REFLECT.
In each of the above special cases, you must specify the name of the handler member function. In the other cases, you must use the standard name for your handler function.

The meanings of the parameters and return values of the functions are documented under either the function name or the function name with On prepended. For instance, CtlColor is documented in OnCtlColor. Several reflected message handlers need fewer parameters than the similar handlers in a parent window. Just match the names in the table below with the names of the formal parameters in the documentation.

Map entry Function prototype
ON_CONTROL_REFLECT( wNotifyCode, memberFxn ) afx_msg void memberFxn ( );
ON_NOTIFY_REFLECT( wNotifyCode, memberFxn ) afx_msg void memberFxn ( NMHDR * pNotifyStruct, LRESULT* result );
ON_UPDATE_COMMAND_UI_REFLECT( memberFxn ) afx_msg void memberFxn ( CCmdUI* pCmdUI );
ON_WM_CTLCOLOR_REFLECT( ) afx_msg HBRUSH CtlColor ( CDC* pDC, UINT nCtlColor );
ON_WM_DRAWITEM_REFLECT( ) afx_msg void DrawItem ( LPDRAWITEMSTRUCT lpDrawItemStruct );
ON_WM_MEASUREITEM_REFLECT( ) afx_msg void MeasureItem ( LPMEASUREITEMSTRUCT lpMeasureItemStruct );
ON_WM_DELETEITEM_REFLECT( ) afx_msg void DeleteItem ( LPDELETEITEMSTRUCT lpDeleteItemStruct );
ON_WM_COMPAREITEM_REFLECT( ) afx_msg int CompareItem ( LPCOMPAREITEMSTRUCT lpCompareItemStruct );
ON_WM_CHARTOITEM_REFLECT( ) afx_msg int CharToItem ( UINT nKey, UINT nIndex );
ON_WM_VKEYTOITEM_REFLECT( ) afx_msg int VKeyToItem ( UINT nKey, UINT nIndex );
ON_WM_HSCROLL_REFLECT( ) afx_msg void HScroll ( UINT nSBCode, UINT nPos );
ON_WM_VSCROLL_REFLECT( ) afx_msg void VScroll ( UINT nSBCode, UINT nPos );
ON_WM_PARENTNOTIFY_REFLECT( ) afx_msg void ParentNotify ( UINT message, LPARAM lParam );


The ON_NOTIFY_REFLECT and ON_CONTROL_REFLECT macros have variations that allow more than one object (such as the control and its parent) to handle a given message.

Map entry Function prototype
ON_NOTIFY_REFLECT_EX( wNotifyCode, memberFxn ) afx_msg BOOL memberFxn ( NMHDR * pNotifyStruct, LRESULT* result );
ON_CONTROL_REFLECT_EX( wNotifyCode, memberFxn ) afx_msg BOOL memberFxn ( );


Handling Reflected Messages: An Example of a Reusable control

This simple example creates a reusable control called CYellowEdit. The control works the same as a regular edit control except that it displays black text on a yellow background. It would be easy to add member functions that would allow the CYellowEdit control to display different colors.

To try this example, do the following steps:

Create a new dialog box in an existing application. For more information seedialog editor in the Visual C++ User?s Guide.
You must have an application in which to develop the reusable control. If you don?t have an existing application to use, create a dialog-based application using AppWizard.

With your project loaded into Visual C++, use ClassWizard to create a new class called CYellowEdit based on CEdit. Leave the ?Add to Component Gallery? box checked.


Add three member variables to your CYellowEdit class. The first two will be COLORREF variables to hold the text color and the background color. The third will be a CBrush object which will hold the brush for painting the background. The CBrush object allows you to create the brush once, merely referencing it after that, and to destroy the brush automatically when the CYellowEdit control is destroyed.


Initialize the member variables by writing the constructor as follows:
CYellowEdit::CYellowEdit()
{
m_clrText = RGB( 0, 0, 0 );
m_clrBkgnd = RGB( 255, 255, 0 );
m_brBkgnd.CreateSolidBrush( m_clrBkgnd );
}

Using ClassWizard, add a handler for the reflected WM_CTLCOLOR message to your CYellowEdit class. Note that the equal sign in front of the message name in the list of messages you can handle indicates that the message is reflected. This is described inDefining a Message Handler for a Reflected Message in the Visual C++ Programmer's Guide.
ClassWizard adds the following message-map macro and skeleton function for you:

ON_WM_CTLCOLOR_REFLECT()

// Note: other code will be in between....

HBRUSH CYellowEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
// TODO: Change any attributes of the DC here

// TODO: Return a non-NULL brush if the
//    parent's handler should not be called
return NULL;
}

Replace the body of the function with the following code. The code specifies the text color, the text background color, and the background color for rest of the control.
pDC->SetTextColor( m_clrText );    // text
pDC->SetBkColor( m_clrBkgnd );    // text bkgnd
return m_brBkgnd;                // ctl bkgnd

Create an edit control in your dialog box, then attach it to a member variable by double-clicking the edit control while holding a control key down. In the Add Member Variable dialog box, finish the variable name and choose ?Control? for the category, then ?CYellowEdit? for the variable type. Don?t forget to set the tab order in the dialog box. Also, be sure to include the header file for the CYellowEdit control in your dialog box?s header file.


Build and run your application. The edit control will have a yellow background.


You can now use Component Gallery to add your CYellowEdit control class to other projects.
Technical Notes by Number |  Technical Notes by Category
-----------------
All the Best
BSR


0
 
LVL 1

Author Comment

by:gangisetti
ID: 6189616
Thanx! srinivas. I will try this and let u know.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 30

Expert Comment

by:Axter
ID: 6199032
Hi gangisetti:
Feel free to click the [Reject Answer] button near (Answer-poster's)
response, even if it seems like a good answer.
Doing so will increase your chance of obtaining additional input from other
experts.  Later, you can click the [Select Comment as Answer] button on any
response.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6199034
Hi ganeshramaswamy, welcome to EE.

If you feel you have an answer, you can post it as a comment, and the
questioner can convert your comment to an answer if he/she thinks it's
correct or deserving of the awarded points.

There are many experts who never post answers as answer.  Instead, they
post their answers as comments.
If you read the following link, you'll see why this is the preferred method
for many of our valued experts, including myself.

http://www.experts-exchange.com/jsp/cmtyQuestAnswer.jsp

0
 
LVL 1

Author Comment

by:gangisetti
ID: 6201021
sorry ganeshramaswamy,

I couldn't find much of the information in that site.

As I was short of time, I havent gone thru some of the suggestions given by others and I will try that in next couple of days.
0
 
LVL 1

Author Comment

by:gangisetti
ID: 6201023
Axter, thanx for ur suggestion.
0
 

Expert Comment

by:SrinivasaRao
ID: 6201063
Hai gangisetti,
  Have you tried what i suggested. I worked with that. Hope you will come back.
bsr
0
 
LVL 1

Author Comment

by:gangisetti
ID: 6201086
Srinivas, I am looking at that. I will get back to u.
0
 
LVL 23

Expert Comment

by:Roshan Davis
ID: 9484638
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Answered by : SrinivasaRao

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Roshan Davis
EE Cleanup Volunteer
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Suggested Solutions

Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now