|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
My concept for a very basic stripboard layouter in VB6http://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 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 On Tue, 10 Mar 2009 15:54:28 -0200, "Eduardo" <m*@mm.com> wrote: Excellent! Thanks.MM 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 On Tue, 10 Mar 2009 16:35:42 -0200, "Eduardo" <m*@mm.com> wrote: Well, I'm experimenting with the code. First, I modified it to draw>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 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 "MM" <kylix***@yahoo.co.uk> escribió en el mensaje No. I wrote once this code for someone at a forum several years ago (not 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? 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). 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 On Tue, 10 Mar 2009 21:08:22 -0200, "Eduardo" <m*@mm.com> wrote: [ snip ]>OK, here is the code commented: 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 "MM" <kylix***@yahoo.co.uk> escribió en el mensaje Great!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! > No, the only reason is that it was the first thing I thought about.> Is there any reason why you chose a label-plus-shape to construct each > drag handle for the lines? 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 Yes, may be.> following reasons: 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. > OK.> 1. Only one control instead of two per drag handle. > 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.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. On Tue, 10 Mar 2009 21:13:58 -0200, "Eduardo" <m*@mm.com> wrote: I need only a very basic tool to aid with layouting a circuit on>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. 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
Other interesting topics
Put Date/Time on Right Side of Form.Caption
With .... End With - Speed Public Thank You To Microsoft Subclassing a la Caton Days and Years - Data Comparing Does anybody know how to translate this C# code to VB6? Copy protection and license management programs Need a Friend, Maybe Which is the Best Twain ActiveX? Error 6 Overflow when multiply |
|||||||||||||||||||||||