I've seen something on this before, and did some poking around on the web:
From:
Dev Luv: Top Ten Things to Know When Using the Visio 2003 ActiveX Control
at:
http://blogs.msdn.com/mailant/archive/2004/09/24/233928.aspx
I found this:
Automating Print Preview in the control almost made my list because the
Visio Automation Model doesn't provide a method for it and control
developers want to do this alot, but since it's really a general Visio
programming question and there's a code sample in the Visio 2003 SDK in
VB.NET, C#, and VB, it didn't make the cut for the list.
It turns out that there's a sample in the Visio SDK's Code Librarian. I've
copied it here for your convenience (VB.NET):
---------------------------------------------------
'// PrintPreview.vb
'// <copyright>Copyright (c) Microsoft Corporation. All rights reserved.
'// </copyright>
'// <summary>This file contains code that creates a custom print preview
'// dialog for a document.</summary>
Imports System
Namespace Microsoft.Samples.Visio.VBNet
'// <summary>This class contains code that creates a custom print
preview
'// dialog for a document.</summary>
Public Class PrintPreview
Inherits System.Windows.Forms.Form
'// <summary>The document and printer information is needed for
dialog
'// and print processing.</summary>
Private targetDocument As Microsoft.Office.Interop.Visio.Document
'// <summary>The document and printer information is needed for
dialog
'// and print processing.</summary>
Private selectedPrinter As String
' Form controls are added automatically as the form is designed.
Private WithEvents cancelationButton As System.Windows.Forms.Button
Private WithEvents printButton As System.Windows.Forms.Button
Private WithEvents drawingPicture As System.Windows.Forms.PictureBox
Private WithEvents noMetafileLabel As System.Windows.Forms.Label
'// <summary>Required designer variable.</summary>
Private components As System.ComponentModel.IContainer
'// <summary>This constructor only contains the form initialization
'// that is added automatically.</summary>
Public Sub New()
MyBase.New()
' Required for Windows Form Designer support
InitializeComponent()
End Sub
'// <summary>This implementation of the PreviewDrawing procedure
'// can be used without providing a printer. The default
'// (active) printer will be used.</summary>
'// <param name="subjectDocument">Visio document to view and
'// print</param>
Public Sub PreviewDrawing(ByVal subjectDocument As _
Microsoft.Office.Interop.Visio.Document)
Try
' Call the main implementation of PreviewDrawing,
' passing the active printer.
PreviewDrawing(subjectDocument, _
subjectDocument.Application.ActivePrinter)
Catch errorThrown As Exception
Debug.WriteLine(errorThrown.Message)
End Try
End Sub
'// <summary>This implementation of the PreviewDrawing method takes
'// both the Visio document and the printer. The page's picture
'// is loaded into the form control, and the information is saved
'// for later printing.</summary>
'// <remarks>The dialog must be shown with a call to ShowDialog()
'// after this method is called.</remarks>
'// <param name="subjectDocument">Visio document to view and print
'// </param>
'// <param name="printer">Desired printer to use</param>
Public Sub PreviewDrawing(ByVal subjectDocument As _
Microsoft.Office.Interop.Visio.Document, _
ByVal printer As String)
Dim pageMetafile As System.Drawing.Imaging.Metafile = Nothing
Dim temporaryShape As Microsoft.Office.Interop.Visio.Shape
Dim firstPage As Microsoft.Office.Interop.Visio.Page
Dim pageWidth As Double
Dim pageHeight As Double
Try
targetDocument = subjectDocument
selectedPrinter = printer
firstPage = subjectDocument.Pages(1)
' draw a frame around the page so the bounding box of the
' picture is the size of the page.
pageWidth = firstPage.PageSheet.CellsSRC( _
CShort(Microsoft.Office.Interop.Visio.VisSectionIndices.
_
visSectionObject), _
CShort(Microsoft.Office.Interop.Visio.VisRowIndices. _
visRowPage), _
CShort(Microsoft.Office.Interop.Visio.VisCellIndices. _
visPageWidth)).ResultIU
pageHeight = firstPage.PageSheet.CellsSRC( _
CShort(Microsoft.Office.Interop.Visio.VisSectionIndices.
_
visSectionObject), _
CShort(Microsoft.Office.Interop.Visio.VisRowIndices. _
visRowPage), _
CShort(Microsoft.Office.Interop.Visio.VisCellIndices. _
visPageHeight)).ResultIU
temporaryShape = firstPage.DrawRectangle(0, 0, _
pageWidth, pageHeight)
temporaryShape.CellsSRC( _
CShort(Microsoft.Office.Interop.Visio.VisSectionIndices.
_
visSectionObject), _
CShort(Microsoft.Office.Interop.Visio.VisRowIndices. _
visRowFill), _
CShort(Microsoft.Office.Interop.Visio.VisCellIndices. _
visFillPattern)).ResultIU = 0
' Get the metafile from the drawing
pageMetafile = getMetafileFromPage(firstPage)
' delete the temporary shape
temporaryShape.Delete()
If (Not pageMetafile Is Nothing) Then
' Scale the metafile and insert it into the PictureBox
showMetafile(drawingPicture, pageMetafile)
Else
' The picture isn't available.
' Just show the not available message.
noMetafileLabel.Visible = True
drawingPicture.Visible = False
End If
Catch errorThrown As Exception
Debug.WriteLine(errorThrown.Message)
End Try
End Sub
'// <summary>Clean up any resources being used. This is
automatically
'// added.</summary>
'// <param name="disposing">true to release both managed and
unmanaged
'// resources; false to release only unmanaged resources.</param>
Protected Overloads Overrides Sub Dispose(ByVal disposing As
Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
#Region " Windows Form Designer generated code "
'NOTE: The following procedure is required by the Windows Form
Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
Me.drawingPicture = New System.Windows.Forms.PictureBox
Me.printButton = New System.Windows.Forms.Button
Me.cancelationButton = New System.Windows.Forms.Button
Me.noMetafileLabel = New System.Windows.Forms.Label
Me.SuspendLayout()
'
'drawingPicture
'
Me.drawingPicture.BackColor = System.Drawing.SystemColors.Window
Me.drawingPicture.Location = New System.Drawing.Point(8, 8)
Me.drawingPicture.Name = "drawingPicture"
Me.drawingPicture.Size = New System.Drawing.Size(272, 216)
Me.drawingPicture.SizeMode = _
System.Windows.Forms.PictureBoxSizeMode.CenterImage
Me.drawingPicture.TabIndex = 5
Me.drawingPicture.TabStop = False
'
'printButton
'
Me.printButton.Location = New System.Drawing.Point(117, 237)
Me.printButton.Name = "printButton"
Me.printButton.TabIndex = 4
Me.printButton.Text = "Print"
'
'cancelationButton
'
Me.cancelationButton.Location = New System.Drawing.Point(205,
237)
Me.cancelationButton.Name = "cancelationButton"
Me.cancelationButton.TabIndex = 3
Me.cancelationButton.Text = "Cancel"
'
'noMetafileLabel
'
Me.noMetafileLabel.Font = New System.Drawing.Font( _
"Microsoft Sans Serif", 18.0!,
System.Drawing.FontStyle.Bold, _
System.Drawing.GraphicsUnit.Point, CType(0, Byte))
Me.noMetafileLabel.Location = New System.Drawing.Point(32, 56)
Me.noMetafileLabel.Name = "noMetafileLabel"
Me.noMetafileLabel.Size = New System.Drawing.Size(224, 72)
Me.noMetafileLabel.TabIndex = 6
Me.noMetafileLabel.Text = "No Preview is Available"
Me.noMetafileLabel.TextAlign = _
System.Drawing.ContentAlignment.MiddleCenter
Me.noMetafileLabel.Visible = False
'
'PrintPreview
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(288, 272)
Me.Controls.Add(Me.noMetafileLabel)
Me.Controls.Add(Me.drawingPicture)
Me.Controls.Add(Me.printButton)
Me.Controls.Add(Me.cancelationButton)
Me.FormBorderStyle = _
System.Windows.Forms.FormBorderStyle.FixedSingle
Me.MinimizeBox = False
Me.MaximizeBox = False
Me.Name = "PrintPreview"
Me.Text = "PrintPreview"
Me.ResumeLayout(False)
End Sub
#End Region
'// <summary>This handler is called when the user clicks on
'// the Cancel button. The form is closed.</summary>
'// <param name="sender">Object raising the event</param>
'// <param name="e">Event arguments</param>
Private Sub cancelButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles cancelationButton.Click
' Close the dialog.
Close()
End Sub
'// <summary>This handler is called when the user clicks on the
'// Print button. The document is printed using the Visio Print
'// method.</summary>
'// <remarks>Classes in managed code can be used to perform this
'// operation by overriding the PrintPage event and providing the
'// Visio Picture for each page as it's printed. The Visio
'// Print method is available for both in-proc and out-of-proc
'// processes.</remarks>
'// <param name="sender">Object raising the event</param>
'// <param name="e">Event arguments</param>
Private Sub printButton_Click1(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles printButton.Click
Dim currentActivePrinter As String
Try
' Set up the desired printer. Save the current printer
' so that it can be restored when this print process is
' done.
currentActivePrinter = _
targetDocument.Application.ActivePrinter()
If Not (currentActivePrinter = selectedPrinter) Then
targetDocument.Application.ActivePrinter = _
selectedPrinter
End If
' Use the Visio print command to print the document.
Dim oldCursor As System.Windows.Forms.Cursor
oldCursor = Cursor
Cursor = System.Windows.Forms.Cursors.WaitCursor
targetDocument.Print()
Cursor = oldCursor
' Restore the original active printer.
If Not (currentActivePrinter = selectedPrinter) Then
targetDocument.Application.ActivePrinter = _
currentActivePrinter
End If
Catch errorThrown As Exception
Debug.WriteLine(errorThrown.Message)
End Try
End Sub
'// <summary>Display the metafile in a picture box control</summary>
'// <remarks>This scales the metafile to fit the picture box control
'// and adjusts the picture box width and height to maintain the
'// correct aspect ratio.</remarks>
'// <param name="pictureBox">PictureBox to display metafile
in</param>
'// <param name="metafile">Metafile to display in the picture box
'// </param>
Private Sub showMetafile( _
ByVal pictureBox As System.Windows.Forms.PictureBox, _
ByVal metafile As System.drawing.imaging.Metafile)
Dim metafileImage As System.drawing.Image
Dim pictureBoxRect As System.drawing.Rectangle
Dim scale As Double
Dim scaleWidth As Double
Dim pictureWidth As Integer
Dim pictureHeight As Integer
pictureBoxRect = pictureBox.ClientRectangle
If ((metafile.Height > 0) And (metafile.Width > 0)) Then
scale = CType(pictureBoxRect.Height / metafile.Height,
Double)
scaleWidth = CType(pictureBoxRect.Width / metafile.Width,
Double)
If (scaleWidth < scale) Then
scale = scaleWidth
End If
pictureWidth = CType(metafile.Width * scale, Int32)
pictureHeight = CType(metafile.Height * scale, Int32)
metafileImage = metafile.GetThumbnailImage(pictureWidth, _
pictureHeight, Nothing, IntPtr.Zero)
' Load the metafile into the control.
pictureBox.Image = metafileImage
' center the picture control
pictureBox.Left = _
CInt((ClientRectangle.Width - pictureWidth) / 2)
pictureBox.Width = pictureWidth
pictureBox.Height = pictureHeight
End If
End Sub
'// <summary>Get a metafile representing the Visio page</summary>
'// <remarks>This will first try the page.Picture method. If that
fails
'// (typically because Visio is out-of-process) this will export
'// the page to a temporary file in enhanced metafile
format.</remarks>
'// <param name="subjectPage">Visio page to get metafile of</param>
'// <returns>Metafile if available, otherwise null</returns>
Private Function getMetafileFromPage(ByVal subjectPage As _
Microsoft.Office.Interop.Visio.Page) As _
System.Drawing.Imaging.Metafile
Dim pageMetafile As System.Drawing.Imaging.Metafile = Nothing
Dim pagePicture As stdole.IPictureDisp
Dim convertedPictureHandle As IntPtr = Nothing
Dim temporaryFileName As String
Try
' Get the metafile from the drawing
' Visio returns an IPictureDisp interface which cannot be
' marshaled between processes. If Visio is out of process
then
' a COMException will be thrown.
pagePicture = subjectPage.Picture
convertedPictureHandle = New IntPtr(pagePicture.Handle)
pageMetafile = New System.Drawing.Imaging.Metafile( _
convertedPictureHandle, False)
Catch comError As System.Runtime.InteropServices.COMException
' Ignore this exception
End Try
If pageMetafile Is Nothing Then
' save the page as an enhanced metafile
temporaryFileName = System.IO.Path.GetTempFileName()
System.IO.File.Delete(temporaryFileName)
temporaryFileName = System.IO.Path.ChangeExtension( _
temporaryFileName, "emf")
subjectPage.Export(temporaryFileName)
pageMetafile = CType(New System.Drawing.Imaging.Metafile( _
temporaryFileName), System.drawing.imaging.Metafile)
End If
Return pageMetafile
End Function
End Class
End Namespace
---------------------------------------------------