Use templates and callback functions to expand the control behavior of C ++ builder-to achieve reuse Purpose

Source: Internet
Author: User

When using C ++ builder, The VCL control provides us with convenient reuse. However, the control provided by a third party may not all meet our own needs. So sometimes I want to extend some behavior for third-party controls for reuse. Is there any way to do this?

The best way to expand the behavior of the VCL control is to change the VCL Code. However, if you are not familiar with Pascal, or try to use the C ++ method (C ++ builder is named C ++, and C ++ syntax is supported ).
So next we will try to use the C ++ method to expand the third-party controls.

The third-party controls used here are sui control sets. Here we will introduce this set: the main function of this control set is to provide a set of extensions (including functional and skin) for our applications ), in addition, all controls are centralized to a skin control. If you want to change the skin of the application, the skin file of the control is changed, and the entire interface is changed, you can use the professional skin solutions of Sui or make skin by yourself. Very convenient. It can help us complete a lot of work on the interface.

We use the Sui tree control as an example, and use some C ++ technologies to expand it and achieve reuse.

First, let's determine the target, that is, the functions to be extended. There are three:
1. Let the tree store the values of each node.
2. Let the tree load the values of each node.
3. recursively Delete nodes.

Why are there the above three goals? When we use the tree control, each node has its own values that need to be stored. These values must be defined by ourselves, and may be permanently saved (databases, files...) when the tree control is destroyed ...), These values are reloaded into the Node during tree control initialization. When we delete a node, we may need to process these values to avoid Memory leakage and other side effects. Every time we use a tree control, we encounter this problem. Why don't we try to encapsulate it as a usable control in a reusable way?

A typical example is: we need to separate the representation of nodes in the application, for example, to separate folders and files.
This is often represented by the enum type and assigned to each node for judgment in use.

First, we should consider the technology of C ++ to implement the three functions mentioned above:
For functions 1 and 2, you can use the template technology because you do not know the Data Type in advance. For the third function, the callback function can be used to solve the problem because the customer may need to do something before the node is deleted.

The following example is provided:

The first function, savetreeviewtofiletemplate, stores the values of each node in the file:

// Because the data size to be stored is unknown in advance, the template technology is used here to solve the problem.
// Store the data value of the tree to the file
Template <class type>
Void savetreeviewtofiletemplate (tsuitreeview * TVW, ansistring & strfile,
Type tnoused)
{
TVW-> savetofile (strfile );

Int nfilehandle = 0;

Ansistring strfilename;
Strfilename. sprintf ("% sdata", strfile );

If (fileexists (strfilename ))
{
Deletefile (strfilename );
}
Nfilehandle = filecreate (strfilename );
If (nfilehandle =-1)
{
Ansistring strmsg;
Strmsg. sprintf ("% s file creation failed.", strfilename );
Showmessage (strmsg );
Return;
}
Else
{
// Data value of the storage Node
Ttreenode * pnode;
Pnode = TVW-> topitem;
While (pnode)
{
Filewrite (nfilehandle, (void *) (pnode-> data), sizeof (type ));
Pnode = pnode-> getnext ();
}
}
Fileclose (nfilehandle );
}

The second function loadtreeviewfromfiletemplate is used to load the node from the file when the tree is loaded. Note that a callback function is provided to do the following when the tree node is loaded:

/*************************************** **************************************/
* Load the data value of the tree from the file
* The callback function is also provided here for the customer to do something during loaditem.
/*************************************** **************************************/

// Original form of the callback function:
Typedef void (callback * loadnodedef) (ttreenode * Tn );
Template <class type>
Void loadtreeviewfromfiletemplate (tsuitreeview * TVW, ansistring & strfile,
Type tnoused, loadnodedef loadnodefunc)
{
TVW-> loadfromfile (strfile );

Int nfilehandle = 0;

Ansistring strfilename;
Strfilename. sprintf ("% sdata", strfile );
If (! Fileexists (strfilename ))
{
Return;
}
Else
{
Nfilehandle = fileopen (strfilename, fmopenread );
FileSeek (nfilehandle, 0, 0 );
Type * data;
Ttreenode * pnode;
Pnode = TVW-> topitem;
While (pnode)
{
Data = new type ();
Fileread (nfilehandle, Data, sizeof (type ));

Pnode-> DATA = data;
If (loadnodefunc! = NULL)
Loadnodefunc (pnode );
Pnode = pnode-> getnext ();
}
}
Fileclose (nfilehandle );
}

The third function recursively deletes Tree nodes:

/*************************************** **************************************/
* Recursively delete a node
/*************************************** **************************************/
Void _ fastcall tsuitreeviewex: deletefolderrecursive (tsuitreeview * TVW,
Ttreenode * TN, deletenodedef deletenodefunc)
{
Blnode (TN, deletenodefunc );
TVW-> items-> Delete (TN );
}

The blnode function prototype is as follows:

/*************************************** **************************************/
* Traverse Tree nodes
/*************************************** **************************************/
Void _ fastcall tsuitreeviewex: blnode (ttreenode * TN, deletenodedef deletenodefunc)
{
If (Tn-> data! = NULL)
{
// Showmessage (Tn-> text );
Deletenodefunc (TN );
Vsafedelete (Tn-> data );
}

Ttreenode * nodetmp;
Nodetmp = Tn-> getfirstchild ();
If (nodetmp = NULL)
Return;
// Showmessage (nodetmp-> text );
Deletenodefunc (nodetmp );
Vsafedelete (nodetmp-> data );

While (nodetmp! = Tn-> getlastchild ())
{
Nodetmp = Tn-> getnextchild (nodetmp );
// Showmessage (nodetmp-> text );
Deletenodefunc (nodetmp );
Vsafedelete (nodetmp-> data );
Blnode (nodetmp, deletenodefunc );
}
}

Finally, we can provide a function for clearing:
/*************************************** **************************************/
* Clear the data values of all nodes in the tree to avoid resource leakage.
/*************************************** **************************************/
Void _ fastcall tsuitreeviewex: deleteallnodedata (tsuitreeview * TVW)
{
Ttreenode * Tn = TVW-> topitem;
While (TN)
{
Vsafedelete (Tn-> data );
Tn = Tn-> getnext ();
}
}

The above functions must be written in the header file and CPP file of the C ++ file.

 

Then our use becomes very convenient, as shown below:
// Store the command tree
Void _ fastcall tsinglefuncuilogic: savetreeviewtofile (tsuitreeview * TVW, ansistring & strfile)
{
Enodetype nodetype = cmd;
Tsuitreeviewex: savetreeviewtofiletemplate (TVW, strfile, nodetype );
}

// Load the command tree
// Callback function, which specifies the imageindex during reprinting.
Void callback tsinglefuncuilogic: loadnodecallback (ttreenode * Tn)
{
If (getnodetype (TN) = folder)
{
If (Tn-> expanded)
{
Tn-> imageindex = 1;
Tn-> selectedindex = 1;
}
Else
{
Tn-> imageindex = 0;
Tn-> selectedindex = 0;
}
}
If (getnodetype (TN) = cmd)
{
Tn-> imageindex = 2;
Tn-> selectedindex = 2;
}
}

Void _ fastcall tsinglefuncuilogic: loadtreeviewfromfile (tsuitreeview * TVW, ansistring & strfile)
{
Enodetype nodetype = cmd;
Tsuitreeviewex: loadtreeviewfromfiletemplate (TVW, strfile, nodetype, loadnodecallback );
}

Here, I believe some people will surely understand how this method extends the functions of controls.

Of course, there are many methods to encapsulate and reuse controls (for example, each node type can be encapsulated into a class, and an object is generated and assigned to a node when a node is generated ), here I just give my own method. This method also has some shortcomings. For example, every time you use it, you must include the written C ++ file in the project. This is a physical defect (that is, it is not convenient to use ). This is just a way of thinking. If you have a better method, you are welcome to discuss it.
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.