Use the VCL control array in BCB (1)
Ixue
Last night, I chatted with Yan Yanhua, a netizen, on OICQ. He was editing a game menu for his friend. A group of buttons were dynamically created, but they could not be released. The implementation method is as follows:
For (INT I = 1; I <= buttoncount; I ++)
{
Tspeedbutton * spdbtn = new tspeedbutton (this );
Spdbtn-> parent = scrollbox; // specify the parent Control
Spdbtn-> caption = inttostr (I );
Spdbtn-> width = 80;
Spdbtn-> Height = 80;
Spdbtn-> onclick = buttonclick;
Spdbtn-> left = intleft;
Spdbtn-> Top = inttop;
Spdbtn-> groupindex = 1;
Spdbtn-> flat = true;
Intleft = intleft + 80 + intspace;
If (I % linecount = 0)
{
Inttop = inttop + 80 + intspace;
Intleft = intspace;
}
Buttons-> Add (spdbtn); // buttons is a tlist pointer
}
Finally, the memory cannot be released using the clear () method of tlist,
In fact, the clear () method only clears the list. to delete the list, you must use Delete. However, the delete operator must have a pointer to delete the list. This implementation method cannot get a pointer! So I gave up this kind of thinking. Suddenly, the light flashed (not to be thundered, but I came up with a solution). Can I use arrays? Just do it! Array allocation? I think, right!
Tspeedbutton * buttons [] = new tspeedbutton [4] (this );
But the compiler tells me: Error!
Tspeedbutton * buttons [] = new tspeedbutton (this) [4]
Still wrong! Finally, I was so confused that I took out all Java allocation methods:
Tspeedbutton [] * buttons = new tspeedbutton [] (this)
Result? You do not need to know! Is there no way? I think of a simple pointer array, int X [] = {1, 2, 3 }.
Tspeedbutton * buttons [] = {New tspeedbutton (this), new tspeedbutton (this), new tspeedbutton (this )};
You can! I was just smiling and suddenly found out: What if I want to define 100 buttons ...... Who can afford a string of repeated words? Even if you use copy/parst, it will inevitably lead to hundreds of thousands of errors. Is there no way? After meditation, I think of another method. How can I do it step by step?
Tspeedbutton ** button = new tbutton * [100];
For (INT I = 0; I <100; I ++) button [I] = new tspeedbutton (this );
Haha! Actually OK! Try release again:
For (INT I = 0; I <4; I ++) delete X [I];
Delete [] X;
Haha! Still OK! So I wrote an example: Put two buttons in a window and click the button to display or close the dynamic generation.
First declare a global variable tbutton ** X;
Then add the generated code to The onclick of button1:
X = new tbutton * [4];
For (INT I = 0; I <4; I ++)
{
X [I] = new tbutton (this );
X [I]-> left = 100;
X [I]-> Top = 10 + I * 30;
X [I]-> width = 90;
X [I]-> Height = 25;
X [I]-> parent = this;
X [I]-> caption = "button" + ansistring (I );
}
Click it to generate and display four buttons, and then add the release code in button2:
For (INT I = 0; I <4; I ++) delete X [I];
Delete [] X;
Run a try. OK! Success!
Therefore, the process of using the VCL array is: first declare a double pointer, then assign the number of VCL components to be VCL, and then allocate each VCL component. When the VCL array is released, resources of each VCL element must be released before resources of the VCL array can be recycled.
##################
Use the VCL control array in BCB (2)
Ixue
In my "using VCL control arrays in BCB", I mentioned the problem that tlist cannot be used to release resources. Now I get the answer, yan Yanhua and other netizens have instructed the tlist release method and defined the Code as follows:
For (INT I = 1; I <= buttoncount; I ++)
{
Tspeedbutton * spdbtn = new tspeedbutton (this );
Spdbtn-> parent = scrollbox; // specify the parent Control
Spdbtn-> caption = inttostr (I );
Spdbtn-> width = 80;
Spdbtn-> Height = 80;
Spdbtn-> onclick = buttonclick;
Spdbtn-> left = intleft;
Spdbtn-> Top = inttop;
Spdbtn-> groupindex = 1;
Spdbtn-> flat = true;
Intleft = intleft + 80 + intspace;
If (I % linecount = 0)
{
Inttop = inttop + 80 + intspace;
Intleft = intspace;
}
Buttons-> Add (spdbtn); // buttons is a tlist pointer
}
The code for releasing a resource is as follows:
Int num = button-> count;
For (INT I = 0; I <num; I ++)
{
Delete (tspeedbutton *) button-> items [I];
}
In fact, each item of the tlist is deleted. However, because the tlist-> items type is void *, in C/C ++, void * can match any type, therefore, you only need to add a forced type conversion (tspeedbutton *). Of course, you can also use (tobject *), because tobject is the base class of all classes in VCL, the base class pointer can point to its direct or indirect subclass.
Comparison of the two methods: the previous method can be said to be a typical C ++ solution, and this method can be said to be a C ++ builder solution, it is flexible and efficient to use double pointers, but we all know that multiple pointers are not so easy to understand. I thought I used four pointers at the beginning (don't look at me that way !), Later I was confused. However, this method is easy to understand and can be used with the tlist class, but it is not as efficient as the previous one. In general, the two methods have their own advantages and disadvantages, it depends on your preferences.
_________________