The article explains how to integrate my Graphical Status display control (
CStatusGraphCtrl) with your application. Many real-time applications will have a requirement to update the user with the current value of some of the critical parameters related to that application;
CStatusGraphCtrl not only displays the values but also shows the progress of the change in the parameter as a graph. Currently, it supports Bar Graph and Line Graph displays. You may customize the code to support your own way of graphs, if required. The control is exactly similar to the one you see in the Windows Task Manager to display the CPU and memory usage.
Using the code
CStatusGraphCtrl source (zip) will include the following files:
These four files are the core files for the control. Add these four files into your VC++ application project.
CGraphData class acts as a holder for the data that is currently shown in the control's viewport. The data is held inside as a linear singly linked list.
CStatusGraphCtrl class is the core control class that is derived from
CWnd MFC Class. To create a
CStatusGraphCtrl control into your dialog, call
CStatusGraphCtrl::Create in your Dialog's
CDialog::OnCreate as follows:
This creates a
StatusGraphCtrl in the desired position. Once the control is created, you need to specify the values for a few properties of the control using:
SetMinValue is called to specify the value of the bottom-most line in the control's viewport.
SetMaxValue is called to specify the value of the top-most line in the control's viewport.
SetSamplingInterval is called to specify the horizontal distance (in pixels) between successive plots. When everything is ready, call
CStatusGraphCtrl::StartUpdate to put the control into action. Once
StartUpdate is called, any call to
CStatusGraphCtrl::SetCurrentValue will be reflected in the graph seen in the control's viewport.
The graph keeps scrolling from right to left. The delay between each scroll can be controlled by calling
CStatusGraphCtrl::SetRefreshDelay with the required delay in milliseconds as argument.
The following block of code is taken from my DemoApp for this control and would give a simple code to make use of the
CStatusGraphCtrl control in your application.
void DataGenerator(LPVOID param)
CStatusGraphCtrl* pCtrl = (CStatusGraphCtrl*)param;
int nRand = rand();
while(nRand > pCtrl->GetMaxValue())
nRand /= 10;
int CDemoDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
Almost every aspect of
CStatusGraphCtrl is customizable. The following are the list of properties which you can customize as per your requirements:
SamplingInterval - call
SetSamplingInterval(short) - horizontal distance in pixels between successive plots
RefreshDelay - call
SetRefreshDelay(int) - Delay in milliseconds between successive scrolls
- Background color - access the public member
- Foreground color - access the public member
Adding custom GraphModes
To add your own
GraphMode, all you need to do is just two steps. Update the
enum StatusGraphType to add entry for your new
GraphType in CStatusGraphCtrl.h header file. Then add the code to draw the graph, in
DrawPoint function in CStatusGraphCtrl.cpp file. See this code snippet:
void DrawPoint(CStatusGraphCtrl* TheCtrl,long int cury,bool Update)
CStatusGraphCtrl is written in such a way that it sends a
WM_COMMAND message when a mouse is clicked on the control. The application shall make use of this, as required. For example, in my DemoApp, I have added the functionality of changing the graph mode of
CStatusGraphCtrl in the
ON_COMMAND handler of the control. See the handler code:
Points of Interest
I will tell you the way I brought up this code. I was coding a networking utility to monitor the network traffic and control excessive traffic from a single source, wherein I wanted a control like this. I started with the
BS_OWNERDRAW feature of Button and happily coded with
CDC for the requirement. This code uses
CDC::BitBlt to perform the scrolling of the Graph and so is very fast and flicker-free. I was almost done, and checked the various functionalities for the control. Till then, I hadn't tried switching between applications when my application was running. And, the problem came in when switched across apps.... When I switched back to my application, the entire Graph was gone!!!!! Ooops, I didn't have necessary information left in my memory to repaint the Graph. That is when I added the new class
CGraphData which stores data associated with the current viewport of the control. The data structure stores only the sequence of points and not the entire viewport pixel matrix. In fact, the scrolling happens in the data structure too. For every new value in the right, the value in the left will be deleted, thereby maintaining the window size.
Thanks to CodeProject members: I got feedback about my code, the first day I submitted this article; from which I could feel that use of
CButton for this control is not at all necessary; I modified the code immediately and I am posting it here. Now the control is no longer using
CButton. Its just a Window.
- First version of
CStatusGraphCtrl was derived from
- Based on the feedback from CodeProject members, I modified the code to derive from