From: James Hahn on
You have made it more complex than it needs to be by attempting to create a
new class. The amount of code involved in what you are trying to do does not
justify this, and in any case I don't like the idea of manipulating the
properties of one object from within the initialize code of another. I
can't see where you are refencing the new object by its index.

I assume that picIndWin is the control you have created with index = 0 and
that it has been created at design time with the same width as the large
picture control and height equal to 1/10 of the form height. The code
should then be something like:

Private Sub cmdNewPic_Click()

Dim N as integer : N = picIndWin.count
Load picIndWin(N)
pctChart.height = pctChart.height - picIndWin(N).Height
picIndWin(N).Top = pctChart.top + pctChart.height
picIndWin(N).Visible = True

End Sub

Note that if you want to start of with no small picture controls rather than
the one that you create at design time, then you should still create it at
design time, but make it invisible. Then control with index 1 will be the
first one that you actually use.

"Webbiz" <nospam(a)formethanks.com> wrote in message
news:AXqil.201$ti1.162(a)newsfe21.iad...
> Here is what I've done (and yes, it does not work).
>
> I created a CLASS and this is its Initialization code:
>
> Private Sub Class_Initialize()
>
> 'Declare my control
> Dim ctlPictureBox As Control
>
> 'Add a new picturebox to the Control Collection
> Set ctlPictureBox = frmChart.Controls.Add("VB.Picturebox", "picIndWin",
> frmChart)
>
> 'Set its initial height as 10% of the overall container form's height
> ctlPictureBox.height = frmChart.height * 0.1
>
> 'Decrease the main picturebox height by the size of the new picturebox
> being added
> frmChart.pctChart.height = frmChart.height - ctlPictureBox.height
>
> 'Move newly created picturebox just under main picturebox
> ctlPictureBox.Top = frmChart.pctChart.height + 1
> ctlPictureBox.Left = frmChart.pctChart.Left
> ctlPictureBox.width = frmChart.pctChart.width
>
> 'Now make the picturebox show up on the form
> ctlPictureBox.Visible = True
>
> End Sub
>
>
> Then in the main program code for the pctChart (picturebox for the chart),
> under the KeyUp method, I have it run this when you press the "I" key:
>
> Public Sub AddIndicatorWindow()
>
> Dim IndWin As cIndWindows
> Set IndWin = New cIndWindows
>
> End Sub
>
>
> Two problems arises:
>
> 1. The pctChart picturebox does not appear to resize and remains covering
> the form from top to bottom.
> 2. When I didn't see the pctChart resize and therefore didn't see my new
> picturebox show up below it (because apparently pctChart didn't resize,
> thus probably covering it), I tried to hit the "I" key and it gave me an
> error:
>
> Run-time error '727':
> There is already a control with the name 'picIndWin'.
>
> Why do you think my pctChart is not resizing?
> How do I change this so that I can add additional picIndWin each time I
> press my "I" key?
>
> Thanks.
>
> Webbiz
>
>
>
>
>
>
>
>
>
> "Webbiz" <nospam(a)formethanks.com> wrote in message
> news:1Rmil.5756$Bk7.5711(a)newsfe02.iad...
>> Greetings.
>>
>> I'm really trying to wrap my mind around this task.
>>
>> Say you have a form with 1 picturebox. We will call this picMain.
>>
>> Say you want to add additional, smaller height pictureboxes to the form
>> during runtime. These are picSmall.
>>
>> =================
>>
>> When the program starts, you see picMain covering the whole form.
>>
>> You can select a menu item or click a button (either way) and a new
>> picturebox will show up directly below picMain with the same width as
>> picMain but only a fraction of the height. This causes picMain to adjust
>> its height to accomodate the new picSmall below it inside the form.
>>
>> If I click to add another one, a new picSmall will show up just below
>> picMain (and of course above the last picSmall). Therefore, once again
>> picMain must adjust its height to accomodate the new picSmall picturebox.
>>
>> Each time I click the button (or select the menu item), picMain will
>> shrink in height to accomodate a new picSmall, that will stack on top of
>> the previous picSmall pictureboxes.
>>
>> A mechanicism to close each picSmall picturebox (you cannot close picMain
>> as it should always be visible) is incorporated (for simplicity or
>> testing, say a right-click inside the respective picSmall will close it).
>>
>> When any picSmall picturebox is closed, the remaining picSmall pb's will
>> adjust so they continue to stack onto each other, with ONLY picMain
>> adjusting in actual size (height) to fill in the new available empty
>> space left by the deleted picSmall.
>>
>> ==================
>>
>> I'm trying to figure out the BASICS of creating new picSmall pictureboxes
>> in code. I'm thinking that I only need to have two pictureboxes on my
>> form during design time. One is picMain and one picSmall. Then in code, I
>> suspect I should be able to make duplicates of picSmall, with each having
>> the same properties, methods, etc., much like a Class object.
>>
>> How is this done if possible? Or do I have to create an array of picSmall
>> pictureboxes, say 5 or 10 of them, whatever my maximum will be, during
>> design time, and then enable/disable them (visible true/false) during
>> run-time?
>>
>> I'd like to be able to create as many picSmall as I like during run-time
>> without knowing how many the user will want to place on the form.
>>
>> I'm still very green when it comes to this kind of stuff, so please be
>> easy on me.
>>
>> Thanks.
>>
>> Webbiz
>>
>>
>>
>
>

From: Webbiz on
I'm just not sure how this should be managed.

When a picIndWin is created, it is sized. The main picMain is resized to
accomodate the new picIndWin.

But say I add a couple more, and then decide to delete one of them in the
middle.

I have to move around those still active to fill the gap left.

Say it is picIndWin(3) that I deleted, and 0, 1, 2, 4, 5 still remain.

If I rely on picIndWin.count to get the next index, it will fail at this
point.

And I imagine that I'll need to shift the higher index controls to fill in
the missing one, right?

Or do I leave gaps in the array?

It's just not clear to me how to juggle these dynamically created picIndWin
controls.

One thing for sure, if the index references change, this would muck up the
reference that the indicator code is using to draw on them. For example, if
I create picIndWin(2) to draw lines based on some code I have, and for some
reason the index 2 is changed, the code would have to know this and adjust
to it. In other words, there cannot be a break in connection between the
code that is drawing and the picbox that it is drawing to.

So how would I manage the adding and deleting of these picIndWin and still
maintain proper connection to drawing code?

Thanks.

Webbiz




"James Hahn" <jhahn(a)yahoo.com> wrote in message
news:u3vtYK1hJHA.4880(a)TK2MSFTNGP02.phx.gbl...
> You have made it more complex than it needs to be by attempting to create
> a new class. The amount of code involved in what you are trying to do does
> not justify this, and in any case I don't like the idea of manipulating
> the properties of one object from within the initialize code of another.
> I can't see where you are refencing the new object by its index.
>
> I assume that picIndWin is the control you have created with index = 0 and
> that it has been created at design time with the same width as the large
> picture control and height equal to 1/10 of the form height. The code
> should then be something like:
>
> Private Sub cmdNewPic_Click()
>
> Dim N as integer : N = picIndWin.count
> Load picIndWin(N)
> pctChart.height = pctChart.height - picIndWin(N).Height
> picIndWin(N).Top = pctChart.top + pctChart.height
> picIndWin(N).Visible = True
>
> End Sub
>
> Note that if you want to start of with no small picture controls rather
> than the one that you create at design time, then you should still create
> it at design time, but make it invisible. Then control with index 1 will
> be the first one that you actually use.
>
> "Webbiz" <nospam(a)formethanks.com> wrote in message
> news:AXqil.201$ti1.162(a)newsfe21.iad...
>> Here is what I've done (and yes, it does not work).
>>
>> I created a CLASS and this is its Initialization code:
>>
>> Private Sub Class_Initialize()
>>
>> 'Declare my control
>> Dim ctlPictureBox As Control
>>
>> 'Add a new picturebox to the Control Collection
>> Set ctlPictureBox = frmChart.Controls.Add("VB.Picturebox",
>> "picIndWin", frmChart)
>>
>> 'Set its initial height as 10% of the overall container form's height
>> ctlPictureBox.height = frmChart.height * 0.1
>>
>> 'Decrease the main picturebox height by the size of the new picturebox
>> being added
>> frmChart.pctChart.height = frmChart.height - ctlPictureBox.height
>>
>> 'Move newly created picturebox just under main picturebox
>> ctlPictureBox.Top = frmChart.pctChart.height + 1
>> ctlPictureBox.Left = frmChart.pctChart.Left
>> ctlPictureBox.width = frmChart.pctChart.width
>>
>> 'Now make the picturebox show up on the form
>> ctlPictureBox.Visible = True
>>
>> End Sub
>>
>>
>> Then in the main program code for the pctChart (picturebox for the
>> chart), under the KeyUp method, I have it run this when you press the "I"
>> key:
>>
>> Public Sub AddIndicatorWindow()
>>
>> Dim IndWin As cIndWindows
>> Set IndWin = New cIndWindows
>>
>> End Sub
>>
>>
>> Two problems arises:
>>
>> 1. The pctChart picturebox does not appear to resize and remains covering
>> the form from top to bottom.
>> 2. When I didn't see the pctChart resize and therefore didn't see my new
>> picturebox show up below it (because apparently pctChart didn't resize,
>> thus probably covering it), I tried to hit the "I" key and it gave me an
>> error:
>>
>> Run-time error '727':
>> There is already a control with the name 'picIndWin'.
>>
>> Why do you think my pctChart is not resizing?
>> How do I change this so that I can add additional picIndWin each time I
>> press my "I" key?
>>
>> Thanks.
>>
>> Webbiz
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> "Webbiz" <nospam(a)formethanks.com> wrote in message
>> news:1Rmil.5756$Bk7.5711(a)newsfe02.iad...
>>> Greetings.
>>>
>>> I'm really trying to wrap my mind around this task.
>>>
>>> Say you have a form with 1 picturebox. We will call this picMain.
>>>
>>> Say you want to add additional, smaller height pictureboxes to the form
>>> during runtime. These are picSmall.
>>>
>>> =================
>>>
>>> When the program starts, you see picMain covering the whole form.
>>>
>>> You can select a menu item or click a button (either way) and a new
>>> picturebox will show up directly below picMain with the same width as
>>> picMain but only a fraction of the height. This causes picMain to adjust
>>> its height to accomodate the new picSmall below it inside the form.
>>>
>>> If I click to add another one, a new picSmall will show up just below
>>> picMain (and of course above the last picSmall). Therefore, once again
>>> picMain must adjust its height to accomodate the new picSmall
>>> picturebox.
>>>
>>> Each time I click the button (or select the menu item), picMain will
>>> shrink in height to accomodate a new picSmall, that will stack on top of
>>> the previous picSmall pictureboxes.
>>>
>>> A mechanicism to close each picSmall picturebox (you cannot close
>>> picMain as it should always be visible) is incorporated (for simplicity
>>> or testing, say a right-click inside the respective picSmall will close
>>> it).
>>>
>>> When any picSmall picturebox is closed, the remaining picSmall pb's will
>>> adjust so they continue to stack onto each other, with ONLY picMain
>>> adjusting in actual size (height) to fill in the new available empty
>>> space left by the deleted picSmall.
>>>
>>> ==================
>>>
>>> I'm trying to figure out the BASICS of creating new picSmall
>>> pictureboxes in code. I'm thinking that I only need to have two
>>> pictureboxes on my form during design time. One is picMain and one
>>> picSmall. Then in code, I suspect I should be able to make duplicates of
>>> picSmall, with each having the same properties, methods, etc., much like
>>> a Class object.
>>>
>>> How is this done if possible? Or do I have to create an array of
>>> picSmall pictureboxes, say 5 or 10 of them, whatever my maximum will be,
>>> during design time, and then enable/disable them (visible true/false)
>>> during run-time?
>>>
>>> I'd like to be able to create as many picSmall as I like during run-time
>>> without knowing how many the user will want to place on the form.
>>>
>>> I'm still very green when it comes to this kind of stuff, so please be
>>> easy on me.
>>>
>>> Thanks.
>>>
>>> Webbiz
>>>
>>>
>>>
>>
>>
>


From: Clive Lumb on

> So how would I manage the adding and deleting of these picIndWin and still
> maintain proper connection to drawing code?
>
> Thanks.
>
> Webbiz

If you use the control's "tag" property you can "name" the controls as and
when you create them.
You can therefore enumerate through the controls searching for the tag,
rather than relying on the index.
That way you can delete intermediates.


From: James Hahn on
There's no need to delete unused controls in the array - just set them to
not visible and adjust the .top of any array elements that are lower in the
'stack'. When traversing the array, ignore elements that are not visible.
When adding new elements first check to see if there are any currently set
to not visible, and re-use one of them, if available. The .top property is
setting the display order, so if you juggle that correctly for the delete
process (and assuming that the add process simply positions the new control
at the top of the 'stack', as per the sample code) then everything falls
into place and the actual index values don't really matter, and do not need
to change.

"Webbiz" <nospam(a)formethanks.com> wrote in message
news:4fvil.12485$Yz.11849(a)newsfe01.iad...
> I'm just not sure how this should be managed.
>
> When a picIndWin is created, it is sized. The main picMain is resized to
> accomodate the new picIndWin.
>
> But say I add a couple more, and then decide to delete one of them in the
> middle.
>
> I have to move around those still active to fill the gap left.
>
> Say it is picIndWin(3) that I deleted, and 0, 1, 2, 4, 5 still remain.
>
> If I rely on picIndWin.count to get the next index, it will fail at this
> point.
>
> And I imagine that I'll need to shift the higher index controls to fill in
> the missing one, right?
>
> Or do I leave gaps in the array?
>
> It's just not clear to me how to juggle these dynamically created
> picIndWin controls.
>
> One thing for sure, if the index references change, this would muck up the
> reference that the indicator code is using to draw on them. For example,
> if I create picIndWin(2) to draw lines based on some code I have, and for
> some reason the index 2 is changed, the code would have to know this and
> adjust to it. In other words, there cannot be a break in connection
> between the code that is drawing and the picbox that it is drawing to.
>
> So how would I manage the adding and deleting of these picIndWin and still
> maintain proper connection to drawing code?
>
> Thanks.
>
> Webbiz

From: Larry Serflaten on

"Webbiz" <nospam(a)formethanks.com> wrote
> Currently,
> when I want to add an indicator to the bottom of the chart, I am actually
> stealing a portion of the bottom of this picturebox to draw the indicator,
> thus having to make size adjustments within my code so that my price chart
> will not over write my indicator window that shares the same picturebox.
> Personally, I find this to be lame and not effective. Instead, if each
> indicator I add to the bottom of the chart can be its own picturebox, I
> won't have to keep track of what real estate is available on the main chart
> picturebox (pctChart).

We went over this last year. I think one time in March and again in
September. But the laws of physics have not changed since then.
In order to move your indicators about, you have to keep track of them.
They don't know how to keep track of themselves, you have to add code
to do all their 'thinking'.

When you write the code to do the manipulations, you have the majority
of the work done, and therefore do not need Picture boxes to keep
things separate. They will only cause you to add more effort to load
and hide them as needed.

You indicated you have to make size adjustments in your code to
avoid overwriting the indicator areas, but that is not necessary.
The area you draw on is completely under your control, if you want
your chart to remain a constant size even when things are added,
then make it stay the same size.

Here is a quick example of adding colored bars to the bottom of
the form. With just minimal code you can add (left click the form)
and remove (right click on a bar) them at will and they fill whatever
space is available on the form. All the while you add and remove
those bars, the *_chart code does not change_*, yet it adjusts to
make room for the bars.....

HTH
LFS

' Paste the following code to a new form:

Option Explicit
Private Panes As Collection
Private RePaint As Long

Private Sub Form_Load()
Set Panes = New Collection
End Sub

Private Sub Form_Paint()
DrawChart
DrawPanes
End Sub

Private Sub Form_Resize()
' Adjust canvas
Me.Scale (0, 0)-(1000, 1000 + (200 * Panes.Count))

'Catch Downsizing
If (Width * Height) < RePaint Then
Form_Paint
End If
RePaint = (Width * Height)
End Sub

Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
Select Case Button
Case vbLeftButton
AddPane
Case vbRightButton
RemovePane Y
End Select
End Sub

Private Sub DrawChart()
Dim X As Long
'No size adjustments, its always the same code
Me.Line (0, 0)-(1000, 1000), vbWhite, BF
Me.DrawWidth = 3
For X = 100 To 400 Step 100
Me.Line (X, X)-(1000 - X, 1000 - X), vbBlack, B
Next
Me.DrawWidth = 1
End Sub

Private Sub DrawPanes()
Dim idx As Long, top As Long
top = 1000
For idx = 1 To Panes.Count
Me.Line (0, top)-(1000, top + 200), Panes(idx), BF
top = top + 200
Next
End Sub

Private Sub AddPane()
Static K As Long
Panes.Add QBColor(K)
K = (K + 1) And 15
Form_Resize
Form_Paint
End Sub

Private Sub RemovePane(ByVal Y As Long)
Dim idx As Long
idx = (Y - 800) \ 200
If idx < 1 Then Exit Sub
Panes.Remove idx
Form_Resize
Form_Paint
End Sub