Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Duplicating controls at run time.

Posted on 1997-07-08
7
Medium Priority
?
136 Views
Last Modified: 2010-04-06
I need to create a duplicate copy of a control at run time. The main control I need to duplicate is a TabControl and allthe components that it contains and put it in a dynamically created form. All the duplicated controls need to have the same values of the original (I cannot just create new ones) Also I cannot just move the original control (by adjusting parent) to new form because both forms may be on screen at the same time.I do not want to use the clipboard to avoid corrupting clip board info from this & other apps.Can anybody help?
0
Comment
Question by:essbb
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 

Author Comment

by:essbb
ID: 1338435
By the way, I am using delphi 2.01
0
 
LVL 12

Accepted Solution

by:
andrewjb earned 200 total points
ID: 1338436
Possibilities :

Let's assume you've got a TabControl on form A that you want to duplicate on form B.


You say that you don't want to change parent, since both may be on the screen at the same time. Why not have form B create its own personal copy of form A, that is never made visible. You can then alter the parent of the copy of the TabControl, and place it on form B. Simply create a copy in the FormCreate event of form B.

You could also stream out the TabControl data using the Read/WriteComponent methods. These are not particually simple to use, but it is possible to get them to work. On the other hand, you won't then get all the events linked up correctly.

Go for the first option!
0
 

Author Comment

by:essbb
ID: 1338437
The first method will not work. If I create a new instance of form A all the components will contain the initial values / states for that form. I need to duplicate the current values.

I also need to have the events linked up properly so the second option will not work.

I do like the simplicity of the first approach and It may make a sutiutable 'work around' in that I could create a new instance and then add code to set the properties and states to match the parent.

I Would however much prefer to duplicate the object if possible as this seems much more eligent and will ensure that all the existing controls and any that I introduce in the future are duplicated correctly.

Do you have any more suggestions?

0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 12

Expert Comment

by:andrewjb
ID: 1338438
Sorry, I didn't quite understand.

You could stream out the current set of components, then create a version of form A telling it to use the stream that you've just created. That should also set up the event handlers correctly. I'll have to look up how to do that, and see if I can get it working. Give me a few moments.........
0
 

Author Comment

by:essbb
ID: 1338439
Do you have a solution for me or can I Reject your answer and see if someone else knows?


0
 
LVL 12

Expert Comment

by:andrewjb
ID: 1338440
Here's something to work on. I'll have another look if I get a minute or two! This attempts to copy a panel and everything on it, at run time. Basically I stream stuff out to a tMemoryStream, then try to load it back in. It doesn't quite work yet!

The code assumes you've got a panel called Panel1 on the form TForm1.





procedure TForm1.Button2Click(Sender: TObject);
var
  lList : TList;
  lListIndex : integer;
  lControlIndex : integer;
  lStream : tMemoryStream;
  lWriter : TWriter;
  lReader : TReader;
  lIndex : integer;
  lControl : TControl;
  lNewForm : TForm1;
  lNew : TPanel;
begin
  lList := TList.Create;

  { Make a list of all the controls on the panel we want to copy }
  lList.Add( Panel1 );
  lListIndex := 0;
  while ( lListIndex < lList.Count ) do
  begin
    lControl := TControl(lList[lListIndex] );
    if ( lControl is tWinControl ) then
    begin
      for lControlIndex := 0 to tWinControl(lControl).ControlCount - 1 do
      begin
        lList.Add( tWinControl(lControl).Controls[lControlIndex] );
      end;
    end;
    Inc( lListIndex );
  end;

  lStream := tMemoryStream.Create;
  lWriter := tWriter.Create( lStream , 1 );
  lReader := tReader.Create( lStream , 1 );

  lNewForm := TForm1.Create( Self );
  lNew := TPanel.Create( lNewForm );
  lNewForm.Panel1.Free;

  { Write the current panel out }
  for lIndex := 1 to lList.Count - 1 do
  begin
    lControl := TControl(lList[lIndex]);
    lWriter.WriteSignature;
    lWriter.WriteComponent( lControl );
  end;
  lWriter.WriteListEnd;
  lWriter.WriteBoolean( True );
  lWriter.Free;

  { Read the new panel in }
  lStream.Seek( 0 , 0 );
  lReader.ReadComponents( lNewForm , lNew , DummyProc );

  lNew.Parent := Self;
  lNew.SetBounds( 100 , 100 , 200 , 200 );

  { Free up }
{  lList.Free;
  lStream.Free;
  lWriter.Free;
  lReader.Free;}

end;

0
 

Expert Comment

by:krisz
ID: 1338441
Create a TMemoryStream, a TReader and a TWriter object.
Connect the TReader and the TWriter to the stream.
Use the source control's WriteState method to save the contents
of the control to the stream.
Create the target control if doesn't exist.
Use the target control's ReadState method.

I didn't look into the details, but it have to work.

Maybe you have to clear all child controls from target.
Maybe you have to reset the Stream's position before writing and
reading.
0

Featured Post

New benefit for Premium Members - Upgrade now!

Ready to get started with anonymous questions today? It's easy! Learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses

660 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question