In my project, I needed a graph to display data. My colleague suggested me to go for a custom graph control. I surfed the net but didn’t find any good and interesting material on creating my own custom controls in Win32. So finally, I decided to take a step and wrote this article. To make things more interesting, I have created a DLL so as to reuse the same control in future projects. The control is developed in C. The main aim of the project is re-usability. You can draw any number of graphs / process bars by differentiating the graph number and the custom control ID.
This is a very simple application and I have given step by step instructions on how to create your custom control. This project contains two applications.
- Graph_dll - A DLL which is used to draw the graph and the process bar.
- Sun_Check_dll - A sample application which describes how to use the DLL.
The Graph_dll is a DLL which provides several functionalities.
Graph Creation Routine
void DrawGraph(HDC hdc, RECT Rect);
DrawGraph routine is used to draw a graph using the specified device context. The graph size is specified using the
Rect parameter. Also, the graph’s vertical movement is implemented in this routine.
void UpdateGraph(HDC hdc, RECT Rect, unsigned long RxValue,
unsigned long TxValue, int GraphNo);
UpdateGraph routine will plot the graph for 30 points horizontal. This can plot only two lines. The value which is specified as ‘
RxValue’ will be plotted with green color and the ‘
TxValue’ value with red color. The parameter ‘
GraphNo’ is nothing but the graph ID, used to identify the graph and to plot the value on the specified graph.
Processbar Creation Routine
void DrawBar(HDC hdc, RECT Rect, int Process_Value);
DrawBar routine is used to design the process bar in a percentage (%) basis. The second parameter ‘
Process_Value’ contains the percentage value. Based on that, the process bar will be filled with green color.
Registering the Global Class
This routine will register a class name called "
Custom_Control", globally, using the
RegisterClassEx API, with a callback function called
CustGraphWindowProc. This callback function contains two user defined messages,
WM_USER_PROCESS_BAR. When you want to draw the graph, you have to send the
WM_USER_GRAPH message. The
WM_USER_PROCESS_BAR message has to be sent when we need to draw the process bar.
Sun_Check_dll, a simple demo application, explains the use of the custom graph control and the process bar DLL. Some garbage values are selected randomly to display the animated graph and the process bar in this demo application. In this application, two custom controls (
IDC_CUSTOM2) are placed in the dialog and given the same class name “
WM_USER_GRAPH message is sent with the data structure (
User_Data) as a reference with the
LPARAM parameter. And for
WM_USER_PROCESS_BAR message is sent to update the process bar with the percentage value. This message is sent on a timer interval of 1000 ms.
Using the Code
To use the above functionalities (DLL), first copy the DLL and place it in your workspace folder. Then, create a dialog, select the custom control from the control toolbar, and place it in the dialog. Select the properties of the custom control, and change the "class" attribute to "Custom_Control".
Now, send the user defined message
WM_USER_PROCESS_BAR using the
Message for Drawing the Graph
(WPARAM) NULL, (LPARAM) &User_Data);
Before sending the above message, the data has to be formatted with the data structure shown below:
Unsigned long RxValue;
Unsigned long TxValue;
Unsigned int GraphNo;
RxValue - Plot graph in green color.
TxValue - Plot graph in red color.
GraphNo - Graph ID (Identifies the graph to plot the current data).
User_Data.GraphNo = 0;
User_Data.RxValue = 10;
User_Data.TxValue = 100;
This data has to be send with the
LPARAM parameter as a reference.
Message for Drawing the Processbar
SendDlgItemMessage(hdlg, (int) IDC_CUSTOM1, WM_USER_PROCESS_BAR ,
(WPARAM) NULL, (LPARAM) Process_Value);
Process_Value is the data for drawing the process bar. This also should be send with
LPARAM. Since it is an ‘
int’ value, we can directly send the data, not the reference.
- Note 1: To redraw / repaint the custom control, the message has to be sent again with the latest values.
- Note 2: A custom control can also be drawn with the ‘
CreateWindow’ API by using the "
Custom_Contol" class name.