分类: C/C++
2008-09-14 20:03:18
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.
The Graph_dll is a DLL which provides several functionalities.
void DrawGraph(HDC hdc, RECT Rect);
The 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);
The 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.
void DrawBar(HDC hdc, RECT Rect, int Process_Value);
The 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.
void InitCustGraph();
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_GRAPH
and 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_CUSTOM1
and IDC_CUSTOM2
) are placed in the dialog and given the same class name “Custom_Control
”. For IDC_CUSTOM1
, the WM_USER_GRAPH
message is sent with the data structure (User_Data
) as a reference with the LPARAM
parameter. And for IDC_CUSTOM2
, the 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.
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_GRAPH
/ WM_USER_PROCESS_BAR
using the SendDlgItemMessage
API.
SendDlgItemMessage(hdlg,(int)IDC_CUSTOM1,WM_USER_GRAPH,
(WPARAM) NULL, (LPARAM) &User_Data);
Before sending the above message, the data has to be formatted with the data structure shown below:
struct lp { Unsigned long RxValue; Unsigned long TxValue; Unsigned int GraphNo; }User_Data;
RxValue
- Plot graph in green color.
TxValue
- Plot graph in red color.
GraphNo
- Graph ID (Identifies the graph to plot the current data). Example:
//(Specified the current value for Graph No : 0) User_Data.GraphNo = 0; //(Dynamically changeable) User_Data.RxValue = 10; //(Dynamically changeable) User_Data.TxValue = 100;
This data has to be send with the LPARAM
parameter as a reference.
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.
CreateWindow
’ API by using the "Custom_Contol
" class name.