To create the Cover Designer application, you need to create the Cover Designer window, the Image Details window, the VisioEvents class, and the VisioMethods class.
The CoverDesigner project uses the frmCoverDesigner class to define the Cover Designer application window. The application allows the end user to design the covers using the images in the picture boxes provided by the Cover Designer window. This window also allows the end user to save the designed covers, create a new cover, open an existing cover, and see the print preview of the cover.
Listing 6-2 shows the code for the frmCoverDesigner.vb file:
Imports System.IO Imports Microsoft.Office.Interop.Visio Imports System.Runtime.InteropServices Imports System.Data.SqlClient Public Class frmCoverDesigner Inherits System.Windows.Forms.Form 'An array list to store the picture box controls in the gallery group box Dim pictureboxlist As New ArrayList Dim files() As String 'An object of the VisioEvents class that handles visio events Dim objVisioEvents As VisioEvents 'The clickedImage object refers to the image that is clicked Dim clickedImage As Shape 'A directory object to hold the path of current directory Dim currentDirectory As Directory 'A string variable to hold the path of any folder Dim currentPath As String 'An array list to hold the names of the opened drawings in the visio drawing control Dim drawingControlList As New ArrayList 'The point on X-axis of visio drawing Dim locationX As Double = 0.0 'The point on Y-axis of visio drawing Dim locationY As Double = 0.0 'The shape returned when the user drops an image on the drawing control Dim dropImage As Shape Dim targetPage As Microsoft.Office.Interop.Visio.Page 'An object to act as the target stencil in which the images in the gallery are stored as shapes Dim targetStencil As Document Dim targetdocuments As Documents 'A variable that contains the total number of images on the drawing control Dim totalImages As Integer 'A rectangle object to keep in track the area selected by the user on the drawing control to write some text. Dim rect As New Rectangle 'A sqlconnection object to establish connection with CoverDesginer database Dim sqlConnection As New SqlConnection Private Sub frmCoverDesigner_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Establish a connection with the CoverDesigner database to retrieve the image categories Try Try 'Read connectionstring from a text file, settings.txt, located in '/bin folder of the application Dim sr As New StreamReader("Settings.txt") sqlConnection.ConnectionString = sr.ReadLine sr.Close() Catch ex As Exception 'If file settings.txt not found sqlConnection.ConnectionString = "SERVER=localhost;UID=sa;PWD=sa;Initial Catalog=QueryTracker" End Try sqlConnection.Open() Catch ex As Exception MsgBox("Error in establishing connection", MsgBoxStyle.OKOnly, "CONNECTION ERROR") Exit Sub End Try 'Retrieving image categories from the database Dim ds As New DataSet Try Dim sqlCommand As New SqlCommand("Select imageCategory from ImageCategory", sqlConnection) Dim sqlda As New SqlDataAdapter(sqlCommand) sqlda.Fill(ds) Catch ex As Exception MsgBox("Error in retrieving image categories from database", MsgBoxStyle.OKOnly, "Retrieval Error") Exit Sub End Try 'Adding the available image categories in the listCooseGallery list box If Not ds.Tables.Count = 0 And Not ds.Tables(0).Rows.Count = 0 Then Dim categoryCount As Integer For categoryCount = 0 To ds.Tables(0).Rows.Count - 1 listChooseGallery.Items.Add(ds.Tables(0).Rows(categoryCount).Item(0)) Next End If 'A variable to iterate through the picture box controls in the gallery group box Dim pictureboxcount As Integer 'Adding the picture box controls in an array list collection Dim i As Integer For pictureboxcount = 0 To Gallery.Controls.Count - 1 If TypeOf Gallery.Controls(pictureboxcount) Is PictureBox Then pictureboxlist.Add(Gallery.Controls(pictureboxcount)) End If Next listChooseGallery.SelectedIndex = 0 listChooseGallery_Click(listChooseGallery, e) initializeVisioEvents() End Sub Private Sub listChooseGallery_Click(ByVal sender As Object, ByVal e As _ System.EventArgs) Handles listChooseGallery.Click 'When the user clicks one of the options provided in the listChooseGallery, 'the picture boxes in the gallery group box gets populated with the corresponding images. 'Retrieving path of the images on the hard disk that belongs to the selected image category. Dim ds As new DataSet Try Dim sqlcommand As New SqlCommand("select imagePath from ImageCategory where _ imageCategory='" & listChooseGallery.Text & "'", sqlConnection) Dim sqlda As New SqlDataAdapter(sqlcommand) sqlda.Fill(ds) Catch ex As Exception MsgBox("Unable to retrieve the path of the selected image category", MsgBoxStyle.OKOnly, "Retrieval Error") Exit Sub End Try If Not ds.Tables(0).Rows.Count = 0 Then 'Get all the image files for the selected image category Try files = Directory.GetFiles(ds.Tables(0).Rows(0).Item(0)) Catch ex As Exception MsgBox("Unable to retrieve images for the selected category", _ MsgBoxStyle.OKOnly, "Retrieval Error") End Try Else Exit Sub End If Dim filescount As Integer 'A bitmap object to hold the reference to the images stored in the music instruments folder Dim objImage As Bitmap 'A temporary picturebox object Dim tempPictureBox As New PictureBox 'A counter variable to iterate through the picture box controls stored in picture box list Dim cntPictureBox As Integer = 0 'Iterate through the files array Try For filescount = 0 To files.Length - 1 'This if block prevents the cached thumbnail image from being loaded into picture box If Not files(filescount).Substring(files(filescount).LastIndexOf("\") + 1).Equals("Thumbs.db") Then 'tempPictureBox holds the reference to the actual picturebox control in the pictureboxlist tempPictureBox = pictureboxlist(cntPictureBox) tempPictureBox.SizeMode = PictureBoxSizeMode.StretchImage 'Creating a new bitmap image objImage = New Bitmap(files(filescount)) tempPictureBox.Image = CType(objImage, Image) tempPictureBox.Text = files(filescount) cntPictureBox += 1 End If Next Catch ex As Exception MsgBox("Unable to load images", MsgBoxStyle.OKOnly, "Cannot load images") End Try End Sub Private Sub onPictureBoxDoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles PictureBox1.DoubleClick, PictureBox2.DoubleClick, PictureBox3.DoubleClick, _ PictureBox4.DoubleClick, PictureBox5.DoubleClick, PictureBox6.DoubleClick, _ PictureBox7.DoubleClick, PictureBox8.DoubleClick, PictureBox9.DoubleClick, _ PictureBox10.DoubleClick, PictureBox11.DoubleClick, PictureBox12.DoubleClick, _ PictureBox13.DoubleClick, PictureBox14.DoubleClick, PictureBox15.DoubleClick, _ PictureBox16.DoubleClick, PictureBox17.DoubleClick, PictureBox18.DoubleClick targetdocuments = drawingControl.Window.Application.Documents Dim ds As New DataSet 'Retrieving the path of the stencil corresponding to selected image category Try Dim sqlCommand As New SqlCommand("select stencilPath, stencilName from stencils where _ stencilId=(select stencilId from ImageCategory where imageCategory='" & _ listChooseGallery.Text & "')", sqlConnection) Dim sqlda As New SqlDataAdapter(sqlCommand) sqlda.Fill(ds) Catch ex As Exception MsgBox("unable to retrieve the path of the stencil corresponding to _ selected image category", MsgBoxStyle.OKOnly, "Retrieval Error") Exit Sub End Try 'Opening the stencil containing the images shown in the picture boxes. 'The stencil is opened in invisible mode If Not ds.Tables(0).Rows.Count = 0 Then targetStencil = targetdocuments.OpenEx(ds.Tables(0).Rows(0).Item(0) & "/" _ & ds.Tables(0).Rows(0).Item(1), VisOpenSaveArgs.visOpenHidden) Else Exit Sub End If 'Extracting the file name from the file path stored in the PictureBox text property Dim tempPictureBox As PictureBox = CType(sender, PictureBox) Dim extractFileName As String = tempPictureBox.Text extractFileName = extractFileName.Substring(extractFileName.LastIndexOf("\") + 1) 'Extracting the master shape from the musicinstruments.vss stencil Dim masters As Masters = targetStencil.Masters 'An object to hold a master shape from a Visio stencil Dim master As Master Try master = masters.Item(extractFileName) Catch ex As Exception MsgBox("Master shape not found", MsgBoxStyle.OKOnly, "Invalid Path") targetStencil.Close() Exit Sub End Try 'Dropping the master shape on the drawing control Try targetPage = drawingControl.Window.Page dropImage = targetPage.Drop(master, locationX, locationY) targetStencil.Close() Catch ex As Exception MsgBox("Unable to drop the image on drawing control", MsgBoxStyle.OKOnly, "Unable to drop image") End Try End Sub Private Sub menuFileNew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles menuFileNew.Click Dim visualFeedbackOn As Integer = 1 Dim visualFeedbackOff As Integer = 0 'A new visio drawing is opened Dim result As DialogResult Dim visioApplication As Microsoft.Office.Interop.Visio.Application 'Prompt the user to save changes in the current drawing before closing current drawing result = VisioMethods.SaveDrawing(drawingControl, True) If result <> DialogResult.Cancel Then visioApplication = drawingControl.Window.Application drawingControl.Src = "" Else Exit Sub End If 'Get the current state of the visual feedback. 'If visual feedback is on the end user will see changes in the drawing 'window as the code operates on the shapes. Dim visualFeedbackStatus As Integer = visioApplication.ScreenUpdating 'Don't let the user see the visual feedback while the shapes are deleted. If visualFeedbackStatus = visualFeedbackOn Then visioApplication.ScreenUpdating = visualFeedbackOff End If 'Delete all of the shapes from the Visio window. Dim targetWindow As Microsoft.Office.Interop.Visio.Window targetWindow = drawingControl.Window Dim targetPage As Microsoft.Office.Interop.Visio.Page targetPage = targetWindow.Page If targetPage.Shapes.Count > 0 Then targetWindow.SelectAll() targetWindow.Selection.Delete() End If 'Set the document saved flag since the drawing control is now displaying a blank document. drawingControl.Document.Saved = True 'Restore the screen updating status. If visualFeedbackStatus = visualFeedbackOn Then visioApplication.ScreenUpdating = visualFeedbackOn End If 'Re-initializing the totalImages count to zero totalImages = 0 Label1.Text = "" End Sub Private Sub menuFileOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles menuFileOpen.Click 'To open a drawing or a stencil Dim openFileDialog As New OpenFileDialog Dim targetDocuments As Documents Dim fileName As String Dim fileNameForCompare As String Dim shapeNumber As Integer Try 'Set up the open file dialog and let the user selects the file to open. openFileDialog.Title = "Open visio document" Dim currentDirectory As Directory Dim currentPath As String currentPath = currentDirectory.GetParent(currentDirectory.GetCurrentDirectory).ToString() openFileDialog.InitialDirectory = currentPath If openFileDialog.ShowDialog = DialogResult.OK Then 'The user has entered a file name and pressed OK. Get the file name 'from the dialog and open the file. fileName = openFileDialog.FileName fileNameForCompare = fileName.ToUpper(System.Globalization.CultureInfo.CurrentCulture) 'Checking if the user opens a stencil If fileNameForCompare.IndexOf(".VSS") > 0 Or fileNameForCompare.IndexOf(".VSX") > 0 Then targetDocuments = drawingControl.Window.Application.Documents() 'Open the stencil targetDocuments.Open(fileName) ElseIf fileNameForCompare.IndexOf(".VSD") > 0 Or _ fileNameForCompare.IndexOf(".VDX") > 0 Then Dim result As DialogResult 'Only one document can be open. Prompt user to save changes 'before closing the current document. result = VisioMethods.SaveDrawing(drawingControl, True) If result <> DialogResult.Cancel Then drawingControl.Src = "" 'Open the new document drawingControl.Src = fileName drawingControl.Document.Saved = True 'Set up the Visio drawing just opened setUpVisioDrawing() 'Initialize Visio events for the opened drawing initializeVisioEvents() 'Count the number of shapes in the opened drawing Dim targetPage As Page = drawingControl.Window.Page shapeNumber = targetPage.Shapes.Count 'Resetting the totalImages counter totalImages = 0 Dim countImages As Integer For countImages = 1 To shapeNumber onImageAdd() Next End If End If End If Catch ex As Exception MsgBox("Unable to open the Visio drawing", MsgBoxStyle.OKOnly, "Retrieval Error") End Try End Sub 'The setUpVisioDrawing method initializes the Visio drawing that is displayed in the drawing control. Public Sub setUpVisioDrawing() Dim pageLeft As Double Dim pageTop As Double Dim pageWidth As Double Dim pageHeight As Double Dim distanceBetweenShapes As Double Dim nextShapeXLocation As Double Dim shapeNumber As Integer Dim windowsCounter As Integer Try 'Hide all built-in docked windows such as shape search, custom properties, etc. For windowsCounter = drawingControl.Window.Windows.Count To windowsCounter > 0 Step -1 Dim visioWindow As Window Dim windowType As Integer visioWindow = drawingControl.Window.Windows.Item(windowsCounter) windowType = visioWindow.Type If windowType = VisWinTypes.visAnchorBarBuiltIn Then Select Case visioWindow.ID Case VisWinTypes.visWinIDCustProp Case VisWinTypes.visWinIDDrawingExplorer Case VisWinTypes.visWinIDMasterExplorer Case VisWinTypes.visWinIDPanZoom Case VisWinTypes.visWinIDShapeSearch Case VisWinTypes.visWinIDSizePos Case VisWinTypes.visWinIDStencilExplorer visioWindow.Visible = False End Select End If Next 'Use the Visio window to set the visible user interface parts of the window. Dim targetWindow As Window targetWindow = drawingControl.Window targetWindow.ShowRulers = 0 targetWindow.ShowPageTabs = False targetWindow.ShowScrollBars = 0 targetWindow.ShowGrid = 0 targetWindow.Zoom = 1.0 'Position the images relative to the page. targetWindow.GetViewRect(pageLeft, pageTop, pageWidth, pageHeight) 'Start the visio events initializeVisioEvents() 'The drawing control is displaying a newly opened document. Set the saved flag to true. drawingControl.Document.Saved = True Catch ex As Exception End Try End Sub 'initializeVisioEvents method initializes the VisioEvents event trapping on the document Public Sub initializeVisioEvents() Dim targetDocument As Document Dim targetApplication As Microsoft.Office.Interop.Visio.Application Try objVisioEvents = New VisioEvents targetApplication = drawingControl.Window.Application targetDocument = drawingControl.Document AddHandler objVisioEvents.OnImageAdd, AddressOf onImageAdd AddHandler objVisioEvents.OnImageDelete, AddressOf onImageDelete objVisioEvents.AddAdvise(targetApplication, targetDocument) Catch ex As Exception End Try End Sub Private Sub menuFileClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles menuFileClose.Click 'Since only one document can exist, this operation is identical to the Menu-> New command menuFileNew_Click(sender, e) End Sub Private Sub menuFilePrintPreview_Click(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles menuFilePrintPreview.Click 'The System.Drawing.Printing objects are used provide print preview of the visio drawing to the user Try 'Create a print document to handle the print preview functionality. Dim printDocument As New System.Drawing.Printing.PrintDocument Dim printPreviewDialog As New PrintPreviewDialog 'Add the local print page handler to print document AddHandler printDocument.PrintPage, AddressOf onPrintDocument printPreviewDialog.Document = printDocument printPreviewDialog.ShowDialog() Catch ex As Exception MsgBox("unable to preview the visio drawing", MsgBoxStyle.OKOnly, "Invalid print status") End Try End Sub 'The onPrintDocument method handles the event that is raised when the user hits Print in the print dialog. Private Sub onPrintDocument(ByVal sender As Object, ByVal e As _ System.Drawing.Printing.PrintPageEventArgs) Dim metafileOriginX As Integer Dim metafileOriginY As Integer Dim pageWidth As Double Dim pageHeight As Double Dim tempShape As Shape Dim targetPage As Page = drawingControl.Window.Page 'Draw a frame around the page so the bounding box of the picture is the size of the page. pageWidth = targetPage.PageSheet.CellsSRC(VisSectionIndices.visSectionObject, _ VisRowIndices.visRowPage, VisCellIndices.visPageWidth.visPageWidth).ResultIU pageHeight = targetPage.PageSheet.CellsSRC(VisSectionIndices.visSectionObject, _ VisRowIndices.visRowPage, VisCellIndices.visPageWidth.visPageHeight).ResultIU 'Creating the temporary shape which contains the visio page to be printed tempShape = targetPage.DrawRectangle(0, 0, pageWidth, pageHeight) tempShape.CellsSRC(VisSectionIndices.visSectionObject, VisRowIndices.visRowFill, _ VisCellIndices.visFillPattern).ResultIU = 0 'Make the line white so it's not visible on the page. tempShape.CellsSRC(VisSectionIndices.visSectionObject, VisRowIndices.visRowLine, _ VisCellIndices.visLineColor).ResultIU = 1 'Create a metafile with the image of the page. Try Dim printInptr As New System.IntPtr(targetPage.Picture.Handle) Dim printMetaFile As New System.Drawing.Imaging.Metafile(printInptr, False) 'Put the metafile image into the graphics of the print document. 'This causes the page image to be printed. e.Graphics.DrawImage(printMetaFile, metafileOriginX, metafileOriginY) Catch ex As Exception MsgBox("Unable to preview the visio drawing", MsgBoxStyle.OKOnly, "Print Error") End Try End Sub Private Sub frmCoverDesigner_Closing(ByVal sender As Object, ByVal e As _ System.ComponentModel.CancelEventArgs) Handles MyBase.Closing 'Before closing, prompt the user to save the document Dim result As DialogResult result = VisioMethods.SaveDrawing(drawingControl, True) If result = DialogResult.Cancel Then e.Cancel = True End If End Sub Private Sub menuFileSave_Click(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles menuFileSave.Click Dim result As DialogResult 'Prompt user to save changes. result = VisioMethods.SaveDrawing(drawingControl, False) End Sub Private Sub menuFileExit_Click(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles menuFileExit.Click Me.Close() End Sub 'This procedure is called when an image is added on the drawing control Private Sub onImageAdd() totalImages += 1 Label1.Text = "Number of images on the Visio drawing : " & totalImages End Sub 'This procedure is called when an image is deleted from the drawing control Private Sub onImageDelete() totalImages -= 1 If totalImages = 0 Then Label1.Text = "" Else Label1.Text = "Number of images on the Visio drawing : " & totalImages End If End Sub 'This method handles the event that is raised when the user clicks on the drawing control. 'If the user clicked the right mouse button on any image, the shortcut menu 'is displayed at the click location. Private Sub drawingControl_MouseUpEvent(ByVal sender As Object, ByVal e As _ AxMicrosoft.Office.Interop.VisOcx.EVisOcx_MouseUpEvent) Handles drawingControl.MouseUpEvent 'Check whether the event was raised because of a right mouse button click and not by zooming '(control+shift+right mouse click) or by selecting images (control+right mouse click). If e.button = VisKeyButtonFlags.visMouseRight And (e.keyButtonState And _ VisKeyButtonFlags.visKeyControl) = 0 Then 'Look for an image on the drawing page at the click location. clickedImage = VisioMethods.GetClickedImage(drawingControl, e.x, e.y) If Not clickedImage Is Nothing Then 'Cancel the default processing of this event since it will be handled in this method. e.cancelDefault = True 'Show the shortcut menu at the click location. 'The coordinates need to be converted from the Visio drawing units to Windows pixel coordinates. imageShortcutMenu.Show(drawingControl, VisioMethods.MapVisioToWindows(drawingControl, e.x, e.y)) shortcutMenu.PerformClick() End If ElseIf e.button = VisKeyButtonFlags.visMouseLeft Then 'To trap the coordinates to create the rectangle to allow the user to specify the text If Not rect.X = CInt(e.x) And Not CInt(e.y) = rect.Y Then Dim tp As Page = drawingControl.Window.Page tp.DrawRectangle(rect.X, rect.Y, e.x, e.y) End If End If End Sub Private Sub drawingControl_VisibleChanged(ByVal sender As Object, ByVal e As _ System.EventArgs) Handles drawingControl.VisibleChanged 'If the drawing control is not on the list of initialized drawing controls, 'the control needs to be initialized. If drawingControl.Visible And Not drawingControlList.Contains(drawingControl.Name) Then 'Set up the drawing, open the product stencil and start the visio events setUpVisioDrawing() End If 'Since all of the initialization tasks succeeded, save the drawing control 'in the list of initialized controls. drawingControlList.Add(drawingControl.Name) End Sub Private Sub shortcutMenu_Click(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles shortcutMenu.Click Try 'Finding the image category for the clicked image on the visio drawing Dim imageCategoryId As Integer Dim targetDocuments As Documents = drawingControl.Window.Application.Documents 'Looking for the clicked image in the available stencils in the current visio drawing Dim masters As Masters Dim targetDocument As Document Dim ds As New DataSet Try Dim sqlCommand As New SqlCommand("select * from stencils", sqlConnection) Dim sqlda As New SqlDataAdapter(sqlCommand) sqlda.Fill(ds) Catch ex As Exception Exit Sub End Try If Not ds.Tables(0).Rows.Count = 0 Then Dim i As Integer For i = 0 To ds.Tables(0).Rows.Count - 1 targetDocument = targetDocuments.OpenEx(ds.Tables(0).Rows(i).Item(2) & "/" _ & ds.Tables(0).Rows(i).Item(1), VisOpenSaveArgs.visOpenHidden) masters = targetDocument.Masters Try If Not masters.Item(clickedImage.Name) Is Nothing Then Dim imageds As New DataSet Dim sqlcmd As New SqlCommand("select imageCategoryId from ImageCategory where _ stencilId=" & ds.Tables(0).Rows(i).Item(0) & "", sqlConnection) Dim sqlda As New SqlDataAdapter(sqlcmd) sqlda.Fill(imageds) imageCategoryId = imageds.Tables(0).Rows(0).Item(0) targetDocument.Close() Exit For End If Catch ex As Exception targetDocument.Close() End Try Next End If 'Create a metafile of the clicked image. Dim imageInptr As New System.IntPtr(clickedImage.Picture.Handle) Dim imageMetaFile As New System.Drawing.Imaging.Metafile(imageInptr, False) 'Calling the ImageDetails form Dim objImageDetails As New ImageDetails(clickedImage.Name, imageCategoryId, imageMetaFile) objImageDetails.ShowDialog() Catch ex As Exception MsgBox("Unable to display the image details", MsgBoxStyle.OKOnly, clickedImage.Name) End Try End Sub Private Sub drawingControl_MouseDownEvent(ByVal sender As Object, ByVal e As _ AxMicrosoft.Office.Interop.VisOcx.EVisOcx_MouseDownEvent) _ Handles drawingControl.MouseDownEvent 'Trapping the coordinates on the visio control when user drags the 'mouse over the drawing control to make a rectangle to write some text rect.X = CInt(e.x) rect.Y = CInt(e.y) End Sub End Class
Download this Listing .
In the above listing, the frmCoverDesigner class loads the image categories in the listChooseGallery list box. When the end user selects an image category from the list box, the picture boxes in the frmCoverDesigner form get loaded with images, which correspond to the selected category. When the end user clicks any picture box, the frmCoverDesigner class opens the Visio stencil (*.VST) according to the selected image category and searches for the clicked image. To view information about the image on the Visio drawing control, the end user right-clicks the image. The code creates an instance of the ImageDetails class to show the image information in the Image Details window. When a new Visio drawing starts, the ImageDetails class registers the events with the VisioEvents class.
Figure 6-3 shows the output of the Listing 6-2:
The ImageDetails class defines the Image Details window. The ImageDetails class enables the end user to view the information about the selected image from the Visio drawing control.
Listing 6-3 shows the code for the frmImageDetails.vb that defines the ImageDetails class:
Imports System.Data.SqlClient Imports System.IO 'The ImageDetails class displays the details of an 'image retrieved by the Web service ImageInfoService onto a form. Public Class ImageDetails Inherits System.Windows.Forms.Form Dim imageFileName As String Dim imageCategoryId As Integer Dim imageMetafile As System.Drawing.Imaging.Metafile Dim sqlConnection As New sqlConnection Public Sub New(ByVal imageName As String, ByVal imageCatId As Integer, _ ByVal metafile As System.Drawing.Imaging.Metafile) MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call imageFileName = imageName imageCategoryId = imageCatId imageMetafile = metafile 'Constructor requires the name of the image, image category, and metafile image as input 'This information is utilized by the ImageDetails to retrieve details of the specified image. End Sub Private Sub ImageDetails_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Retrieving details for the specified image from the ImageInfoService Web service Dim infoProvider As New localhost.ImageInfoService Dim ds As DataSet = infoProvider.getImageInfo(imageCategoryId, imageFileName) If Not ds Is Nothing And Not ds.Tables.Count = 0 And Not ds.Tables(0).Rows.Count = 0 Then lblId.Text = lblId.Text & " " & ds.Tables(0).Rows(0).Item(0) 'Establish a connection with the CoverDesigner database to retrieve the Image Category Try Try 'Read connectionstring from a text file, settings.txt, located in '/bin folder of the application Dim sr As New StreamReader("Settings.txt") sqlConnection.ConnectionString = sr.ReadLine sr.Close() Catch ex As Exception 'If file settings.txt not found sqlConnection.ConnectionString = _ "SERVER=localhost;UID=sa;PWD=sa;Initial Catalog=CoverDesigner" End Try sqlConnection.Open() Catch ex As Exception MsgBox("Error in establishing connection", MsgBoxStyle.OKOnly, "CONNECTION ERROR") Exit Sub End Try Dim sqlCommand As New SqlCommand("select imageCategory from ImageCategory where _ imageCategoryId=" & imageCategoryId & "", sqlConnection) Dim sqlda As New SqlDataAdapter(sqlCommand) Dim imageds As New DataSet sqlda.Fill(imageds) lblCategory.Text = lblCategory.Text & " " & imageds.Tables(0).Rows(0).Item(0) lblName.Text = lblName.Text & " " & ds.Tables(0).Rows(0).Item(2) lblDescription.Text = lblDescription.Text & " " & ds.Tables(0).Rows(0).Item(3) lblSource.Text = lblSource.Text & " " & ds.Tables(0).Rows(0).Item(4) 'Save the metafile in the picture box control that shows the clicked image 'Maintain metafile aspect and scale the metafile to fit in the Picture Box. Dim metafileImage As System.Drawing.Image Dim pictureBoxRect As System.Drawing.Rectangle Dim metafileWidth As Double Dim metafileHeight As Double Dim horizontalScale As Double Dim verticalScale As Double Dim pictureWidth As Integer Dim pictureHeight As Integer PictureBox1.RectangleToClient(pictureBoxRect) metafileWidth = imageMetafile.Width metafileHeight = imageMetafile.Height If metafileHeight > 0 And metafileWidth > 0 Then verticalScale = pictureBoxRect.Height / metafileHeight horizontalScale = pictureBoxRect.Width / metafileWidth If verticalScale < horizontalScale Then pictureWidth = CInt(metafileWidth * verticalScale) pictureHeight = CInt(metafileHeight * verticalScale) Else pictureWidth = CInt(metafileWidth * horizontalScale) pictureHeight = CInt(metafileHeight * horizontalScale) End If metafileImage = imageMetafile.GetThumbnailImage(pictureWidth, pictureHeight, Nothing, IntPtr.Zero) PictureBox1.Image = metafileImage End If End If End Sub End Class
Download this Listing .
In the above listing, the ImageDetails class accepts the image id, image category, and the meta file that represents the selected image, in the constructor of the ImageDetails class. Then, the ImageDetails class calls the getImageInfo function provided by the ImageInfoService Web service to display the image information on the frmImageDetails form.
Figure 6-4 shows the output of Listing 6-3:
The VisioEvents.vb file defines the VisioEvents class that handles events from the Visio drawing tool. The VisioEvents class provides methods that trap the generated events when the end user designs the cover using the Visio drawing control.
Listing 6-4 shows the code for the VisioEvents.vb that defines the VisioEvents class:
Imports System.Diagnostics Imports Microsoft.Office.Interop.Visio Public Class VisioEvents Implements Microsoft.Office.Interop.Visio.IVisEventProc 'VisioEventHandler is an event delegate used for raising events for the 'Visio objects in the frmCoverDesigner class Public Delegate Sub VisioEventHandler() 'A Visio application object Dim visioApplication As Microsoft.Office.Interop.Visio.Application 'A Visio document object Dim visioDocument As Document 'OnImageAdd event is raised when an image is added to the Visio drawing Public Event OnImageAdd As VisioEventHandler 'OnImageDelete event is raised when an image is deleted from the Visio drawing Public Event OnImageDelete As VisioEventHandler 'OnImageDoubleClick event is raised when the user double clicks an image from the Visio drawing Public Event OnImageDoubleClick As VisioEventHandler 'AddAdvise method adds an Event object to the EventList collection of the 'source object whose events you want to receive. When selected events occur, 'the source object will notify your event handler. Public Function AddAdvise(ByVal sourceApplication As _ Microsoft.Office.Interop.Visio.Application, ByVal sourceDocument As Document) visioApplication = sourceApplication visioDocument = sourceDocument 'Add the events that need to be responded to the behavior of the Visio objects. Dim newEvent As [Event] Dim applicationEvents As EventList = visioApplication.EventList Dim documentEvents As EventList = visioDocument.EventList 'Add the image-added event to the document. The new image will be available for processing in the handler. Dim addimageEventCode As Short = -32704 newEvent = documentEvents.AddAdvise(addimageEventCode, Me, "", "") 'Add the image-deleted event to the document. This event executes 'when an image is deleted from the document. 'The deleted image will still be available for processing in the handler. Dim deleteimageEventCode As Short = VisEventCodes.visEvtShape + VisEventCodes.visEvtDel newEvent = documentEvents.AddAdvise(deleteimageEventCode, Me, "", "") 'Add marker events to the application. This event executes 'when a user double clicks an image from the visio drawing. Dim doubleclickEventCode As Short = VisEventCodes.visEvtApp + VisEventCodes.visEvtMarker newEvent = documentEvents.AddAdvise(doubleclickEventCode, Me, "", "") End Function 'The IVisEventProc.VisEventProc function is called by Visio 'when an event which has been added to an events list collection has been raised. Public Function VisEventProc(ByVal nEventCode As Short, ByVal pSourceObj As Object, _ ByVal nEventID As Integer, ByVal nEventSeqNum As Integer, ByVal pSubjectObj _ As Object, ByVal vMoreInfo As Object) As Object _ Implements Microsoft.Office.Interop.Visio.IVisEventProc.VisEventProc Dim Image As Shape If TypeOf pSourceObj Is Microsoft.Office.Interop.Visio.Application Then visioApplication = pSourceObj ElseIf TypeOf pSourceObj Is Document Then visioDocument = pSourceObj End If 'Check for each event code that is handled. The event codes are a 'combination of an object and an action. 'As VisEventCodes.visEvtAdd cannot be converted to short value, 'the value for event code for adding image is taken as -32704 which is a short value Dim addimageEventCode As Short = -32704 Dim deleteimageEventcode As Short = VisEventCodes.visEvtShape + VisEventCodes.visEvtDel Dim doubleclickimageEventCode As Short = VisEventCodes.visEvtApp + _ VisEventCodes.visEvtMarker If nEventCode = addimageEventCode Then 'Handle the add image event Image = CType(pSubjectObj, Shape) handleImageAdd(Image) ElseIf nEventCode = deleteimageEventcode Then 'Handle the delete image event Image = CType(pSubjectObj, Shape) handleImageDelete(Image) ElseIf nEventCode = doubleclickimageEventCode Then 'Handle the double-click event End If End Function 'This procedure is called when an image is added on the Visio drawing Public Sub handleImageAdd(ByVal addedImage As Shape) 'Ignore the image add event that occurs when the user groups existing images in the Visio drawing. 'This is done to prevent an OnImageAdd event from being raised that 'would cause the existing images to be counted more than once. If Not visioApplication.IsInScope(Microsoft.Office.Interop.Visio.VisUICmds.visCmdObjectGroup) Then RaiseEvent OnImageAdd() End If End Sub 'This procedure is called when an image is deleted from the visio drawing Public Sub handleImageDelete(ByVal deletedImage As Shape) RaiseEvent OnImageDelete() End Sub End Class
Download this Listing .
In the above listing, the VisioEvents class implements the Microsoft.Office.Interop.Visio.IvisEventProc interface to trap the events. The VisioEvents class traps the events when the end user adds an image on the Visio drawing, deletes an image from the Visio drawing, and double-clicks an image on the Visio drawing. The VisioEvents class provides the AddAdvise method that adds an Event object to the EventList collection of the Visio drawing control. When a particular event occurs, the drawing control specifies the corresponding event handler.
The VisioMethods.vb file defines the VisioMethods class that defines methods to execute operations commonly performed on Visio objects.
Listing 6-5 shows the code for the VisioMethods.vb that defines the VisioMethods class:
Imports Microsoft.Office.Interop.Visio Imports System.IO Public Class VisioMethods 'The MapVisioToWindows function converts Visio coordinates to Windows coordinates Public Shared Function MapVisioToWindows(ByVal drawingControl As _ AxMicrosoft.Office.Interop.VisOcx.AxDrawingControl, ByVal visioX As Double, _ ByVal visioY As Double) As System.Drawing.Point If drawingControl Is Nothing Then MsgBox("Invalid control", MsgBoxStyle.OKOnly, "Null Reference") Exit Function End If Dim windowsX As Integer Dim windowsY As Integer Dim visioLeft As Double Dim visioTop As Double Dim visioWidth As Double Dim visioHeight As Double Dim pixelLeft As Integer Dim pixeltop As Integer Dim pixelWidth As Integer Dim pixelHeight As Integer Dim referenceWindow As Window = drawingControl.Window 'Get the window coordinates in Visio units referenceWindow.GetViewRect(visioLeft, visioTop, visioWidth, visioHeight) 'Get the window coordinates in pixels referenceWindow.GetWindowRect(pixelLeft, pixeltop, pixelWidth, pixelHeight) 'Convert the X-coordinate by using pixels per inch from the width values windowsX = pixelLeft + ((pixelWidth / visioWidth) * (visioX - visioLeft)) 'Convert the Y-coordinate by using pixels per inch from the height values and transform from 'a top-left origin (Windows coordinates) to a bottom-left origin (Visio coordinates). windowsY = pixeltop + ((pixelHeight / visioHeight) * (visioTop - visioY)) Return New System.Drawing.Point(windowsX, windowsY) End Function 'The getClickedImage method finds an image at the specified location 'If there are more than one image at the location the top image in Z order is returned Public Shared Function GetClickedImage(ByVal drawingControl As _ AxMicrosoft.Office.Interop.VisOcx.AxDrawingControl, ByVal VisioX As Double, _ ByVal VisioY As Double) As Shape If drawingControl Is Nothing Then MsgBox("Invalid control", MsgBoxStyle.OKOnly, "Null Reference") Exit Function End If 'A shape object Dim shape As Shape Dim currentPage As Page = drawingControl.Window.Page 'Use the spatial search method to return a list of images at the clicked location. Dim foundImages As Selection = currentPage.SpatialSearch(VisioX, VisioY, _ CShort(VisSpatialRelationCodes.visSpatialContainedIn), 0.0001, _ CShort(VisSpatialRelationFlags.visSpatialBackToFront)) 'If there is more than one image on the selected location return the top most images If foundImages.Count > 0 Then shape = foundImages(foundImages.Count) End If Return shape End Function 'The SaveDrawing method to save changes to the Visio document. 'The user is prompted before saving the visio drawing. 'This method returns the id of the message box that has closed the dialog result Public Shared Function SaveDrawing(ByVal drawingControl As _ AxMicrosoft.Office.Interop.VisOcx.AxDrawingControl, _ ByVal promptFirst As Boolean) As DialogResult Dim saveFileDialog As SaveFileDialog Dim result As DialogResult Dim targetFilename As String Dim targetDocument As Document Try targetFilename = drawingControl.Src 'Extracting the file name instead of the full path of the file targetFilename = targetFilename.Substring(targetFilename.LastIndexOf("\") + 1) targetDocument = drawingControl.Document 'If prompting first is true If promptFirst = True Then Dim promptMessage As String Dim title As String = "Save As" 'saving changes to existing drawing If targetFilename.Length > 0 Then promptMessage = "Save changes to : " & targetFilename & " ?" Else 'saving changes as new drawing promptMessage = "Save changes to current document ?" End If result = MsgBox(promptMessage, MsgBoxStyle.YesNoCancel, "Save Changes") Else result = DialogResult.Yes End If 'Display a file browse dialog box to select path and filename. If result = DialogResult.Yes And targetFilename.Length = 0 Then 'Set up the save file dialog and let the user specify the name to save the drawing. saveFileDialog = New SaveFileDialog saveFileDialog.Title = "Save As" Dim currentDirectory As Directory Dim currentPath As String currentPath = currentDirectory.GetParent(currentDirectory.GetCurrentDirectory).ToString saveFileDialog.InitialDirectory = currentPath If saveFileDialog.ShowDialog() = DialogResult.OK Then targetFilename = saveFileDialog.FileName End If End If 'Save the Visio drawing to the filename specified by the end user in 'the save file dialog, or the existing file name. If result = DialogResult.Yes And targetFilename.Length > 0 Then targetDocument.SaveAs(targetFilename) drawingControl.Src = targetFilename drawingControl.Document.Saved = True End If Catch ex As Exception End Try Return result End Function End Class
Download this Listing .
In the above listing, the MapVisioToWindows method provides the functionality to map the Visio co ordinates to Window co ordinates. The SaveDrawing method provides the functionality to save the Visio drawing and the GetClickedImage method retrieves the image selected by the end user in the drawing control.