<!-- Download Links -->
<!-- Add the rest of your HTML here -->

Initial idea
The initial idea for doing this code was put into my mind when my love asked me
to go to a clinic in order to check out my heart. You know, doctors have got some
sort of plotters that plot the information obtained from the heart on a piece of
paper as a histogram. The idea came into my mind from there! This control
is sincerely dedicated to my love, Cindy.
How to use:
To use the control, you import the header file as well as the .cpp file attached to this article.
Then you simply open the dialog editor and place a rectangle on your dialog. We call this static control
IDC_STATIC_HISTOGRAM
. Thereafter, you instantiate an object of the
CHistogramCtrl
class, say m_ctrlHistogram
, as a data member of your dialog class.
In the message handler of the WM_INITDIALOG
message, you get the area of the static rectangle you already placed on
your dialog box and you simply create the Histogram Control as follows:
CRect rect;
GetDlgItem(IDC_STATIC_HISTOGRAM)->GetWindowRect(rect);
ScreenToClient(rect);
m_ctrlHistogram.Create(WS_VISIBLE | WS_CHILD
| WS_TABSTOP, rect, this, IDC_STATIC_HISTOGRAM);
After doing this, the histogram's window is shown
on screen in the default colors assigned to the control within the constructor
of the class. For example, the background color of the control is held in the
m_crBackGround
member variable of the class and is assigned to the color black
in the constructor of the CHistogramCtrl
. The other member variable, m_crGrids
holds the grid color and is assigned to RGB(0, 130, 66)
in the constructor of
the class.
What if we would like to change the grid color to red? Shall we alter the mentioned variables within
the constructor? Of course, not! To do so, I've created a method, SetGridsColor
,
prototyped as follows:
BOOL CHistogramCtrl::SetGridsColor(COLORREF cr);
Where cr is the grids' color reference. For
example, you can change the color of grids to red this way:
m_ctrlHistogram.SetGridsColor(RGB(255, 0, 0));
Here are the other methods of the class that can
be used to change the default behavior of the control:
BOOL CHistogramCtrl::SetBkColor(COLORREFcr);
void CHistogramCtrl::SetPen(int nWidth, COLORREF crColor);
void CHistogramCtrl::SetRange(UINT uLower, UINT uUpper);
CHistogramCtrl::SPEED SetSpeed(CHistogramCtrl::SPEED uSpeed);
void CHistogramCtrl::SetPos(UINT uPos);</td>
Although the method names clarifies their
purposes, it makes sense if we have a quick look at what each one is
useful for.
The first above-mentioned method, SetBkColor
,
is used to set the background color of the control. The default value is black,
i.e. RGB(0, 0, 0)
, declared in the constructor of the class.
The second method is used to set the control's
pen, the one that's used to draw the histogram. The first parameter, nWidth
, is
used to set the width of the line. The second parameter, crColor
, is a COLORREF
that sets the color of the pen. If you don't use this
function, the default values are used, 1 as the pen width, and RGB(0, 255, 0)
as
the pen's color.
The third method, SetRange
, is used to set the upper and lower limits (range)
of the control. The valid range for these arguments is as follows:
- uLower > 0
- uUpper > 0
- uLower < uUpper
Please note that the range will be set to
1-100 if you don't specify a range - i.e. you can plot numbers between 1 to
100.
Now let's move from SetRange
to the next
method, SetSpeed
. This is used to control the refresh speed of CHistogramCtrl
.
Let me say that the window contents are shifted 3 pixels to the left within the
specified intervals. There are 4 predefined intervals declared as an enum
as
follows:
- LOW_SPEED (3000 ms)
- NORMAL_SPEED (1000 ms; default value)
- HIGH_SPEED (500 ms)
- IDLE (0 ms)
To use this function, all you've to do is as follows:
m_ctrlHistogram.SetSpeed(CHistogramCtrl::HIGH_SPEED);</td>
This way, the contents of the control is
shifted 3 pixels to the left at 500ms intervals.
Now it is time to turn our attention to the
last public method of the class, SetPos
, declared as follows:
void CHistogramCtrl::SetPos(UINT uPos);
This member function does the actual plotting. For example, to set the current position of the
histogram to 26 you can easily write the following statement:
m_ctrlHistogram.SetPos(26);
Now imagine what happens if you set the
position of the histogram to 87 ten seconds later. You'll see a histogram as
follows:

In other words, there will be no change in the
line if we don't feed the control with new values. But what happens if we feed
the control more than it can show? For example, imagine that we've set the
speed of the control to HIGH_SPEED
(500ms) and we feed the control 20 times
within the 500ms. Which value is shown at the end of the first 500ms?
To solve this problem, I created a CList
as a
private data member of CHistogramCtrl
. Whenever you call SetPos
, I append the
value you provide to the mentioned list. Whenever I want to refresh the control
(at the end of each 500ms in our example), I process the list and obtain the
average value of the current values within the list. To clarify what I'm talking
about, imagine that we set the current position of the control to the following
values within the first 500ms:
10, 87, 19, 54, 63, 74
When this time elapses, I process the current
values within the list and calculate the average of the list members:
10 + 87 + 19 + 54 +63 + 74 = 307
307 / 6 = 51.1
And I show 51.1 as the current value... Got it?
This is done via one of the private methods
of the class called, GetAverage
, that returns the average of numbers within the
mentioned list. In some cases, you have to change the mechanism of calculating
the current position of the control within the refresh intervals with your
desired one. For example, I've used the variance of the numbers instead of their
average in my latest project. Please note that the function is called within the DrawLine
method to obtain a value to show at the end of each period.
Since the source code is straight forward and
easy to understand this article is finished now. Please feel free to send your
comments, questions and/or suggestions about this control to "mehdi_mousavi@hotmail.com",
the author of many popular articles on the net; and the latest one, MODEMMANIA.
- Aloha!