vsintegration/src/FSharp.ProjectSystem.PropertyPages/Common/ShellUtil.vb (371 lines of code) (raw):

' Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. Imports EnvDTE Imports VB = Microsoft.VisualBasic Imports Microsoft.VisualStudio.Shell.Interop Imports System Imports System.Collections.Generic Imports System.Diagnostics Imports System.Drawing Imports System.IO Imports System.Windows.Forms Imports System.Windows.Forms.Design Namespace Microsoft.VisualStudio.Editors.Common ''' <summary> ''' Utilities relating to the Visual Studio shell, services, etc. ''' </summary> ''' <remarks></remarks> Friend NotInheritable Class ShellUtil ''' <summary> ''' Gets a color from the shell's color service. If for some reason this fails, returns the supplied ''' default color. ''' </summary> ''' <param name="VsUIShell">The IVsUIShell interface that must also implement IVsUIShell2 (if not, or if Nothing, default color is returned)</param> ''' <param name="VsSysColorIndex">The color index to look up.</param> ''' <param name="DefaultColor">The default color to return if the call fails.</param> ''' <returns></returns> ''' <remarks></remarks> Public Shared Function GetColor(ByVal VsUIShell As IVsUIShell, ByVal VsSysColorIndex As __VSSYSCOLOREX, ByVal DefaultColor As Color) As Color Return GetColor(TryCast(VsUIShell, IVsUIShell2), VsSysColorIndex, DefaultColor) End Function ''' <summary> ''' Gets a color from the shell's color service. If for some reason this fails, returns the supplied ''' default color. ''' </summary> ''' <param name="VsUIShell2">The IVsUIShell2 interface to use (if Nothing, default color is returned)</param> ''' <param name="VsSysColorIndex">The color index to look up.</param> ''' <param name="DefaultColor">The default color to return if the call fails.</param> ''' <returns></returns> ''' <remarks></remarks> Public Shared Function GetColor(ByVal VsUIShell2 As IVsUIShell2, ByVal VsSysColorIndex As __VSSYSCOLOREX, ByVal DefaultColor As Color) As Color If VsUIShell2 IsNot Nothing Then Dim abgrValue As System.UInt32 Dim Hr As Integer = VsUIShell2.GetVSSysColorEx(VsSysColorIndex, abgrValue) If VSErrorHandler.Succeeded(Hr) Then Return COLORREFToColor(abgrValue) End If End If Debug.Fail("Unable to get color from the shell, using a predetermined default color instead." & VB.vbCrLf & "Color Index = " & VsSysColorIndex & ", Default Color = &h" & VB.Hex(DefaultColor.ToArgb)) Return DefaultColor End Function ''' <summary> ''' Converts a COLORREF value (as UInteger) to System.Drawing.Color ''' </summary> ''' <param name="abgrValue">The UInteger COLORREF value</param> ''' <returns>The System.Drawing.Color equivalent.</returns> ''' <remarks></remarks> Private Shared Function COLORREFToColor(ByVal abgrValue As System.UInt32) As Color Return Color.FromArgb(CInt(abgrValue And &HFFUI), CInt((abgrValue And &HFF00UI) >> 8), CInt((abgrValue And &HFF0000UI) >> 16)) End Function ''' <summary> ''' Retrieves the window that should be used as the owner of all dialogs and messageboxes. ''' </summary> ''' <returns></returns> ''' <remarks></remarks> Friend Shared Function GetDialogOwnerWindow(ByVal serviceProvider As IServiceProvider) As IWin32Window Dim dialogOwner As IWin32Window = Nothing Dim UIService As IUIService = DirectCast(serviceProvider.GetService(GetType(IUIService)), IUIService) If UIService IsNot Nothing Then dialogOwner = UIService.GetDialogOwnerWindow() End If Debug.Assert(dialogOwner IsNot Nothing, "Couldn't get DialogOwnerWindow") Return dialogOwner End Function ''' <summary> ''' Given an IVsCfg, get its configuration and platform names. ''' </summary> ''' <param name="Config">The IVsCfg to get the configuration and platform name from.</param> ''' <param name="ConfigName">[out] The configuration name.</param> ''' <param name="PlatformName">[out] The platform name.</param> ''' <remarks></remarks> Public Shared Sub GetConfigAndPlatformFromIVsCfg(ByVal Config As IVsCfg, ByRef ConfigName As String, ByRef PlatformName As String) Dim DisplayName As String = Nothing VSErrorHandler.ThrowOnFailure(Config.get_DisplayName(DisplayName)) Debug.Assert(DisplayName IsNot Nothing AndAlso DisplayName <> "") 'The configuration name and platform name are separated by a vertical bar. The configuration ' part is the only portion that is user-defined. Although the shell doesn't allow vertical bar ' in the configuration name, let's not take chances, so we'll find the last vertical bar in the ' string. Dim IndexOfBar As Integer = DisplayName.LastIndexOf("|"c) If IndexOfBar = 0 Then 'It is possible that some old projects' configurations may not have the platform in the name. ' In this case, the correct thing to do is assume the platform is "Any CPU" ConfigName = DisplayName PlatformName = "Any CPU" Else ConfigName = DisplayName.Substring(0, IndexOfBar) PlatformName = DisplayName.Substring(IndexOfBar + 1) End If Debug.Assert(ConfigName <> "" AndAlso PlatformName <> "") End Sub ''' <summary> ''' Returns whether or not we're in simplified config mode for this project, which means that ''' we hide the configuration/platform comboboxes. ''' </summary> ''' <param name="ProjectHierarchy">The hierarchy to check</param> ''' <remarks></remarks> Public Shared Function GetIsSimplifiedConfigMode(ByVal ProjectHierarchy As IVsHierarchy) As Boolean Try If ProjectHierarchy IsNot Nothing Then Dim Project As Project = DTEProjectFromHierarchy(ProjectHierarchy) If Project IsNot Nothing Then Return CanHideConfigurationsForProject(ProjectHierarchy) AndAlso Not ToolsOptionsShowAdvancedBuildConfigurations(Project.DTE) End If End If Catch ex As Exception Common.RethrowIfUnrecoverable(ex) Debug.Fail("Exception determining if we're in simplified configuration mode - default to advanced configs mode") End Try Return False 'Default to advanced configs End Function ''' <summary> ''' Returns whether it's permissible to hide configurations for this project. This should normally ''' be returned as true until the user changes any of the default configurations (i.e., adds, deletes ''' or removes a configuration, at which point the project wants to show the advanced settings ''' from then on out). ''' </summary> ''' <param name="ProjectHierarchy">The project hierarchy to check</param> ''' <remarks></remarks> Private Shared Function CanHideConfigurationsForProject(ByVal ProjectHierarchy As IVsHierarchy) As Boolean Dim ReturnValue As Boolean = False 'If failed to get config value, default to not hiding configs Dim ConfigProviderObject As Object = Nothing Dim ConfigProvider As IVsCfgProvider2 = Nothing If VSErrorHandler.Succeeded(ProjectHierarchy.GetProperty(VSITEMID.ROOT, __VSHPROPID.VSHPROPID_ConfigurationProvider, ConfigProviderObject)) Then ConfigProvider = TryCast(ConfigProviderObject, IVsCfgProvider2) End If If ConfigProvider IsNot Nothing Then Dim ValueObject As Object = Nothing 'Ask the project system if configs can be hidden Dim hr As Integer = ConfigProvider.GetCfgProviderProperty(__VSCFGPROPID2.VSCFGPROPID_HideConfigurations, ValueObject) If VSErrorHandler.Succeeded(hr) AndAlso TypeOf ValueObject Is Boolean Then ReturnValue = CBool(ValueObject) Else Debug.Fail("Failed to get VSCFGPROPID_HideConfigurations from project config provider") ReturnValue = False End If End If Return ReturnValue End Function ''' <summary> ''' Retrieves the current value of the "Show Advanced Build Configurations" options in ''' Tools.Options. ''' </summary> ''' <param name="DTE">The DTE extensibility object</param> ''' <remarks></remarks> Private Shared Function ToolsOptionsShowAdvancedBuildConfigurations(ByVal DTE As DTE) As Boolean 'Now check for if the Tools option setting to show Advanced Config Settings is on Dim ShowAdvancedBuildIntValue As Integer = -1 Dim ShowValue As Boolean Dim ProjAndSolutionProperties As EnvDTE.Properties Const EnvironmentCategory As String = "Environment" Const ProjectsAndSolution As String = "ProjectsandSolution" Try ProjAndSolutionProperties = DTE.Properties(EnvironmentCategory, ProjectsAndSolution) If ProjAndSolutionProperties IsNot Nothing Then ShowValue = CBool(ProjAndSolutionProperties.Item("ShowAdvancedBuildConfigurations").Value) Else Debug.Fail("Couldn't get ProjAndSolutionProperties property from DTE.Properties") ShowValue = True 'If can't get to the property, assume advanced mode End If Catch ex As Exception Common.RethrowIfUnrecoverable(ex) Debug.Fail("Couldn't get ShowAdvancedBuildConfigurations property from tools.options") Return True 'default to showing advanced End Try Return ShowValue End Function ''' <summary> ''' Given an IVsHierarchy, fetch the DTE Project for it, if it exists. For project types that ''' don't support this, returns Nothing (e.g. C++). ''' </summary> ''' <param name="ProjectHierarchy"></param> ''' <returns></returns> ''' <remarks></remarks> Public Shared Function DTEProjectFromHierarchy(ByVal ProjectHierarchy As IVsHierarchy) As Project If ProjectHierarchy Is Nothing Then Return Nothing End If Dim hr As Integer Dim Obj As Object = Nothing hr = ProjectHierarchy.GetProperty(VSITEMID.ROOT, __VSHPROPID.VSHPROPID_ExtObject, Obj) If VSErrorHandler.Succeeded(hr) Then Return TryCast(Obj, EnvDTE.Project) End If Return Nothing End Function ''' <summary> ''' Given a DTE Project, get the hierarchy corresponding to it. ''' </summary> ''' <param name="sp"></param> ''' <param name="project"></param> ''' <returns></returns> ''' <remarks></remarks> Public Shared Function VsHierarchyFromDTEProject(ByVal sp As IServiceProvider, ByVal project As Project) As IVsHierarchy Debug.Assert(sp IsNot Nothing) If sp Is Nothing OrElse project Is Nothing Then Return Nothing End If Dim vssolution As IVsSolution = TryCast(sp.GetService(GetType(IVsSolution)), IVsSolution) If vssolution IsNot Nothing Then Dim hierarchy As IVsHierarchy = Nothing If VSErrorHandler.Succeeded(vssolution.GetProjectOfUniqueName(project.UniqueName, hierarchy)) Then Return hierarchy Else Debug.Fail("Why didn't we get the hierarchy from the project?") End If End If Return Nothing End Function ''' <summary> ''' Returns the IVsCfgProvider2 for the given project hierarchy ''' </summary> ''' <param name="ProjectHierarchy"></param> ''' <returns></returns> ''' <remarks></remarks> Public Shared Function GetConfigProvider(ByVal ProjectHierarchy As IVsHierarchy) As IVsCfgProvider2 'CONSIDER: This will not work for all project types because they do not support this property. Dim ConfigProvider As Object = Nothing If VSErrorHandler.Failed(ProjectHierarchy.GetProperty(VSITEMID.ROOT, __VSHPROPID.VSHPROPID_ConfigurationProvider, ConfigProvider)) Then Return Nothing End If Return TryCast(ConfigProvider, IVsCfgProvider2) End Function ''' <summary> ''' Given a hierarhy, determine if this is a devices project... ''' </summary> ''' <param name="hierarchy"></param> ''' <returns></returns> ''' <remarks></remarks> Public Shared Function IsDeviceProject(ByVal hierarchy As IVsHierarchy) As Boolean If hierarchy Is Nothing Then Debug.Fail("I can't determine if this is a devices project from a NULL hierarchy!?") Return False End If Dim vsdProperty As Object = Nothing Dim hr As Integer = hierarchy.GetProperty(VSITEMID.ROOT, 8000, vsdProperty) If Interop.NativeMethods.Succeeded(hr) AndAlso vsdProperty IsNot Nothing AndAlso TryCast(vsdProperty, IVSDProjectProperties) IsNot Nothing Then Return True End If Return False End Function ''' <summary> ''' Is this a web (Venus WSP or WAP project) ''' </summary> ''' <param name="hierarchy"></param> ''' <returns></returns> ''' <remarks></remarks> Friend Shared Function IsWebProject(ByVal hierarchy As IVsHierarchy) As [Boolean] Const WebAppProjectGuid As String = "{349c5851-65df-11da-9384-00065b846f21}" If hierarchy Is Nothing Then Return False End If Try ' VS WAP Projects are traditional vb/c# apps, but 'flavored' to add functionality ' for ASP.Net. This flavoring is marked by adding a guid to the AggregateProjectType guids ' Get the project type guid list Dim guidList As New System.Collections.Generic.List(Of Guid) Dim WAPGuid As New Guid(WebAppProjectGuid) Dim aggregatableProject As IVsAggregatableProject = TryCast(hierarchy, IVsAggregatableProject) If aggregatableProject IsNot Nothing Then Dim guidStrings As String = Nothing ' The project guids string looks like "{Guid 1};{Guid 2};...{Guid n}" with Guid n the inner most aggregatableProject.GetAggregateProjectTypeGuids(guidStrings) For Each guidString As String In guidStrings.Split(New Char() {";"c}) If guidString <> "" Then ' Insert Guid to the front Try Dim flavorGuid As New Guid(guidString) If WAPGuid.Equals(flavorGuid) Then Return True End If Catch ex As Exception System.Diagnostics.Debug.Fail(String.Format("We received a broken guid string from IVsAggregatableProject: '{0}'", guidStrings)) End Try End If Next Else ' Should not happen, but if they decide to make this project type non-flavored. Dim typeGuid As Guid = Nothing VSErrorHandler.ThrowOnFailure(hierarchy.GetGuidProperty(VSITEMID.ROOT, __VSHPROPID.VSHPROPID_TypeGuid, typeGuid)) If Guid.Equals(WAPGuid, typeGuid) Then Return True End If End If Catch ex As Exception ' We failed. Assume that this isn't a web project... End Try Return False End Function ''' <summary> ''' ''' </summary> ''' <param name="fileName">IN: name of the file to get the document info from</param> ''' <param name="rdt">IN: Running document table to find the info in</param> ''' <param name="hierarchy">OUT: Hierarchy that the document was found in</param> ''' <param name="itemid">OUT: Found itemId</param> ''' <param name="readLocks">OUT: Number of read locks for the document</param> ''' <param name="editLocks">OUT: Number of edit locks on the document</param> ''' <param name="docCookie">OUT: A cookie for the doc, 0 if the doc isn't found in the RDT</param> ''' <remarks></remarks> Friend Shared Sub GetDocumentInfo(ByVal fileName As String, ByVal rdt As IVsRunningDocumentTable, ByRef hierarchy As IVsHierarchy, ByRef readLocks As UInteger, ByRef editLocks As UInteger, ByRef itemid As UInteger, ByRef docCookie As UInteger) If fileName Is Nothing Then Throw New ArgumentNullException("fileName") If rdt Is Nothing Then Throw New ArgumentNullException("rdt") ' ' Initialize out parameters... ' readLocks = 0 editLocks = 0 itemid = VSITEMID.NIL docCookie = 0 hierarchy = Nothing ' Now, look in the RDT to see if this doc data already has an edit lock on it. ' if it does, we keep it and we begin tracking changes. Otherwise, we ' let it get disposed. ' Dim flags As UInteger Dim localPunk As IntPtr = IntPtr.Zero Dim localFileName As String = Nothing Try VSErrorHandler.ThrowOnFailure(rdt.FindAndLockDocument(CType(_VSRDTFLAGS.RDT_NoLock, UInteger), fileName, hierarchy, itemid, localPunk, docCookie)) Finally If (localPunk <> IntPtr.Zero) Then System.Runtime.InteropServices.Marshal.Release(localPunk) localPunk = IntPtr.Zero End If End Try Try VSErrorHandler.ThrowOnFailure(rdt.GetDocumentInfo(docCookie, flags, readLocks, editLocks, localFileName, hierarchy, itemid, localPunk)) Finally If (localPunk <> IntPtr.Zero) Then System.Runtime.InteropServices.Marshal.Release(localPunk) localPunk = IntPtr.Zero End If End Try End Sub ''' <summary> ''' Get the name of a project item as well as a SFG generated child item (if any) ''' Used in order to check out all dependent files for a project item ''' </summary> ''' <param name="projectitem">The parent project item that is to be checked out</param> ''' <param name="suffix">Suffix added by the single file generator</param> ''' <param name="requireExactlyOneChild"> ''' Only add the child item to the list of items to check out if there is exactly one child ''' project item. ''' </param> ''' <param name="exclude"> ''' Predicate used to filter items that we don't want to check out. ''' The predicate is passed each full path to the project item, and if it returns ''' true, the item will not be added to the list of items to check out. ''' </param> ''' <returns> ''' The list of items that are to be checked out ''' </returns> ''' <remarks></remarks> Friend Shared Function FileNameAndGeneratedFileName(ByVal projectitem As EnvDTE.ProjectItem, _ Optional ByVal suffix As String = ".Designer", _ Optional ByVal requireExactlyOneChild As Boolean = True, _ Optional ByVal exclude As Predicate(Of String) = Nothing) _ As Collections.Generic.List(Of String) Dim result As New List(Of String) If projectitem IsNot Nothing AndAlso projectitem.Name <> "" Then result.Add(DTEUtils.FileNameFromProjectItem(projectitem)) End If ' For each child, check if the name matches the filename for the generated file If projectitem IsNot Nothing AndAlso projectitem.ProjectItems IsNot Nothing Then ' If we require exactly one child, we better check the number of children ' and bail if more than one child. If projectitem.ProjectItems.Count = 1 OrElse Not requireExactlyOneChild Then For childNo As Integer = 1 To projectitem.ProjectItems.Count Try Dim childItemName As String = DTEUtils.FileNameFromProjectItem(projectitem.ProjectItems.Item(childNo)) ' Make sure that the filename matches what we expect. If String.Equals( _ System.IO.Path.GetFileNameWithoutExtension(childItemName), _ System.IO.Path.GetFileNameWithoutExtension(DTEUtils.FileNameFromProjectItem(projectitem)) & suffix, _ StringComparison.OrdinalIgnoreCase) _ Then ' If we've got a filter predicate, we remove anything that we've been ' told we shouldn't check out... Dim isExcluded As Boolean = exclude IsNot Nothing AndAlso exclude.Invoke(childItemName) If Not isExcluded Then result.Add(childItemName) End If End If Catch ex As ArgumentException ' If the child name wasn't a file moniker, then we may throw an argument exception here... ' ' Don't really care about that scenario! End Try Next End If End If Return result End Function '''<summary> ''' a fake IVSDProjectProperties definition. We only use this to check whether the project supports this interface, but don't pay attention to the detail. '''</summary> <System.Runtime.InteropServices.ComImport(), System.Runtime.InteropServices.ComVisible(True), System.Runtime.InteropServices.Guid("1A27878B-EE15-41CE-B427-58B10390C821"), System.Runtime.InteropServices.InterfaceType(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsDual)> _ Private Interface IVSDProjectProperties End Interface ''' <summary> ''' Wrapper class for IVsShell.OnBroadcastMessage ''' </summary> ''' <remarks></remarks> Friend Class BroadcastMessageEventsHelper Implements IVsBroadcastMessageEvents Implements IDisposable Public Event BroadcastMessage(ByVal msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) 'Cookie for use with IVsShell.{Advise,Unadvise}BroadcastMessages Private m_CookieBroadcastMessages As UInteger Private m_ServiceProvider As IServiceProvider Friend Sub New(ByVal sp As IServiceProvider) m_ServiceProvider = sp ConnectBroadcastEvents() End Sub #Region "Helper methods to advise/unadvise broadcast messages from the IVsShell service" Friend Sub ConnectBroadcastEvents() Dim VSShell As IVsShell = Nothing If m_ServiceProvider IsNot Nothing Then VSShell = DirectCast(m_ServiceProvider.GetService(GetType(IVsShell)), IVsShell) End If If VSShell IsNot Nothing Then VSErrorHandler.ThrowOnFailure(VSShell.AdviseBroadcastMessages(Me, m_CookieBroadcastMessages)) Else Debug.Fail("Unable to get IVsShell for broadcast messages") End If End Sub Private Sub DisconnectBroadcastMessages() If m_CookieBroadcastMessages <> 0 Then Dim VsShell As IVsShell = DirectCast(m_ServiceProvider.GetService(GetType(IVsShell)), IVsShell) If VsShell IsNot Nothing Then VSErrorHandler.ThrowOnFailure(VsShell.UnadviseBroadcastMessages(m_CookieBroadcastMessages)) m_CookieBroadcastMessages = 0 End If End If End Sub #End Region ''' <summary> ''' Forward to overridable OnBrodcastMessage handler ''' </summary> ''' <param name="msg"></param> ''' <param name="wParam"></param> ''' <param name="lParam"></param> ''' <returns></returns> ''' <remarks></remarks> Private Function IVsBroadcastMessageEvents_OnBroadcastMessage(ByVal msg As UInteger, ByVal wParam As System.IntPtr, ByVal lParam As System.IntPtr) As Integer Implements IVsBroadcastMessageEvents.OnBroadcastMessage OnBroadcastMessage(msg, wParam, lParam) Return Interop.NativeMethods.S_OK End Function ''' <summary> ''' Raise OnBroadcastMessage event. Can be overridden to implement custom handling of broadcast messages ''' </summary> ''' <param name="msg"></param> ''' <param name="wParam"></param> ''' <param name="lParam"></param> ''' <remarks></remarks> Protected Overridable Sub OnBroadcastMessage(ByVal msg As UInteger, ByVal wParam As System.IntPtr, ByVal lParam As System.IntPtr) RaiseEvent BroadcastMessage(msg, wParam, lParam) End Sub #Region "Standard dispose pattern - the only thing we need to do is to unadvise events..." Private disposed As Boolean = False ' IDisposable Private Overloads Sub Dispose(ByVal disposing As Boolean) If Not Me.disposed Then If disposing Then DisconnectBroadcastMessages() End If End If Me.disposed = True End Sub #Region " IDisposable Support " ' This code added by Visual Basic to correctly implement the disposable pattern. Public Overloads Sub Dispose() Implements IDisposable.Dispose ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above. Dispose(True) GC.SuppressFinalize(Me) End Sub Protected Overrides Sub Finalize() ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above. Dispose(False) MyBase.Finalize() End Sub #End Region #End Region End Class ''' <summary> ''' Monitor and set font when font changes... ''' </summary> ''' <remarks></remarks> Friend NotInheritable Class FontChangeMonitor Inherits BroadcastMessageEventsHelper ' Control that we are going to set the font on (if any) Private m_Control As System.Windows.Forms.Control Private m_ServiceProvider As IServiceProvider ''' <summary> ''' Create a new instance... ''' </summary> ''' <param name="sp"></param> ''' <param name="ctrl"></param> ''' <param name="SetFontInitially">If true, set the font of the provided control when this FontChangeMonitor is created</param> ''' <remarks></remarks> Public Sub New(ByVal sp As IServiceProvider, ByVal ctrl As System.Windows.Forms.Control, ByVal SetFontInitially As Boolean) MyBase.new(sp) Debug.Assert(sp IsNot Nothing, "Why did we get a NULL service provider!?") Debug.Assert(ctrl IsNot Nothing, "Why didn't we get a control to provide the dialog font for!?") m_ServiceProvider = sp m_Control = ctrl If SetFontInitially Then m_Control.Font = GetDialogFont(sp) End If End Sub ''' <summary> ''' Override to get WM_SETTINGCHANGE notifications and set the font accordingly... ''' </summary> ''' <param name="msg"></param> ''' <param name="wParam"></param> ''' <param name="lParam"></param> ''' <remarks></remarks> Protected Overrides Sub OnBroadcastMessage(ByVal msg As UInteger, ByVal wParam As System.IntPtr, ByVal lParam As System.IntPtr) MyBase.OnBroadcastMessage(msg, wParam, lParam) If m_Control IsNot Nothing Then If msg = Interop.win.WM_SETTINGCHANGE Then ' Only set font if it is different from the current font... Dim newFont As Font = GetDialogFont(m_ServiceProvider) If Not newFont.Equals(m_Control.Font) Then m_Control.Font = newFont End If End If End If End Sub ''' <summary> ''' Pick current dialog font... ''' </summary> ''' <value></value> ''' <remarks></remarks> Friend Shared ReadOnly Property GetDialogFont(ByVal ServiceProvider As IServiceProvider) As Font Get If ServiceProvider IsNot Nothing Then Dim uiSvc As System.Windows.Forms.Design.IUIService = CType(ServiceProvider.GetService(GetType(System.Windows.Forms.Design.IUIService)), System.Windows.Forms.Design.IUIService) If uiSvc IsNot Nothing Then Return CType(uiSvc.Styles("DialogFont"), Font) End If End If Debug.Fail("Couldn't get a IUIService... cheating instead :)") Return System.Windows.Forms.Form.DefaultFont End Get End Property End Class ''' <summary> ''' Determine if the specified custom tool is registered for the current project system ''' </summary> ''' <param name="hierarchy">Hierarchy to check if the custom tool is registered for</param> ''' <param name="customToolName">Name of custom tool to look for</param> ''' <returns>True if registered, false otherwise</returns> ''' <remarks></remarks> Friend Shared Function IsCustomToolRegistered(ByVal hierarchy As IVsHierarchy, ByVal customToolName As String) As Boolean If hierarchy Is Nothing Then Throw New ArgumentNullException("hierarchy") If customToolName Is Nothing Then Throw New ArgumentNullException("customToolName") ' All project systems support empty string (= no custom tool) If customToolName.Length = 0 Then Return True Dim sfgFactory As IVsSingleFileGeneratorFactory = TryCast(hierarchy, IVsSingleFileGeneratorFactory) If sfgFactory Is Nothing Then ' If the hierarchy doesn't support IVsSingleFileGeneratorFactory, then we assume that ' the custom tools aren't supported by the project system. Return False End If Dim pbGeneratesDesignTimeSource As Integer Dim pbGeneratesSharedDesignTimeSource As Integer Dim pbUseTempPEFlag As Integer Dim pguidGenerator As System.Guid Dim hr As Integer = sfgFactory.GetGeneratorInformation(customToolName, pbGeneratesDesignTimeSource, pbGeneratesSharedDesignTimeSource, pbUseTempPEFlag, pguidGenerator) If VSErrorHandler.Succeeded(hr) Then Return True Else Return False End If End Function End Class End Namespace