Dears
im petroleum engineer
i want to create a program that enables the user to draw a pipeline system
which consists of pipeline segments,pumping station,valves
etc...
i want the user to draw the pipeline segment on a form as (line or arrow)
and let this (line or arrow) be an interactive object: means after the user
draw a line ,when he double click it ,another form should appear, to enter
the information relevant to that line(pipeline segment)
about the pumping station,valves etc... ,i want the user insert them as
interactive icon and attached them to the existing pipeline segment
i did all the above by drawing a line using the line control each time a user
click on 'insert a pipeline segment' button .
and let the user insert an icon represent pumping station,valves etc
making the inserted icon interactive( a form show and let the user enter any
relevent information about this icon), went well ,but the problem of
selecting the line and make it interactive is the probelm since you cant
select a line control during run time .
is there any solution by which we can make a line control selectable during
run time ?
and i want to add an annotation to the drawn line such as for example
'pipe1',after drawing
it ,and aligned it the the line (e.g diagonal annotation attached to a
diagonal line,etc..)
are there any other approachs than the one i used ?
i found on this site an article about api functions concerning drawings but
it was somehow misleading .It contains, somthing like using gdi ,floodfill
lib"gdi 32".But i could make a conclusion
that api could be helpful in solving my problem . is there any tutorial about
drawings with api
thanks in advance for your help
husseina78 - 20 Feb 2007 15:16 GMT
Sorry i forgot to mention i m using vb6
>Dears
>im petroleum engineer
[quoted text clipped - 35 lines]
>
>thanks in advance for your help
Rick Rothstein (MVP - VB) - 20 Feb 2007 15:17 GMT
> i want to create a program that enables the user to draw a pipeline system
> which consists of pipeline segments,pumping station,valves
[quoted text clipped - 29 lines]
>
> are there any other approachs than the one i used ?
Maybe you can make use of this IsNearLine function I have posted previously.
I'm thinking you could identify whether the point the user clicks with is
near a line control (using a loop through all the Line controls, I guess...
put them in a control array to make that easier to do) and, if so, change
the Line control's color or BorderWidth to "highlight" it. The rest of what
you want to do sounds like plain coding from here. Anyway, it is just a
thought for you to consider.
Rick
Below is a (commented) function that I've posted in the past which will tell
you if a point is near a line. The routine assumes the line is a Line
control (if you chose to modify it for some other use, the key to its
operation is keyed around the line's endpoints). One of the parameters is
Tolerance which tells the function how close to the line the point must be
in order to consider it near enough. The other parameters is the Line
control you want to test nearness to and the X and Y coordinates of the
point being tested. Here is a simple project that will demonstrate the
function. Start a new project and place a Line control anywhere on the form
and place a Label control that is out of the way of the Line (maybe in one
of the corners). Now, copy/paste the function below and the following into
the form's code window...
Private Sub Form_MouseDown(Button As Integer, _
Shift As Integer, X As Single, Y As Single)
If IsNearLine(Line1, X, Y, 90) Then
Label1.BackColor = vbGreen
Else
Label1.BackColor = vbRed
End If
End Sub
That's it. Run the project and click around the line. If you click within 90
Twips of the line, the Label will be colored green; if you miss, the Label
will be colored red.
Function IsNearLine(LineControl As Line, _
PX As Variant, PY As Variant, _
Tolerance As Variant) As Boolean
Dim A As Single
Dim B As Single
Dim C As Single
Dim LenWholeLine As Single
Dim DistPtToX1Y1 As Single
Dim DistPtToX2Y2 As Single
Dim LenAlongLine As Single
Dim DistPtToLine As Single
Dim ProjectedX As Single
Dim ProjectedY As Single
With LineControl
' This checks to see if the point (PX, PY) lies
' within the Tolerance distance of either end point
' of the line by using the general equation of a
' circle x² + y² = r² adjusted for the offset to
' each end point of the line.
If ((PX - .X1) * (PX - .X1) + _
(PY - .Y1) * (PY - .Y1) < _
Tolerance * Tolerance) Or _
((PX - .X2) * (PX - .X2) + _
(PY - .Y2) * (PY - .Y2) < _
Tolerance * Tolerance) Then
IsNearLine = True
' If the point (PX, PY) does not lie within a circle
' of radius Tolerance from either end point of the
' line (checked for above), then we check if it lies
' Tolerance units away from from the line anywhere
' along its length.
Else
' If you take the general formula for a line
' y = mx + b and substitute two points (X1, Y1)
' and (X2, Y2) into it one at a time, solve the two
' equations simultaneously and then manipulate it
' into the more general equation Ax + By + C = 0,
' you eventually arrive at the solution for A, B, C.
A = .Y2 - .Y1
B = .X1 - .X2
C = .X2 * .Y1 - .Y2 * .X1
' We do the above because knowing A, B, C for the
' above more general formula for a line allows us
' to use the following formula for the offset
' distance from any point (PX, PY) to the above
' described line:
DistPtToLine = Abs((A * PX + B * PY + C) / _
Sqr(A * A + B * B))
' If this offset distance is less than than the
' specified Tolerance, then we know the point is
' possibly a "valid" point; that is, we know it is
' close enough to the line, but we need to check
' if it is within the range that the line covers,
' or it falls off the line on either end.
If DistPtToLine <= Tolerance Then
' Calculate the length of the specified line
LenWholeLine = Sqr((.X2 - .X1) * (.X2 - .X1) + _
(.Y2 - .Y1) * (.Y2 - .Y1))
' Calculate the distance between the point we
' are checking and Point #1 on the line.
DistPtToX1Y1 = Sqr((.X1 - PX) * (.X1 - PX) + _
(.Y1 - PY) * (.Y1 - PY))
' Calculate the distance between the point we
' are checking and Point #2 on the line.
DistPtToX2Y2 = Sqr((.X2 - PX) * (.X2 - PX) + _
(.Y2 - PY) * (.Y2 - PY))
' Selecting Point #1 (because we need to pick an
' end), check if the distance between point we are
' checking, projected onto the line, is less than
' the length of the line.
If DistPtToX1Y1 * DistPtToX1Y1 - DistPtToLine * _
DistPtToLine < LenWholeLine * LenWholeLine Then
' If so, calculate the projected length for the
' distance from point we are checking to Point #2
LenAlongLine = Sqr(DistPtToX2Y2 * DistPtToX2Y2 - _
DistPtToLine * DistPtToLine)
End If
' If that projected length is not zero, then the
' point properly lies along side of the line.
If LenAlongLine > 0 Then
' Calculate the projected point's X and Y values
' (Point #2 being the reference point) using a
' direct proportion... length of projected line
' divided by length of line is the same as the
' X offset to the line from the point we are
' checking to the X offset of the whole line for
' the X-coordinate. Same ratio using Y offsets
' for the Y-coordinate.
ProjectedX = .X2 - (LenAlongLine * _
(.X2 - .X1)) / LenWholeLine
ProjectedY = .Y2 - (LenAlongLine * _
(.Y2 - .Y1)) / LenWholeLine
' Next, we simply see if the projected X and Y
' values lie between the end points of the line
' taking into account the orientation of the
' end points to each other.
If .X2 >= .X1 And ProjectedX >= .X1 And _
ProjectedX <= .X2 Then
If .Y2 >= .Y1 And ProjectedY >= .Y1 And _
ProjectedY <= .Y2 Or _
.Y2 < .Y1 And ProjectedY <= .Y1 And _
ProjectedY >= .Y2 Then
IsNearLine = True
End If
ElseIf .X2 <= .X1 And ProjectedX <= .X1 And _
ProjectedX >= .X2 Then
If .Y2 >= .Y1 And ProjectedY >= .Y1 And _
ProjectedY <= .Y2 Or .Y2 < .Y1 And _
ProjectedY <= .Y1 And ProjectedY >= .Y2 Then
IsNearLine = True
End If
End If
End If
End If
End If
End With
End Function
mr_unreliable - 20 Feb 2007 18:20 GMT
hi Husseina78,
What you are talking about sounds to me like a "form designer",
i.e., the kind of graphics that microsoft has included in vb
to draw in controls on a form (or user control).
That is, you have a "toolbox" with various icons (including
lines and boxes -- similar to the components of a piping system).
The user selects a toolbox element (say a line or a box) and
then draws it on his/her form. Later he/she may come back,
click on the control (line or box, etc) and little "sizing
handles" will appear. The user can then adjust the positioning
of his/her graphic elements.
I mention this for two reasons. For one, there is plenty of
sample code out there on the various vb source code download
sites showing how to do a "form designer" as found in vb.
And for two, the various piping design programs I have seen
work in just the same way, -- you select a piece of "hardware"
(line, valve, elbow, etc) from a "hardware menu" plop it down
on your drawing, and then move and/or adjust its positioning.
That should get you going.
The thing NOT found in the "form designer" code is the connections.
You will want your piping to connect with the other elements,
such as elbows, pumps, tanks, etc. However, there is something
in the "form designer" code samples that can be helpful with
this too. That is, the "Snap-To-Grid" code. With SnapToGrid,
you have a constraint similar to connecting piping elements.
With Snap-To-Grid, your (nearly) horizontal or vertical lines
will auto-magically become EXACTLY horizontal or vertical. You
could use the same sort of logic to make adjacent elements
of the piping system (magically) join up with each other.
cheers, jw
> Dears
> im petroleum engineer
> i want to create a program that enables the user to draw a pipeline system
> which consists of pipeline segments,pumping station,valves
> etc...
Michael C - 21 Feb 2007 06:50 GMT
> i found on this site an article about api functions concerning drawings
> but
[quoted text clipped - 5 lines]
>
> thanks in advance for your help
What you are describing is a bit of a project. If you're asking such general
questions it's probably best to hire a programmer. I'm sure the people you
work for are not short of dosh. :-)
Mark Yudkin - 25 Feb 2007 08:48 GMT
I know this is not quite the answer you're looking for, but have you
considered using Visio Professional (with VBA macros and/or a VB6 COM
addin), rather than trying to code the whole program in VB6?
Visio would give you most the drawing functionality "for free". For your
specific cases, no coding would be required: you only have to create the
object descriptions for your specific problem domain. You could also perform
a net search to see if there is already a set of Visio objects that
addresses your problem.
> Dears
> im petroleum engineer
[quoted text clipped - 41 lines]
>
> thanks in advance for your help