Click to See Complete Forum and Search --> : Copying Controls


WWWJax
August 23rd, 2001, 10:04 AM
I am trying to, at RUN time, copy and paste a Control (a picture box) on a Form without using the mouse’s ‘right click’ Copy/Paste feature.
I have a Control Array of Picture Boxes. Picture1(0), Picture1(1), etc… These picture boxes are contained in a larger empty Picture2 box.
On a click event, I am trying to copy the particular picture box control, and paste the duplicate anywhere on the Picture2 box. The newly formed picture box should be the next element of the control array, and the new control should be dragable anywhere on the form – which John from CodeGuru has already helped me with.

Here is what I have tried:
First, in the picture box module, I copy the control to the Clipboard (after clearing the clipboard) using the Copy method (I’m not even sure I’m using that command properly).

Then I create a new instance for the new Picture box, Picture1 (Index +1) using the Add method (is this right?)
But then pasting or assigning the new cloned picture box, with its new index, e.g. Picture1(8) onto the form does not work.
Since the control array is already established, I should not have to declare the new control array in a Dim statement, right?

The Copy Method makes sense, but my syntax must be way off as I can’t figure out what object I should be copying: the Picture, the Picture1(Index), or the Picture.box?

Thanks again.


<Strong>Wendell W. Wilson</Strong>
<EM>Software Engineer</EM>
St. Petersburg, FL

John G Duffy
August 23rd, 2001, 11:19 AM
Here is a slight revision to my previous sample
Make the Index property of Picture2 = 0 and put a picture in it, for effect, for this to work

option Explicit
private Declare Function SetParent Lib "User32" _
(byval hWndChild as Long, byval hWndNewparent as Long) as Long

private Sub Form_DragDrop(Source as Control, x as Single, Y as Single)
Dim iret
iret = SetParent(Source.hWnd, me.hWnd)
Source.Move x, Y
End Sub

private Sub Picture1_DragDrop(Source as Control, x as Single, Y as Single)
static ctr as Integer
ctr = ctr + 1
Load Picture2(ctr)
Picture2(ctr).Visible = true
Picture2(ctr).AutoRedraw = true
Picture2(ctr).Move x, Y
Picture2(ctr).Picture = Source.Picture
End Sub




John G

Kdev
August 23rd, 2001, 11:22 AM
Instead of Copy/Paste try this:

Load Picture1(NewIndex). This will add the control to the form. You can now access all of the new control's properties via Picture1(NewIndex).Property.

-K

DSJ
August 23rd, 2001, 11:24 AM
Try:

load Picture1(index + 1)

WWWJax
August 28th, 2001, 12:58 PM
Re: Copying, Drag and Dropping Picture Boxes.

Thanks again, John and everyone else who posted an equally similar solution!
We’re getting there. I really appreciate your time on this.

I’m still a bit confused about ‘how’ the SetParent function works, since I’m not using MDI Child/Parent Form strategy. Still I'm glad it works. Thanks.

So, using Load Picture2(n+1) instruction,the module can create another picture box (Cool!), I have to figure out a way to make the new Picture2(index+1) box appear on the original Picture1 box container. Currently, the new Picture2(Index+1) is loaded on my .bmp form, underneath or behind my control bar. Hmmmm... I can still grab an edge of the new picture2(Index+1) box and drag/drop it around the form, but I still need to CLEARLY load the new Picture2(Index+1) onto the Picture1 box.

I know that Loading the form is not the same a Showing the form. But how do you ‘Show’ a picture box that's behind another picture?

I’ve looked into :
* Show (works with forms but not picture boxes)
* “Back to Front” feature (that only works with forms)
* Changing the Top and Left properties to make the newly loaded Picture2(Index+1) box appear away from the Picture1 box; but my commands won’t move the control.
* SetParent(Picture2(Index+1).hWnd, Picture1.hWnd) to set the focus back to the Picture1 Box. I get a syntax error on this one.
* Zorder

Might I be digging down the wrong tunnel in solving this? This process seems very complicated for something that is so easy with a right mouse click.

In lieu of abandoning this train of thought, is there a way, in RUN time to right click the mouse, Copy and Paste the Picture(Index+1)box …and then be able to place the new picture box anywhere on the form?


<Strong>Wendell W. Wilson</Strong>
<EM>Software Engineer</EM>
St. Petersburg, FL

DSJ
August 28th, 2001, 01:16 PM
If I understand everything you want the second picturebox to be inside the original... start a project and add a picturebox, set it's index property to zero and then put this code behind a pushbutton and see if this is the effect you want....


private Declare Function SetParent Lib "User32" (byval hWndChild as Long, byval hWndNewparent as Long) as Long
private Sub Command1_Click()
Load Picture1(1)
SetParent Picture1(1).hWnd, Picture1(0).hWnd
Picture1(1).Top = 10
Picture1(1).Width = Picture1(0).Width - 100
Picture1(1).Left = 10
Picture1(1).Height = Picture1(0).Height - 100
Picture1(1).Visible = true
End Sub




notice that the new top and left (10,10) for picture1(1) are relative to the top/left of picture1(0).

WWWJax
August 28th, 2001, 04:55 PM
Hello DSJ!
Thanks for the prompt reply and code.

What I see in your code is that the Command1 button ~which is Picture(1) ~ fills up the Picture1(0) box on an event. Since I need to drag the button, I made sure the button was dragable. However, what I need, is a duplicate button or preferably a duplicate PictureBox that will be loaded onto Picture1(0) and that it can later be dragged onto the Form1 without it losing its properties.
Basically, when one picture box is removed from Picture1 box, another duplicate picture box replaces it.

I have a Form1
I have a Picture1 which is a picture box
I have a Picture2(0), Picture2(1), Picture2(2), etc. which are all picture boxes (control array) that are initially loaded onto Picture1 box.

The code I have and provided by John of CodeGuru is:

Option Explicit
Private Declare Function SetParent Lib "User32" _
(ByVal hWndChild As Long, ByVal hWndNewparent As Long) As Long

Private Sub Form_DragDrop(Source As Control, X As Single, Y As Single)
Dim iret
iret = SetParent(Source.hWnd, Me.hWnd)
Source.Move X, Y
End Sub

Private Sub Picture2_DragDrop(Index As Integer, Source As Control, X As Single, Y As Single)
Static ctr As Integer


ctr = ctr + 1

Load Picture2(ctr)
'Picture2(ctr).Left = Left + 1000 ‘Try to load the picture far away from the Picture1 box
‘so that I can see the new picture box and grab it.
'SetParent Picture2(ctr).hWnd, Picture2(ctr-1).hWnd ‘ Or…Try to make the new ‘Picture2(ctr) box a member of Picture1 box.
Show
Picture2(ctr).Visible = True
Picture2(ctr).AutoRedraw = True
Picture2(ctr).Move X, Y
Picture2(ctr).Picture = Source.Picture
End Sub



Upon my drag and drop event (and a separate click??) of the Picture2(ctr) box, another Picture2(ctr+1) box is created -- which is what I want --, but VB places that new picture box behind Picture1 box. I would like the newly loaded picture box to be loaded on or in front of Picture1 box.
Somehow, I think I have to explicitly code all of the properties of the newly loaded Picture2(ctr+1) box and tell VB that this newly loaded Picture(ctr+1) box belongs to Picture1..i.e. Picture1 is the new parent.
Suggestions…??



<Strong>Wendell W. Wilson</Strong>
<EM>Software Engineer</EM>
St. Petersburg, FL

WWWJax
August 30th, 2001, 08:05 AM
Ok…it looks like the key to all of this parent/form/picture switching is the

Load Picture2(ctr)
iret = SetParent(Picture2(ctr).hWnd, Picture1.hWnd)



Using the Setparent function (thanks, John D), I was able to drag the first picture box to the form. Then, by clicking on that dragged Picture2(ctr), another Picture2(ctr+1), popped up in the Picture1 box; whereby I could drag THAT Picture2(ctr+1) box to the form etc.

Great!

Now I’ll have to figure out how to delete a picture box from the form…maybe with a right click event. But that will be another post.

Thanks to DSJ and John D. for your code and ideas. I’ll be back….


Wendell W. Wilson
Software Engineer
St. Petersburg, FL

John G Duffy
September 2nd, 2001, 02:23 PM
Been away for a while. To position one picturebox in front of another, use the ZORDER command. You might want to look at the Help facility on this one, particularily the last paragraph or so because is discusses Windows Hierarchical structure on displaying controls on a screen. It's pretty short and to the point and resolves a lot of problems regarding two objects occupying the same physical space.

John G

WWWJax
September 6th, 2001, 08:41 AM
Thanks again, John!
I have looked into the Zorder method for something else I have in mind (making a picture box flash by overlaying one picture box, with another picture box that contains a different color).
By using your 'Set Parent' function I am able to toggle the focus from the form, Form1 to the picture Box, Picture2(ctr), thereby being able to drag the small picture box, Pictuer2(ctr) to any spot on the form;
and being able to duplicate another picture box Picture2(ctr+1) and being able to drag that to any spot on the form.
Thanks!

Wendell W. Wilson
Software Engineer
St. Petersburg, FL