Home All Groups Group Topic Archive Search About

My concept for a very basic stripboard layouter in VB6

Author
10 Mar 2009 3:04 PM
MM
Please take a look at
http://www.littletyke.myzen.co.uk/cheapo/index.html

This is an example of using the Visual Basic design environment *as a
tool in its own right*.

I have set the grid matrix to 144 x 144 twips, which corresponds to a
..1 inch stripboard matrix.

The integrated circuits are shapes; the jumper wires are lines. All in
component arrays.

With only these absolutely basic components I can move jumpers, add
new, delete, change colour etc. Same with the ICs. To "save" my layout
I just save the VB project. It never ever gets to be run because I am
only using the design environment and its features like snap to grid
and, indeed, the visible grid to represent a piece of stripboard.

Now here comes the $64,000 question: How do I replicate this
functionality at *run* time? That is, a visible grid, components,
snap-to-grid and so on.

I will need a shopping list:
- Components (roll my own, using maybe picture boxes)
- A component placing tool
- A line placing tool
- Some kind of snap-to-grid logic
- Plenty of time!

I've done a bit of drag and drop coding before. I've already got some
ideas as to how to proceed. But any hints, suggestions, or advice
before I start might save me a lot of hassle later on.

So any input will be gratefully received!

(By the way, I AM aware of the existence of Lochmaster, Veecad,
Stripboard Designer and Stripboard Magic.)

Thanks!

MM

Author
10 Mar 2009 5:54 PM
Eduardo
To draw the grid, you could:

Private Sub DrawGrid()
    Dim iX As Long
    Dim iY As Long
    Dim iStep As Long

    iStep = 144
    For iX = 1 To Me.ScaleWidth Step iStep
        For iY = 1 To Me.ScaleHeight Step iStep
            Me.PSet (iX, iY)
        Next iY
    Next iX
End Sub

Private Sub Form_Paint()
    DrawGrid
End Sub

And here there is an example of how to move lines at run time:

http://groups.google.com/group/microsoft.public.vb.general.discussion/msg/3ff035e71e370a56?hl=en


Show quoteHide quote
"MM" <kylix***@yahoo.co.uk> escribió en el mensaje
news:bovcr4hr6ho6jsj6f3s08u51kdvd2s3ebd@4ax.com...
> Please take a look at
> http://www.littletyke.myzen.co.uk/cheapo/index.html
>
> This is an example of using the Visual Basic design environment *as a
> tool in its own right*.
>
> I have set the grid matrix to 144 x 144 twips, which corresponds to a
> .1 inch stripboard matrix.
>
> The integrated circuits are shapes; the jumper wires are lines. All in
> component arrays.
>
> With only these absolutely basic components I can move jumpers, add
> new, delete, change colour etc. Same with the ICs. To "save" my layout
> I just save the VB project. It never ever gets to be run because I am
> only using the design environment and its features like snap to grid
> and, indeed, the visible grid to represent a piece of stripboard.
>
> Now here comes the $64,000 question: How do I replicate this
> functionality at *run* time? That is, a visible grid, components,
> snap-to-grid and so on.
>
> I will need a shopping list:
> - Components (roll my own, using maybe picture boxes)
> - A component placing tool
> - A line placing tool
> - Some kind of snap-to-grid logic
> - Plenty of time!
>
> I've done a bit of drag and drop coding before. I've already got some
> ideas as to how to proceed. But any hints, suggestions, or advice
> before I start might save me a lot of hassle later on.
>
> So any input will be gratefully received!
>
> (By the way, I AM aware of the existence of Lochmaster, Veecad,
> Stripboard Designer and Stripboard Magic.)
>
> Thanks!
>
> MM
Are all your drivers up to date? click for free checkup

Author
10 Mar 2009 6:28 PM
MM
On Tue, 10 Mar 2009 15:54:28 -0200, "Eduardo" <m*@mm.com> wrote:

Excellent! Thanks.

MM
Author
10 Mar 2009 6:35 PM
Eduardo
You're welcome.

I see that to draw the grid in the Paint event make it too slow.

It would be better to set the AutoRedraw property of the form to True, and
draw the grid in the resize event:

Private Sub Form_Resize()
    DrawGrid
End Sub

Show quoteHide quote
"MM" <kylix***@yahoo.co.uk> escribió en el mensaje
news:s9cdr4tmqi3teli5ai8eh4qq1g6mudch2g@4ax.com...
> On Tue, 10 Mar 2009 15:54:28 -0200, "Eduardo" <m*@mm.com> wrote:
>
> Excellent! Thanks.
>
> MM
Author
10 Mar 2009 8:15 PM
MM
On Tue, 10 Mar 2009 16:35:42 -0200, "Eduardo" <m*@mm.com> wrote:

>You're welcome.
>
>I see that to draw the grid in the Paint event make it too slow.
>
>It would be better to set the AutoRedraw property of the form to True, and
>draw the grid in the resize event:
>
>Private Sub Form_Resize()
>    DrawGrid
>End Sub

Well, I'm experimenting with the code. First, I modified it to draw
the grid on a picture box.

That line-moving code works very well. I'm still dissecting it in
order to understand it fully. Did it come from a larger example? From
yourself or another programmer?

MM
Author
10 Mar 2009 9:21 PM
Eduardo
"MM" <kylix***@yahoo.co.uk> escribió en el mensaje
news:2bidr4dalad9423sdgnb9tjf0j9c0ud4lr@4ax.com...

> That line-moving code works very well. I'm still dissecting it in
> order to understand it fully. Did it come from a larger example? From
> yourself or another programmer?

No. I wrote once this code for someone at a forum several years ago (not
this newsgroup). Then, when the OP of the post that I linked asked about
moving lines, I dont rememnber whether I found the other post or I found the
project sample in my PC, then I added some features like "selecting lines"
that the first sample didn't have.

The idea is to see if the clicks that the user does are near to a line
object, then select or move.
The function LineIsClose calculates the distance from a point to a line.

If I have some time I'll try to comment the code (but I'll have also to
understand it again. LOL).
Author
10 Mar 2009 11:08 PM
Eduardo
OK, here is the code commented:

' mMovingLineName has the name of the line object
    'that the user is moving
Private mMovingLineName As String
' mSelectedLineName has the name of the line that is selected,
    'if none is selected it has ""
' The difference between mMovingLineName and mSelectedLineName
    ' is that mMovingLineName is set to "" in the MouseUp event,
    ' but mSelectedLineName still store the name of the selected
    ' line after the MouseUp
Private mSelectedLineName As String
' mClickY has the Y coordinate where the mouse was pressed
Private mClickY As Long
' mClickX has the X coordinate where the mouse was pressed
Private mClickX As Long
' These two labels are used to place them at the ends of a line
    'when it's selected
Private WithEvents mlblSelected As Label
Private WithEvents mlblSelected2 As Label
' These two square shapes are also used to place them at the ends
    'of a line when it's selected
Private mshpSelected1 As Shape
Private mshpSelected2 As Shape


'Pressing "DEL" key deletes the line that is selected, if any
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    ' if the key pressed is DEL
    If KeyCode = vbKeyDelete Then
        ' if there is a line selected
        If mSelectedLineName <> "" Then
            ' it doesn't really delete the line object, just hides it
            Controls(mSelectedLineName).Visible = False
            Deselect
        End If
    End If
End Sub

Private Sub Form_Load()
    Me.KeyPreview = True

    'adds two aquare shapes and two labels to place at the
       ' end of a line to show it is selected
    ' to fully simulate the IDE I had to add square shapes because the
        ' borders of the labels are black, and I needed the borders
        ' to be white
    ' I needed also labels to place over the shapes, because I needed
        ' the MouseDown events, that the shapes don't have

    ' creates one square shape and set its properties
    Set mshpSelected1 = Controls.Add("VB.Shape", "shpSelected1")
    mshpSelected1.Shape = vbShapeSquare
    mshpSelected1.Width = 100
    mshpSelected1.Height = 100
    mshpSelected1.BackStyle = 1
    mshpSelected1.BackColor = &H8000000D
    mshpSelected1.BorderColor = &H8000000E
    mshpSelected1.ZOrder

    ' creates the second square shape and set its properties
    Set mshpSelected2 = Controls.Add("VB.Shape", "shpSelected2")
    mshpSelected2.Shape = vbShapeSquare
    mshpSelected2.Width = 100
    mshpSelected2.Height = 100
    mshpSelected2.BackStyle = 1
    mshpSelected2.BackColor = &H8000000D
    mshpSelected2.BorderColor = &H8000000E
    mshpSelected2.ZOrder

    ' creates one label and set its properties
    Set mlblSelected = Controls.Add("VB.Label", "lblSelected")
    mlblSelected.Width = 100
    mlblSelected.Height = 100
    mlblSelected.BackStyle = 0

    ' creates the second label and set its properties
    Set mlblSelected2 = Controls.Add("VB.Label", "lblSelected2")
    mlblSelected2.Width = 100
    mlblSelected2.Height = 100
    mlblSelected2.BackStyle = 0
End Sub

Private Sub Form_MouseDown(Button As Integer, Shift _
    As Integer, X As Single, Y As Single)

    Dim C As Control
    Dim L As Line
    Dim iSel As Boolean

    ' With a click on the form, first deselect whatever
        'line is selected, if any
    mMovingLineName = ""
    mSelectedLineName = ""
    Deselect

    ' see all controls on the form to find the lines
    For Each C In Controls
        If TypeOf C Is Line Then
            Set L = C
            ' we found one line, let's see if it's close
               'to the point the mouse was pressed
            If LineIsClose(L, CLng(X), CLng(Y)) Then
                ' OK, this line is close to the click point
                   ' so store its name in mMovingLineName
                mMovingLineName = C.Name
                ' stores the point of the MouseDown, x and y
                mClickX = X
                mClickY = Y
                ' selects the line
                ' NOTE: mSelectedLineName is set inside the SelectLine
                    ' routine, and it holds the name of the selected line
                    ' like mMovingLineName, but it keeps storing it after
                    ' the MouseUp event (when mMovingLineName is cleared)
                SelectLine C
                ' we won't select more than one line, so exit
                Exit For
            End If
        End If
    Next

End Sub

Private Sub Form_MouseMove(Button As Integer, Shift _
    As Integer, X As Single, Y As Single)

    Dim L As Line

    'if there is a line that is selected to move...
    ' in other words, if the user moved the mouse after
        'clicking on a line...
    If mMovingLineName <> "" Then
        Set L = Controls(mMovingLineName)
        ' moves the line according to the difference in x and y
        L.X1 = L.X1 - mClickX + X
        L.X2 = L.X2 - mClickX + X
        L.Y1 = L.Y1 - mClickY + Y
        L.Y2 = L.Y2 - mClickY + Y
        ' select the line again to place the shapes at
           'the ends of the line where the line is now
        SelectLine L
        ' update the reference point, because we already
            'moved the line
        mClickX = X
        mClickY = Y
    End If
End Sub

Private Sub Form_MouseUp(Button As Integer, Shift _
    As Integer, X As Single, Y As Single)

    ' when the user release the mouse, we don't want
        'to move the line any more in the MouseMove event
        ' but the line stays appearing as selected and
        ' the name of the line is stored in mSelectedLineName
        '(the way to unselect the line is to click again - MouseDown -
        ' but far from the line)
    mMovingLineName = ""
    mClickX = 0
    mClickY = 0
End Sub

' this function is an implementation of the math required to
    ' know the distance from a point to a line
    ' it returns True if the (MouseDown) point is near to the line
    ' and False if it's not near
    ' This is necessary because the VB line control doesn't have any
surface,
    ' and any event
Private Function LineIsClose(nL As Line, pX As Long, pY As Long) As Boolean
    Dim dx As Single, dy As Single, t As Single
    Dim iDistancePointLine As Long
    Dim X1 As Long, X2 As Long, Y1 As Long, Y2 As Long

    X1 = nL.X1
    X2 = nL.X2
    Y1 = nL.Y1
    Y2 = nL.Y2

    dx = X2 - X1
    dy = Y2 - Y1
    If dx = 0 And dy = 0 Then
       dx = pX - X1
       dy = pY - Y1
       iDistancePointLine = Sqr(dx * dx + dy * dy)
       Exit Function
    End If
    t = (dx * (pX - X1) + dy * (pY - Y1)) / (dx * dx + dy * dy)
    If t < 0 Then
        dx = pX - X1
        dy = pY - Y1
    ElseIf t > 1 Then
        dx = pX - X2
        dy = pY - Y2
    Else
        dx = pX - (X1 + t * dx)
        dy = pY - (Y1 + t * dy)
    End If
    iDistancePointLine = Sqr(dx * dx + dy * dy)

    LineIsClose = iDistancePointLine < 40
End Function

' This procedure is to show the line as selected
Private Sub SelectLine(nLine As Line)
    ' position one square shape at one end of the line to show the
        ' blue square with white border
    mshpSelected1.Left = nLine.X1 - mshpSelected1.Width / 2
    mshpSelected1.Top = nLine.Y1 - mshpSelected1.Height / 2
    ' position the other one at the other end
    mshpSelected2.Left = nLine.X2 - mshpSelected1.Width / 2
    mshpSelected2.Top = nLine.Y2 - mshpSelected1.Height / 2
    mshpSelected1.Visible = True
    mshpSelected2.Visible = True

    ' Also position the two labels in the same place
       ' where the square shapes are.
    ' The labels are transparent, and just necessary
       ' to have the events (MouseDown and MouseDown) that
       ' the shapes controls lacks of.
    mlblSelected.Left = mshpSelected1.Left
    mlblSelected.Top = mshpSelected1.Top
    mlblSelected2.Left = mshpSelected2.Left
    mlblSelected2.Top = mshpSelected2.Top
    mlblSelected.Visible = True
    mlblSelected2.Visible = True

    ' stores in mSelectedLineName the name of the line
        ' that we already have in mMovingLineName
    mSelectedLineName = mMovingLineName
End Sub

' deselect the line hiding the square shapes
    'and labels thata re at the end
Private Sub Deselect()
    mshpSelected1.Visible = False
    mshpSelected2.Visible = False

    mlblSelected.Visible = False
    mlblSelected2.Visible = False
End Sub

' We use the labels placed at the ends of the selected line to move
   ' one extremity of the line
' They are mlblSelected and mlblSelected2
Private Sub mlblSelected_MouseDown(Button As Integer, Shift _
    As Integer, X As Single, Y As Single)

    ' reuse the same variables mClickX and mClickY to know
        ' where the MouseDown was
    mClickX = X
    mClickY = Y
End Sub

Private Sub mlblSelected_MouseMove(Button As Integer, Shift _
    As Integer, X As Single, Y As Single)

    Dim L As Line
    'f the mouse button is holded down...
    If Button = 1 Then
        If mClickX <> 0 Then
            ' moves just one end of the line, the one that where
                'mlblSelected is over
            ' (It has to move the line extremity itself, and also
               ' the square shape and the label that are over)
            mlblSelected.Left = mlblSelected.Left - mClickX + X
            mlblSelected.Top = mlblSelected.Top - mClickY + Y
            mshpSelected1.Left = mlblSelected.Left
            mshpSelected1.Top = mlblSelected.Top
            Set L = Controls(mSelectedLineName)
            L.X1 = mlblSelected.Left + mlblSelected.Width / 2
            L.Y1 = mlblSelected.Top + mlblSelected.Height / 2
        End If
    End If
End Sub

' The same for the other end of the line
Private Sub mlblSelected2_MouseDown(Button As Integer, Shift _
    As Integer, X As Single, Y As Single)

    mClickX = X
    mClickY = Y
End Sub

Private Sub mlblSelected2_MouseMove(Button As Integer, Shift _
    As Integer, X As Single, Y As Single)

    Dim L As Line
    If Button = 1 Then
        If mClickX <> 0 Then
            mlblSelected2.Left = mlblSelected2.Left - mClickX + X
            mlblSelected2.Top = mlblSelected2.Top - mClickY + Y
            mshpSelected2.Left = mlblSelected2.Left
            mshpSelected2.Top = mlblSelected2.Top
            Set L = Controls(mSelectedLineName)
            L.X2 = mlblSelected2.Left + mlblSelected2.Width / 2
            L.Y2 = mlblSelected2.Top + mlblSelected2.Height / 2
        End If
    End If
End Sub
Author
15 Mar 2009 6:29 PM
MM
On Tue, 10 Mar 2009 21:08:22 -0200, "Eduardo" <m*@mm.com> wrote:

>OK, here is the code commented:

[ snip ]

Hi again, Eduardo. I've been modifying the code and adding new
functionality to provide a visible grid and Snap-To-Grid. It's coming
along nicely!

Is there any reason why you chose a label-plus-shape to construct each
drag handle for the lines?

I'm beginning to think a picture box would be better, for the
following reasons:

1. Only one control instead of two per drag handle.
2. PictureBox allows MousePointer to be set.
3. Less complexity when calculating the various X, Y coordinates.
4. Drag/drop simplified overall.

MM
Author
16 Mar 2009 2:38 AM
Eduardo
"MM" <kylix***@yahoo.co.uk> escribió en el mensaje
news:l2gqr4purbb18nq4t5620qkfko2c9u6i3e@4ax.com...
> On Tue, 10 Mar 2009 21:08:22 -0200, "Eduardo" <m*@mm.com> wrote:
>
>>OK, here is the code commented:
>
> [ snip ]
>
> Hi again, Eduardo. I've been modifying the code and adding new
> functionality to provide a visible grid and Snap-To-Grid. It's coming
> along nicely!

Great!

>
> Is there any reason why you chose a label-plus-shape to construct each
> drag handle for the lines?

No, the only reason is that it was the first thing I thought about.
I needed the two controls because I wanted to fully emulate the IDE, and the
borders of the labels can't be white, hence the use of the shapes, where I
could set the borders to white, but the shapes don't handle events, hence
the need of the transparent labels above.

> I'm beginning to think a picture box would be better, for the
> following reasons:

Yes, may be.
You'll lose the white borders, but this isn't something important, it was
just for being perfectionist (emulating the IDE).
You still could set them with no borders and draw the borders (at the edges
of the pictureboxes) yourself if you want.

>
> 1. Only one control instead of two per drag handle.

OK.

> 2. PictureBox allows MousePointer to be set.

Labels also allows it. I forgot to add that in the code.

> 3. Less complexity when calculating the various X, Y coordinates.

Yes.

> 4. Drag/drop simplified overall.

OK, I think that pictureboxes would be fine.
Author
10 Mar 2009 11:13 PM
Eduardo
Anyway, I was thinking that I wouldn't do it in this way.
I guess you'll need a toolbox with ICs, transistors, resistances,
capacitors, etc.
I was thinking that you could make an UserControl for each different
electronic component, and also an UserControl for lines.
So you can move the lines easier, because the main reason of this code is
that the VB line control doens't have a surface and doens't have events to
know when the user clicked on it.
Author
11 Mar 2009 9:06 AM
MM
On Tue, 10 Mar 2009 21:13:58 -0200, "Eduardo" <m*@mm.com> wrote:

>Anyway, I was thinking that I wouldn't do it in this way.
>I guess you'll need a toolbox with ICs, transistors, resistances,
>capacitors, etc.
>I was thinking that you could make an UserControl for each different
>electronic component, and also an UserControl for lines.
>So you can move the lines easier, because the main reason of this code is
>that the VB line control doens't have a surface and doens't have events to
>know when the user clicked on it.

I need only a very basic tool to aid with layouting a circuit on
stripboard, rather than graph paper, a pencil and an eraser.
Lochmaster is the best I've seen, but it's not free (!)

But certainly, for anyone interested there is definitely a big gap in
this market. Large numbers of hobbyists and prototypers still use
stripboard and the available software, apart from Lochmaster, is dire.
Most do not work or are lacking in functionality if they do. I was
getting *more* functionality yesterday by just using the *design
environment* as a tool and "saving" my design by saving the project.
What an indictment against all those so-called stripboard utilities!

If one spent a month on such a project, knowing what we do already, I
reckon quite a sophisticated little tool could be produced. After I
have finished my current project I might return to this.

At the moment I have already got something working, after your
valuable input and after I rediscovered some code I wrote a few years
ago. (Funny how one writes stuff on a whim and then years later one
suddenly finds a use for it!) I'm going to spend a few more days on it
and then use it to plan my layout!

Thanks for the commented source code in your previous post. I had only
bothered to work out so far what the purpose of LineIsClose is! And
then I remembered that Microsoft in its unwisdom decided to make the
line and shape controls totally dumb ones. Yeah, a user control to
replace Line would be handy. Got one??? !!! ;)

Cheers!

MM

Bookmark and Share