Visio Guy

Visio Discussions => Programming & Code => Topic started by: perry59 on February 21, 2017, 11:17:44 PM

Title: drop master here
Post by: perry59 on February 21, 2017, 11:17:44 PM
there are a number of examples of dropping master shapes on a document, so that is pretty easy and straightforward.
They all have in common one thing though, you have to supply coordinates to place it. i.e.  page.Drop(master, 4, 4)
My question is:
Is there any way to programmatically drop a master, but have the shape attached to the mouse cursor as if you were dragging it off a stencil?
Title: Re: drop master here
Post by: Surrogate on February 22, 2017, 04:38:21 PM
that code can get click coordinates.
QuoteThis code is part of code which originally posted at
'  https://translate.google.ru/translate?sl=ru&tl=en&js=y&prev=_t&hl=ru&ie=UTF-8&u=http%3A%2F%2Fvisio.getbb.ru%2Fviewtopic.php%3Ff%3D15%26t%3D671&edit-text=&act=url
Dim WithEvents myapp As Visio.Application
Dim x As Double, y As Double

'Start-up procedure
Sub Start ()
Set myapp = Application
End Sub

'Beginning of the intersecting separation frame - storing coordinates
Private Sub myapp_MouseDown (ByVal Button As Long, ByVal KeyButtonState As Long, ByVal x1 As Double, ByVal y1 As Double, CancelDefault As Boolean)
If Button = 1 Then 'Left mouse button
x = x1: y = y1
End If
End Sub
but i haven't idea how make the program wait when the user clicks ?
Title: Re: drop master here
Post by: perry59 on February 22, 2017, 08:57:48 PM
Thanks Surrogate
I know how to get the mouse coordinates, but I don't think there is a way to drop a shape without supplying coordinates in the function call.
what I would like to do is something like drop shape function where the shape follows the mouse cursor until it is clicked, then completes.
Title: Re: drop master here
Post by: wapperdude on February 23, 2017, 02:18:51 AM
I'm probably the last person to comment on something like this...have no idea how to use events...but what strikes me about  is that mouse events are reactionary, that is, the mouse does something and an event fires.  I don't think there are mouse command objects or properties, so you can't attach the shape to the mouse.

Wapperdude
Title: Re: drop master here
Post by: Hey Ken on February 23, 2017, 02:15:48 PM
Perry:

    I do this trick all the time with my stencil-based macros.

    I start with a Mouse Up window event in the stencil's ThisDocument module that stores the mouse X and Y in the document's shapesheet as follows:



Public WithEvents EventWindow As Visio.Window

Private Sub EventWindow_MouseUp(ByVal Button As Long, ByVal KeyButtonState As Long, ByVal x As Double, ByVal y As Double, CancelDefault As Boolean)

Dim TheDocument      As Document
Dim TheDocumentSheet As Shape

Set TheDocument = ActiveDocument
Set TheDocumentSheet = TheDocument.DocumentSheet

If Not TheDocumentSheet.CellExists("User.MouseX", 0) Then
    TheDocumentSheet.AddNamedRow(visSectionUser, "MouseX", 0)
    End If
If Not TheDocumentSheet.CellExists("User.MouseY", 0) Then
    TheDocumentSheet.AddNamedRow(visSectionUser, "MouseY", 0)
    End If

TheDocumentSheet.Cells("User.MouseX").Formula = x
TheDocumentSheet.Cells("User.MouseY").Formula = y

End Sub



    Next, on the master shape, on its shapesheet, in the EventDrop cell, I have a call to a stencil macro, =CALLTHIS("ThisDocument.Dropped","Kencil"), where "Kencil" is the name of my stencil , and "Dropped" is defined in the stencil's ThisDocument module as follows:



Public Sub Dropped(ByRef TheDroppedShape As Visio.Shape)

Dim TheDocument      As Document
Dim TheDocumentSheet As Shape

Set TheDocument = ActiveDocument
Set TheDocumentSheet = TheDocument.DocumentSheet

TheDroppedShape.Cells("PinX").Formula = TheDocumentSheet.Cells("User.MouseX").Formula
TheDroppedShape.Cells("PinY").Formula = TheDocumentSheet.Cells("User.MouseY").Formula

End Sub



   My apologies, but I did not test this code.  I'd post the original out of my Kencil, but it has a lot of other stuff that obfuscates the simplicity of the task. But this should point you in the right direction--I hope.

    - Ken


Title: Re: drop master here
Post by: perry59 on February 23, 2017, 05:53:09 PM
Quote from: Hey Ken on February 23, 2017, 02:15:48 PM
Perry:

    I do this trick all the time with my stencil-based macros.

    I start with a Mouse Up window event in the stencil's ThisDocument module that stores the mouse X and Y in the document's shapesheet as follows:



Public WithEvents EventWindow As Visio.Window

Private Sub EventWindow_MouseUp(ByVal Button As Long, ByVal KeyButtonState As Long, ByVal x As Double, ByVal y As Double, CancelDefault As Boolean)

Dim TheDocument      As Document
Dim TheDocumentSheet As Shape

Set TheDocument = ActiveDocument
Set TheDocumentSheet = TheDocument.DocumentSheet

If Not TheDocumentSheet.CellExists("User.MouseX", 0) Then
    TheDocumentSheet.AddNamedRow(visSectionUser, "MouseX", 0)
    End If
If Not TheDocumentSheet.CellExists("User.MouseY", 0) Then
    TheDocumentSheet.AddNamedRow(visSectionUser, "MouseY", 0)
    End If

TheDocumentSheet.Cells("User.MouseX").Formula = x
TheDocumentSheet.Cells("User.MouseY").Formula = y

End Sub



    Next, on the master shape, on its shapesheet, in the EventDrop cell, I have a call to a stencil macro, =CALLTHIS("ThisDocument.Dropped","Kencil"), where "Kencil" is the name of my stencil , and "Dropped" is defined in the stencil's ThisDocument module as follows:



Public Sub Dropped(ByRef TheDroppedShape As Visio.Shape)

Dim TheDocument      As Document
Dim TheDocumentSheet As Shape

Set TheDocument = ActiveDocument
Set TheDocumentSheet = TheDocument.DocumentSheet

TheDroppedShape.Cells("PinX").Formula = TheDocumentSheet.Cells("User.MouseX").Formula
TheDroppedShape.Cells("PinY").Formula = TheDocumentSheet.Cells("User.MouseY").Formula

End Sub



   My apologies, but I did not test this code.  I'd post the original out of my Kencil, but it has a lot of other stuff that obfuscates the simplicity of the task. But this should point you in the right direction--I hope.

    - Ken

Thanks Ken, but that is not really what I am looking for
Title: Re: drop master here
Post by: perry59 on February 23, 2017, 05:56:41 PM
Quote from: wapperdude on February 23, 2017, 02:18:51 AM
I'm probably the last person to comment on something like this...have no idea how to use events...but what strikes me about  is that mouse events are reactionary, that is, the mouse does something and an event fires.  I don't think there are mouse command objects or properties, so you can't attach the shape to the mouse.

Wapperdude

Yeah, it's dumb that the DROP method requires pre-defined coordinates.
what if those pre-defined coordinates are the upper left corner of the drawing and the user is zoomed into the lower right corner. when he runs the command he'll never see the shape get dropped.
Lame!
Title: Re: drop master here
Post by: perry59 on February 24, 2017, 12:07:11 AM
One may wonder why I want to do this in code, since you can just drag a master off a stencil with the effect that I want.
What I need to do is pull one master out of the stencil, then pull another shape off the stencil and place it into the first one, thereby creating a group which I then want to drag to its location on the page. The configuration of this group can change depending on user input so I cant just put all these grouped objects in the stencil.
An idea occurred to me, but haven't tried in code yet. Maybe this could work. I will try to drop the master in some location way off the page where it likely wont be seen, then drop the other shapes into it, make the group. Then with the group selected, constantly update its PinX and PinY cells based on input from a mouse listener. When the user clicks, quit updating those cells and turn off the mouse listener.
Does this sound do-able?
Title: Re: drop master here
Post by: wapperdude on February 24, 2017, 12:28:56 AM
Well, why did cross my mind.

Using the Window.GetWindowReectangle method ought to allow you to determine a set of coordinates within the viewing window.  You could drop your shapes to desired coordinate, group, and since viewable, grab and locate as needed.  This is for newer Visio versions, so, I can't discuss it.  https://msdn.microsoft.com/en-us/library/office/ff765668.aspx (https://msdn.microsoft.com/en-us/library/office/ff765668.aspx)

Wapperdude
Title: Re: drop master here
Post by: AndyW on February 24, 2017, 02:12:01 PM
Can't you drag your initial shape from the stencil and drop it where you want it, then programatically take your other shape from the stencil and group it into the original dropped shape.
Title: Re: drop master here
Post by: perry59 on February 24, 2017, 04:05:34 PM
Quote from: AndyW on February 24, 2017, 02:12:01 PM
Can't you drag your initial shape from the stencil and drop it where you want it, then programatically take your other shape from the stencil and group it into the original dropped shape.

You could do that, of course, but that is not what I want to do.
This is going to be a command function in a larger visio addin for adding electrical connectors to a sheet.
the user selects a connector from the database and it is inserted.
I don't want the command to ask the user to select a connector from the database and then ask him to drag stuff from a stencil (which may or may not be loaded/visible)
Title: Re: drop master here
Post by: wapperdude on February 25, 2017, 12:12:57 AM
Connectors say you.  Tell us a little more or show a couple examples of variants.  This might be do-able with a single smartshape.  There have been several different style/versions done on the forum. 

Wapperdude
Title: Re: drop master here
Post by: AndyW on February 27, 2017, 01:11:23 PM
You could use OLE drag-n-drop, drag something off your form, then tracking the mouse events put your shape at the drop location on you diagram.

https://youtu.be/apUZ1Xt3EKc (https://youtu.be/apUZ1Xt3EKc)
Title: Re: drop master here
Post by: perry59 on February 27, 2017, 04:19:48 PM
Quote from: wapperdude on February 25, 2017, 12:12:57 AM
Connectors say you.  Tell us a little more or show a couple examples of variants.  This might be do-able with a single smartshape.  There have been several different style/versions done on the forum. 

Wapperdude

These are connectors used in aviation equipment. Typically Mil Spec or our custom D-subs. they can have a few as 9 contacts or over 100.
The contacts (pins or sockets) and the connector symbol will be part of a group with custom properties. A sql database will track how many contacts are shown. A connector can be "broken", i.e. part of it shown on one page, another part of it shown somewhere else but it would still be considered the same physical connector by the database. The user may choose to show all the contacts or just some. So unused contacts can still be used later by inserting another portion of the connector. When a visio connector object is attached to a contact, it sets a flag for that contact in the database as being used. This allows for creating reports on how many connectors are in a project and how many of their contacts are "hooked up". I also generate wire reports on all visio connector objects which are "wires" and their to-from.
I have attached a small drawing showing a couple of variations.
Title: Re: drop master here
Post by: perry59 on February 27, 2017, 04:21:40 PM
Quote from: wapperdude on February 24, 2017, 12:28:56 AM
Well, why did cross my mind.

Using the Window.GetWindowReectangle method ought to allow you to determine a set of coordinates within the viewing window.  You could drop your shapes to desired coordinate, group, and since viewable, grab and locate as needed.  This is for newer Visio versions, so, I can't discuss it.  https://msdn.microsoft.com/en-us/library/office/ff765668.aspx (https://msdn.microsoft.com/en-us/library/office/ff765668.aspx)

Wapperdude

looks like that wont work with visio 2007, which I am stuck with.
I am busy with a Solidworks project right now. when I'm done I will get back to my mad visio experiments!
Title: Re: drop master here
Post by: wapperdude on February 27, 2017, 07:40:35 PM
Actually, does work with V2007.  Try this code:

Sub MoveShp2CntrView()

    Dim lVz As Double, tVz As Double, wVz As Double, hVz As Double
    Dim locX As Double, locY As Double
    Dim vsoShp As Shape
   
    Visio.ActiveWindow.GetViewRect lVz, tVz, wVz, hVz
'    Debug.Print "Current View Window: " & lVz, tVz, wVz, hVz

'Calculate center of View:
    locX = lVz + 0.5 * wVz
    locY = tVz - 0.5 * hVz
'    Debug.Print locX, locY

'Use shape based upon selection:
'    Set vsoShp = ActiveWindow.Selection(1)
'    vsoShp.CellsU("PinX").FormulaU = locX
'    vsoShp.CellsU("PinY").FormulaU = locY

'Use shape based upon ID:
    Set vsoShp = ActivePage.Shapes.ItemFromID(1)
    ActiveWindow.Select vsoShp, visSelect   'Optional:  this makes the shape ACTIVE
   
    vsoShp.CellsU("PinX").FormulaU = locX
    vsoShp.CellsU("PinY").FormulaU = locY
End Sub


Wapperdude
Title: Re: drop master here
Post by: perry59 on March 01, 2017, 11:31:11 PM
Quote from: wapperdude on February 25, 2017, 12:12:57 AM
Connectors say you.  Tell us a little more or show a couple examples of variants.  This might be do-able with a single smartshape.  There have been several different style/versions done on the forum. 

Wapperdude

do tell
Title: Re: drop master here
Post by: perry59 on March 01, 2017, 11:37:43 PM
Quote from: wapperdude on February 24, 2017, 12:28:56 AM
Well, why did cross my mind.

Using the Window.GetWindowReectangle method ought to allow you to determine a set of coordinates within the viewing window.  You could drop your shapes to desired coordinate, group, and since viewable, grab and locate as needed.  This is for newer Visio versions, so, I can't discuss it.  https://msdn.microsoft.com/en-us/library/office/ff765668.aspx (https://msdn.microsoft.com/en-us/library/office/ff765668.aspx)

Wapperdude

I'm not sure how the Window.GetWindowReectangle is going to help me.
I have already got my shapes dropped and grouped on the page. The thing I cant figure out is how to move them around on the page with the mouse cursor.
code like this does NOT work

'while mouse left button is NOT down...
        While mouseDownForConnector = False 'mouseDownForConnector is a global boolean variable
            'mouseDownForConnector is set to true and false by the mousehandler events
            groupShape.CellsU("PinX").FormulaU = mouseHandler.xPos.ToString() & " in"
            groupShape.CellsU("PinY").FormulaU = mouseHandler.yPos.ToString() & " in"
        End While


it just goes into an endless loop.
it seems that the group I create does not actually appear on the page until the function is completed.
maybe I should be trapping the shape drop event and trying to do my moving there (assuming the shape dropped is the one I want)
Title: Re: drop master here
Post by: Surrogate on March 01, 2017, 11:52:04 PM
Quote from: perry59 on March 01, 2017, 11:37:43 PMit just goes into an endless loop.
not sure that your task impossible in visio because there haven't special event for get mouse click coordinate.
For example AutoCAD have GetPoint Method (https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2017/ENU/AutoCAD-ActiveX/files/GUID-5C8BA75E-5F87-479B-B167-3961F93E617E-htm.html) which stoped code execution until then define point
Title: Re: drop master here
Post by: perry59 on March 02, 2017, 12:35:59 AM
Quote from: Surrogate on March 01, 2017, 11:52:04 PM
Quote from: perry59 on March 01, 2017, 11:37:43 PMit just goes into an endless loop.
not sure that your task impossible in visio because there haven't special event for get mouse click coordinate.
For example AutoCAD have GetPoint Method (https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2017/ENU/AutoCAD-ActiveX/files/GUID-5C8BA75E-5F87-479B-B167-3961F93E617E-htm.html) which stoped code execution until then define point

Good 'ole AutoCAD!
Title: Re: drop master here
Post by: wapperdude on March 02, 2017, 12:42:24 AM
@Perry59:  did you look at the code snippet I provided?  Well, please look at the attached file.

The macro draws two squares.  Then it groups them.  After grouping, the move shape macro is called.

To demonstrate:  start with just the oval shape visible.  More dramatic that way.  Then, zoom in on the oval, about 500X.  Reposition the window so the oval is NOT centered in the viewing window.  Now, run the macro.  Phoosh!  A group of 2 squares appears centered in the screen.  The group is still selected.  Mouse over, push left button down, drag the group to desired location.  NO mouse events necessary.

Wapperdude
Title: Re: drop master here
Post by: perry59 on March 02, 2017, 04:03:59 PM
Quote from: wapperdude on March 02, 2017, 12:42:24 AM
@Perry59:  did you look at the code snippet I provided?  Well, please look at the attached file.

The macro draws two squares.  Then it groups them.  After grouping, the move shape macro is called.

To demonstrate:  start with just the oval shape visible.  More dramatic that way.  Then, zoom in on the oval, about 500X.  Reposition the window so the oval is NOT centered in the viewing window.  Now, run the macro.  Phoosh!  A group of 2 squares appears centered in the screen.  The group is still selected.  Mouse over, push left button down, drag the group to desired location.  NO mouse events necessary.

Wapperdude

Yes I have seen that. Thanks for posting.
Perhaps I have not been clear in what I am trying to achieve (which I am afraid is probably not possible in the visio API)
I have no problem in programmatically dropping shapes on the sheet, or moving them once they are there.
what I want to do is that immediately after the shape appears, it is "attached" to the mouse cursor and follows the mouse cursor until the user clicks, then it is set at that location.
Again, probably not possible, I may have to change my approach to the problem.
-Perry
Title: Re: drop master here
Post by: wapperdude on March 02, 2017, 05:01:52 PM
I think we're splitting hairs here.  I understand you know how to drop, group, and move.  The issue is attaching to the mouse.  Presumably, there are occasions when the drop/group may take place outside of user view, i.e., off screen.  And, the mouse will be within user view.  Hence, assign the group to the mouse and the group pops into view, attached to the mouse, and the user can drag to desired location and place.

I don't think you can do the attach to mouse, nor do I think it's necessary.  That was the point of the file and it's demo.  The macro replicates your drop/group, which, for the demo is off view screen.  Then, wherever the user is viewing, the group is moved to that location.  The group remains selected.  So, yes, the user must mouse over, left click, drag and position as desired.  That's minimal user interaction.  The user knows the shape will be center screen.  This ought to satisfy 98% of your requirements.  Plus, the code is quite simple.

Wapperdude
Title: Re: drop master here
Post by: perry59 on March 02, 2017, 06:18:49 PM
Quote from: wapperdude on March 02, 2017, 05:01:52 PM
I think we're splitting hairs here.  I understand you know how to drop, group, and move.  The issue is attaching to the mouse.  Presumably, there are occasions when the drop/group may take place outside of user view, i.e., off screen.  And, the mouse will be within user view.  Hence, assign the group to the mouse and the group pops into view, attached to the mouse, and the user can drag to desired location and place.

I don't think you can do the attach to mouse, nor do I think it's necessary.  That was the point of the file and it's demo.  The macro replicates your drop/group, which, for the demo is off view screen.  Then, wherever the user is viewing, the group is moved to that location.  The group remains selected.  So, yes, the user must mouse over, left click, drag and position as desired.  That's minimal user interaction.  The user knows the shape will be center screen.  This ought to satisfy 98% of your requirements.  Plus, the code is quite simple.

Wapperdude

That's true.
what I originally wanted is probably not possible.
I'll have to modify my desires!
Title: Re: drop master here
Post by: wapperdude on March 02, 2017, 06:37:05 PM
Life is full of compromises!   :-\
Title: Re: drop master here
Post by: perry59 on March 02, 2017, 08:23:13 PM
Quote from: wapperdude on March 02, 2017, 06:37:05 PM
Life is full of compromises!   :-\

That it is, but at least I can drop my shape where the user will see it!
Thanks