Window.CenterViewOnShape doesn't work for me for centering one shape in window

Started by Visisthebest, July 28, 2023, 10:02:54 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Visisthebest

There are several good topics in the forum on how to show a specific Visio shape centered in a Visio windows.

The simple tip was just to use Window.CenterViewOnShape but it doesn't work well for me and is unpredictable. I just cannot count on it to just show the specific shape at the center of the window.

Visio Guy and Thomas shared code here I'm going to try it for my purpose: http://visguy.com/vgforum/index.php?topic=6144.0

Then convert it to vb.net for a .NET VSTO add-in. The working vb.net code I'll share here as there is only VBA code available to solve this currently.
Visio 2021 Professional

Visisthebest

Thomas Winkel's code doesnt' work for me, but Visio Guy's code works fine!

Still in VBA here, made a small change to the calling code (I'd rather select a shape, then test the VBA sub).

I need to change the code slightly because I do not want to zoom in just put the shape in the center of the window (leave the zoom level unchanged), but again this is some good code by Visio Guy!


Sub CenterOnSelected()

Dim Sel As Selection
Dim S As Shape

Set S = ActiveWindow.Selection(1)

Call CenterShapeInView(S)


End Sub


Public Sub CenterShapeInView(ByRef visShp As Visio.Shape)

  '// Notes:
  '// 'w' stands for 'width' and 'window'
  '// 'h' stands for 'height',
  '// 'l', 't', 'r', 'b' stand for 'left', 'top', 'right', 'bottom'
 
  Dim win As Visio.Window
  Set win = visShp.Application.ActiveWindow
 
  If (win.Type = Visio.VisWinTypes.visDrawing) Then
 
    '// Switch the page in the active window so
    '// that it is the page that visShp is on:
    win.Page = visShp.ContainingPage
   
    '// Select the shape:
    Call win.DeselectAll
    Call win.Select(visShp, Visio.VisSelectArgs.visSelect)
   
    '// Zoom and pan:
   
    '// Get the dimensions of the active window. These
    '// are PAGE coordinates for what is displayed in the
    '// window:
    Dim wl As Double, wt As Double, ww As Double, wh As Double
    Call win.GetViewRect(wl, wt, ww, wh)
   
    '// Get the size and position of the shape:
    Dim flags As Integer
    flags = Visio.VisBoundingBoxArgs.visBBoxUprightWH
   
    '// Get the left, bottom, right, top of the shape, and
    '// calculate the center point:
    Dim sl As Double, sb As Double, sr As Double, st As Double
    Dim sx As Double, sy As Double
    Call visShp.BoundingBox(flags, sl, sb, sr, st)
    sx = (sl + sr) * 0.5
    sy = (st + sb) * 0.5
           
    '// Calculate the width and height:
    Dim sw As Double, sh As Double
    sw = Math.Abs(sr - sl)
    sh = Math.Abs(st - sb)
   
    '// Add some padding around the shape, because win.SetViewRect
    '// doesn't seem to be exact when we try to zoom. Let's take
    '// a percentage of the shape's size:
    Const PaddingPct# = 0.05 '//...5% padding
    Dim padding As Double
    If (sw > sh) Then
      padding = PaddingPct * sw
    Else
      padding = PaddingPct * sh
    End If
   
    '// Recalculate the shape dimensions with the added padding:
    sl = sl - padding
    sr = sr + padding
    st = st + padding
    sb = sb - padding
    sw = sr - sl
    sh = st - sb
   
    '// Calculate aspect rations of window and shape.
    '// Greater-than-one means 'more wide than tall':
    Dim arw As Double, ars As Double
    arw = ww / wh
    ars = sw / sh
   
   
    '// We will maximize the view of the shape in the
    '// window. This means that either the sides of the shape
    '// or the shape's top and bottom will be against the
    '// edges of the window. We have to figure this out using
    '// geometry.
   
    '// We'll set up some new dimensions for the window's view:
    Dim wlNew As Double, wtNew As Double, wrNew As Double, wbNew As Double
    Dim wwNew As Double, whNew As Double
   
    If (ars > arw) Then
     
      '// The shape is more 'wider' than the window.
     
      '// The window's left and right should match that
      '// of the shape:
      wlNew = sl
      wrNew = sr
      wwNew = wrNew - wlNew '//...the new view width
     
      '// Thew window's top and bottom SHOULD be calculated,
      '// but since the size of the window won't really change,
      '// we COULD enter nonsense values. But we'll try and
      '// calculate anyway:
      whNew = wwNew / arw '//...width/(width/height) => height
      wtNew = sy + wwNew * 0.5
      wbNew = sy - wwNew * 0.5
     
    Else
   
      '// The window is more 'wider' than the shape.
     
      '// The window's top and bottom should match that
      '// of the shape:
      wtNew = st
      wbNew = sb
      whNew = wtNew - wbNew '//...the new view height
     
      '// Thew window's left and right must be calculated:
      wwNew = arw * whNew '//...(width/height)*height => width
      wlNew = sx - wwNew * 0.5
      wrNew = sx + wwNew * 0.5
     
    End If
   
    '// Set the new window view:
    Call win.SetViewRect(wlNew, wtNew, wwNew, whNew)
   
  Else
    '// Make the active window a ShapeSheet window to
    '// make this happen:
    Call MsgBox("Active window is not a drawing window, I'm not sure what to do!")
  End If

End Sub
Visio 2021 Professional

Visisthebest

Actually I see Visio Guy's code is really about zooming in on a specific shape, so changing this code to leave the zoom level unchanged is a bit more than a slight change.

Maybe there is some VBA code that just does exactly what I need, which is to put one shape that is selected in the center of the window, keeping the zoom level exactly the same as it was.
Visio 2021 Professional

wapperdude

Visio 2019 Pro

Visisthebest

Thank you Wapperdude I understand shape.centerDrawing will cause a shape to move, but the shapes should stay in the exact same position only the Visio window should move to center around the selected shape.
Visio 2021 Professional