Click here to Skip to main content
15,893,381 members
Articles / Desktop Programming / MFC
Article

CPercentageCtrl

Rate me:
Please Sign up or sign in to vote.
4.47/5 (9 votes)
20 Mar 2002CPOL2 min read 81.1K   1.5K   27   12
An easy control to display and to modify percentages

Sample Image - PercentageCtrl.gif

Introduction

CPercentageCtrl is an easy control to display the ratio between many entities, as the used space and the free space, or the composition of a cocktail :)

Obviously user can modify ratios dragging the blocks' edges.

Using the control

Add an instance of the control as member data in your dialog;
class CMyDialog : public CDialog
{
    ...
    CPercentageCtrl m_percentage;
    ...
}

Then initialize the control in OnInitDialog() using the Create(...) function

BOOL CMyDialog::OnInitDialog()
{
    ...
    CRect r(10,10, 200, 50);
    m_percentage.Create(NULL, NULL, WS_VISIBLE | WS_BORDER, r, 
                           this, ID_PERCENTAGE);
    ...
}

To add a block is really easy, you must only specify its weight:

m_percentage.AddBlock(250);

In any block you can select the color and a text to be displayed: the text can be formatted using CString::Format(...) (or printf) style, the color is the usual RGB value

m_percentage.AddBlock(250, "%0.1f%%", RGB(200,255,255));

Blocks' dimension must be an integer value, but you can set a double multiplier that is used to display the text. For example, if you want to show the value as "25.1" you should insert a 251 dimension and set the multiplier to 0.1

m_percentage.AddBlock(251);
m_percentage.SetMultiplier(0.1);

Some options are available:

  • PC_HORIZONTAL (default) or PC_VERTICAL
  • PC_VERTICALTEXT (default) or PC_HORIZONTALTEXT
  • PC_READONLY
  • PC_ALWAYSSHOWTEXT: the control will show the text even if it is not completely contained in the block; otherwise the control display text only if it is completely contained in his block.
  • PC_TEXTELLIPSIS: if it's needed, the control does a text ellipsis to shorten the text as it could be contained in the block.
You can set these options using the command SetOptions(int):
m_percentage.SetOptions(PC_HORIZONTAL | PC_ALWAYSSHOWTEXT);

Any time that the user modifies the dimension of a block, the control sends a message. You can intercept this message inserting in the messages map the macro:

<code>ON_REGISTERED_MESSAGE(PERCENTAGE_CHANGED,FunctionName)</code>

For example:

BEGIN_MESSAGE_MAP(CPercentageCtrlDemoDlg, CDialog)
    //{{AFX_MSG_MAP(CPercentageCtrlDemoDlg)
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    //}}AFX_MSG_MAP
    ON_REGISTERED_MESSAGE(PERCENTAGE_CHANGED,OnPercentageChanged)
END_MESSAGE_MAP()
In this case remember to declare the message PERCENTAGE_CHANGED in this way:
extern const UINT PERCENTAGE_CHANGED;
The called function will receive in WPARAM the handle of the calling control, and in LPARAM the index of the first modified block (when a user modifies a block, he modifies also that one at its right). The OnPercentageChanged function could be:
LRESULT MyDialog::OnPercentageChanged(WPARAM WParam, LPARAM LParam)
{
    if ((HWND)WParam == m_percentage.m_hWnd)
    {
        int data1 = m_percentage.GetData((int)LParam);
        int data2 = m_percentage.GetData((int)LParam+1);
        ....
    }
}

Developing notes

I chose to allow the insertion of entire values with a multiplier in order to avoid errors of approximation in the visualization of the text
(e.g. 99 = 24 + 24 + 24 + 27 = 24.4 + 24.4 + 24.4 + 26.8 = 100 = 24.6 + 24.6 + 24.6 + 26.2 = 25 + 25 + 25 + 26 = 101)

I used Keith Rule's CMemDC to avoid flickering. You can find his class and an article here at codeproject :)

Obviously the code compiles cleanly under the warning level 4 :)

History

21 Mar 2002 - serious GDI resources leaks fixed.

License

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


Written By
Software Developer (Senior) Ermit
Italy Italy
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
MURALEE KRISHNAN N28-Nov-12 8:26
MURALEE KRISHNAN N28-Nov-12 8:26 
GeneralThank you very much for this workspace posting Pin
MURALEE KRISHNAN N28-Nov-12 8:25
MURALEE KRISHNAN N28-Nov-12 8:25 
GeneralVery cool! Suggestion though: Pin
ajhuddy2-May-03 17:32
ajhuddy2-May-03 17:32 
GeneralGreat Control ! Pin
DizzyMissLizzy11-Dec-02 23:00
sussDizzyMissLizzy11-Dec-02 23:00 
GeneralThis control rules Pin
Mark Cooper23-May-02 15:46
Mark Cooper23-May-02 15:46 
GeneralThank you! Pin
sport26-Apr-02 0:01
sport26-Apr-02 0:01 
Generalnice! Pin
Mazdak13-Mar-02 3:05
Mazdak13-Mar-02 3:05 
GeneralVery clever control, but it crashes Pin
flector12-Mar-02 12:53
flector12-Mar-02 12:53 
If you drag one bar all the way to another and back 10-15 times, it crashes your demo app.
GeneralRe: Very clever control, but it crashes Pin
PJ Arends12-Mar-02 16:31
professionalPJ Arends12-Mar-02 16:31 
GeneralRe: Very clever control, but it crashes Pin
ilinov12-Mar-02 21:10
ilinov12-Mar-02 21:10 
GeneralRe: Very clever control, but it crashes Pin
Paolo Vernazza22-Mar-02 1:39
Paolo Vernazza22-Mar-02 1:39 
GeneralGreat job! Pin
Alexander Wiseman12-Mar-02 10:06
Alexander Wiseman12-Mar-02 10:06 

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.