// -------------------------------------------------------------------------------------------- /// <summary> /// This method is called directly before OnToolWindowCreated. /// </summary> // -------------------------------------------------------------------------------------------- private void OnToolWindowCreatedInternal() { VsDebug.Assert(_Frame != null, "Frame should be set before this method is called"); // --- If any property were set, set them on the frame. Caption = _Caption; BitmapResourceID = _BitmapResourceID; BitmapIndex = _BitmapIndex; }
// -------------------------------------------------------------------------------------------- /// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"> /// <c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only /// unmanaged resources. /// </param> // -------------------------------------------------------------------------------------------- protected virtual void Dispose(bool disposing) { if (disposing) { if (_VsShell != null) { try { // --- Don't check for return code because here we can't do anything in case of failure. _VsShell.UnadviseBroadcastMessages(_BroadcastEventCookie); } catch (SystemException) { // --- This exception is intentionally caught } _VsShell = null; _BroadcastEventCookie = 0; } IWin32Window window = Window; if (window is IDisposable) { try { ((IDisposable)window).Dispose(); } catch (Exception) { VsDebug.Fail("Failed to dispose window"); } } if (_CommandService != null && _CommandService is IDisposable) { try { ((IDisposable)_CommandService).Dispose(); } catch (Exception) { VsDebug.Fail("Failed to dispose command service"); } } _CommandService = null; if (_ParentServiceProvider != null) { _ParentServiceProvider = null; } if (_HelpService != null) { _HelpService = null; } // --- Do not clear _ServiceProvider. SetSite will do it for us. _Zombied = true; } }
// -------------------------------------------------------------------------------------------- /// <summary> /// Obtains the menu information for a command handler method. /// </summary> /// <param name="idAttr">CommandID attribute belonging to the command.</param> /// <param name="method">Method information to scan for attributes.</param> /// <param name="defaultGuid"> /// Default GUID to be used if not defined with the command handler. /// </param> /// <returns>MenuCommandInfo instance about the method.</returns> // -------------------------------------------------------------------------------------------- private static MenuCommandInfo ObtainCommandMethodAttributes(CommandIdAttribute idAttr, MethodInfo method, Guid defaultGuid) { var menuInfo = new MenuCommandInfo(); bool commandAttrFound = false; foreach (var attr in method.GetCustomAttributes(true)) { // --- Check for command method attributes var cmdAttr = attr as CommandMethodAttribute; if (cmdAttr != null) { if (commandAttrFound) { VsDebug.Fail(String.Format("Only one CommandMethodAttribute is allowed for {0}.{1}", method.DeclaringType.Name, method.Name)); continue; } commandAttrFound = true; if (cmdAttr is CommandStatusMethodAttribute) { menuInfo.QueryStatusMethod = method; } else if (cmdAttr is CommandExecMethodAttribute) { menuInfo.ExecMethod = method; } else if (cmdAttr is CommandChangeMethodAttribute) { menuInfo.ChangeMethod = method; } } // --- Check command action var actionAttr = attr as ActionAttribute; if (actionAttr != null) { menuInfo.Action = actionAttr; } // --- Check promote flag var promoteAttr = attr as PromoteAttribute; if (promoteAttr != null) { menuInfo.Promote = true; } // --- Set command ID and handle the defaultvalue of the command GUID menuInfo.Guid = idAttr.Guid == Guid.Empty ? defaultGuid : idAttr.Guid; menuInfo.Id = idAttr.Id; } return(menuInfo); }
// -------------------------------------------------------------------------------------------- /// <summary> /// Gets the service object of the specified type. /// </summary> /// <param name="serviceType"> /// An object that specifies the type of service object to get. /// </param> /// <returns> /// A service object of type <paramref name="serviceType"/>.-or- null if there is no service /// object of type <paramref name="serviceType"/>. /// </returns> // -------------------------------------------------------------------------------------------- protected virtual object GetService(Type serviceType) { if (_Zombied) { VsDebug.Fail("GetService called after WindowPane was zombied"); return(null); } if (serviceType == null) { throw new ArgumentNullException("serviceType"); } // --- We provide IMenuCommandService, so we will demand create it. MenuCommandService also // --- implements IOleCommandTarget, but unless someone requested IMenuCommandService no // --- commands will exist, so we don't demand create for IOleCommandTarget if (serviceType == typeof(IMenuCommandService)) { EnsureCommandService(); return(_CommandService); } if (serviceType == typeof(IOleCommandTarget)) { return(_CommandService); } if (serviceType == typeof(IHelpService)) { if (_HelpService == null) { _HelpService = new HelpService(this); } return(_HelpService); } // --- Ask the if (_ServiceProvider != null) { object service = _ServiceProvider.GetService(serviceType); if (service != null) { return(service); } } if (_ParentServiceProvider != null) { return(_ParentServiceProvider.GetService(serviceType)); } return(null); }
// -------------------------------------------------------------------------------------------- /// <summary> /// Writes a VSPackage's configuration to disk using the Visual Studio settings mechanism when /// the export option of an Import/Export Settings feature available on the IDE’s Tools menu /// is selected by a user. /// </summary> /// <remarks> /// This method is called when the dialog page should load its default settings from the /// profile XML file. /// </remarks> // -------------------------------------------------------------------------------------------- public virtual void LoadSettingsFromXml(IVsSettingsReader reader) { _Initializing = true; try { object automationObject = AutomationObject; var properties = TypeDescriptor.GetProperties(automationObject, new Attribute[] { DesignerSerializationVisibilityAttribute.Visible }); foreach (PropertyDescriptor property in properties) { var converter = property.Converter; if (converter.CanConvertTo(typeof(string)) && converter.CanConvertFrom(typeof(string))) { // --- read from the xml feed object cv = null; try { string value; if (NativeMethods.Succeeded(reader.ReadSettingString(property.Name, out value)) && (value != null)) { cv = property.Converter.ConvertFromInvariantString(value); } } catch (Exception) { // --- ReadSettingString throws an exception if the property is not found and we also // --- catch ConvertFromInvariantString exceptions so that we gracefully handle bad // --- vssettings. VsDebug.Fail("Error in ReadSettingsString ignored."); } // --- Not all values have to be present if (cv != null) { property.SetValue(automationObject, cv); } } } } finally { _Initializing = false; } // --- Hook in properties HookProperties(true); OnPageDataLoaded(); }
// -------------------------------------------------------------------------------------------- /// <summary> /// Loads the settings belonging to this dialog page from the store. /// </summary> /// <remarks> /// This method is called when the dialog page should load its default settings from the /// registry. The default implementation gets the Package service, gets the user registry key, /// and reads in all properties for this page that could be converted from strings. /// </remarks> // -------------------------------------------------------------------------------------------- public virtual void LoadSettingsFromStorage() { _Initializing = true; try { // --- Obtain registry key for the package var package = PackageBase.GetPackageInstance <TPackage>(); VsDebug.Assert(package != null, "No package service; we cannot load settings"); if (package != null) { using (var rootKey = package.UserRegistryRoot) { // --- Obtain the path where settings are stored var path = SettingsRegistryPath; object automationObject = AutomationObject; var key = rootKey.OpenSubKey(path, false); if (key != null) { using (key) { // --- Read each property from the store using the invariant string form string[] valueNames = key.GetValueNames(); var properties = TypeDescriptor.GetProperties(automationObject); foreach (var valueName in valueNames) { var value = key.GetValue(valueName).ToString(); var prop = properties[valueName]; if (prop != null && prop.Converter.CanConvertFrom(typeof(string))) { prop.SetValue(automationObject, prop.Converter.ConvertFromInvariantString(value)); } } } } } } } finally { _Initializing = false; } // --- Hook in the properties HookProperties(true); OnPageDataLoaded(); }
// -------------------------------------------------------------------------------------------- /// <summary> /// Ensures that IVsRunningDocTableEvents is unadvised when required. /// </summary> // -------------------------------------------------------------------------------------------- public void EnsureUnadvise() { lock (this) { if (AdviseCount == 0) { VsDebug.Fail("EnsureUnadvise has been called with a zero-valued AdviceCount."); return; } AdviseCount--; if (AdviseCount == 0) { NativeMethods.ThrowOnFailure(Unadvise(_EventCookie)); Events = null; } } }
// -------------------------------------------------------------------------------------------- /// <summary> /// Disposes this object. /// </summary> // -------------------------------------------------------------------------------------------- protected override void Dispose(bool disposing) { if (disposing) { // --- First dispose the dialog container if (_Container != null) { try { _Container.Dispose(); } catch (Exception) { VsDebug.Fail("Failed to dispose container"); } _Container = null; } // --- Dispose the window itself if (_Window != null && _Window is IDisposable) { try { ((IDisposable)_Window).Dispose(); } catch (Exception) { Debug.Fail("Failed to dispose window"); } _Window = null; } // --- Reset the dialog subclass if (_Subclass != null) { _Subclass = null; } // --- Unhook dialog page properties HookProperties(false); } base.Dispose(disposing); }
// -------------------------------------------------------------------------------------------- /// <summary> /// This function hooks property change events so that we automatically serialize /// if the value changes outside of UI and loading /// </summary> /// <param name="hook"> /// True if properties should be hooked; otherwise they should be unhooked. /// </param> // -------------------------------------------------------------------------------------------- private void HookProperties(bool hook) { if (_PropertyChangedHooked != hook) { if (_OnPropertyChanged == null) { _OnPropertyChanged = OnPropertyChanged; } object automationObject = null; try { automationObject = AutomationObject; } catch (Exception e) { VsDebug.Fail(e.ToString()); } if (automationObject != null) { var properties = TypeDescriptor.GetProperties(automationObject, new Attribute[] { DesignerSerializationVisibilityAttribute.Visible }); foreach (PropertyDescriptor property in properties) { if (hook) { property.AddValueChanged(automationObject, _OnPropertyChanged); } else { property.RemoveValueChanged(automationObject, _OnPropertyChanged); } } _PropertyChangedHooked = hook; } } }
// -------------------------------------------------------------------------------------------- /// <summary> /// Writes a VSPackage's configuration to local storage (typically the registry) following /// state update. /// </summary> // -------------------------------------------------------------------------------------------- public virtual void SaveSettingsToStorage() { var package = PackageBase.GetPackageInstance <TPackage>(); VsDebug.Assert(package != null, "No package service; we cannot load settings"); if (package != null) { // --- Oper the user registry key to save back settings. using (var rootKey = package.UserRegistryRoot) { var path = SettingsRegistryPath; var automationObject = AutomationObject; var key = rootKey.OpenSubKey(path, true) ?? rootKey.CreateSubKey(path); if (key == null) { VsDebug.Fail("Could not obtain storage key."); return; } using (key) { var properties = TypeDescriptor.GetProperties(automationObject, new Attribute[] { DesignerSerializationVisibilityAttribute.Visible }); foreach (PropertyDescriptor property in properties) { var converter = property.Converter; if (converter.CanConvertTo(typeof(string)) && converter.CanConvertFrom(typeof(string))) { key.SetValue(property.Name, converter.ConvertToInvariantString(property.GetValue(automationObject))); } } } } } }