diff --git a/Source/ExcelDna.Integration/ComInterop/ExcelComAddInHelper.cs b/Source/ExcelDna.Integration/ComInterop/ExcelComAddInHelper.cs index c0e7313e..7a447880 100644 --- a/Source/ExcelDna.Integration/ComInterop/ExcelComAddInHelper.cs +++ b/Source/ExcelDna.Integration/ComInterop/ExcelComAddInHelper.cs @@ -35,10 +35,6 @@ public static void OnUnloadComAddIn(ExcelComAddIn addIn, object addInInst) public static void LoadComAddIn(ExcelComAddIn addIn) { - // If we are called without the addIn's DnaLibrary being set, default to the current library - if (addIn.DnaLibrary == null) - addIn.DnaLibrary = DnaLibrary.CurrentLibrary; - Guid clsId; string progId; @@ -62,6 +58,16 @@ public static void LoadComAddIn(ExcelComAddIn addIn) // Change from Dna.xxx.n to Dna_xxx_n to avoid McAfee bug that blocks registry writes with a "." anywhere progId = "Dna_" + clsId.ToString("N") + "_" + loadedComAddIns.Count; } + + LoadComAddIn(addIn, clsId, progId); + } + + internal static void LoadComAddIn(ExcelComAddIn addIn, Guid clsId, string progId) + { + // If we are called without the addIn's DnaLibrary being set, default to the current library + if (addIn.DnaLibrary == null) + addIn.DnaLibrary = DnaLibrary.CurrentLibrary; + addIn.SetProgId(progId); // Put together some nicer descriptions for the Add-ins dialog. diff --git a/Source/ExcelDna.Integration/CustomUI/ExcelCustomTaskPane.cs b/Source/ExcelDna.Integration/CustomUI/ExcelCustomTaskPane.cs index beab8e2f..690cc2ee 100644 --- a/Source/ExcelDna.Integration/CustomUI/ExcelCustomTaskPane.cs +++ b/Source/ExcelDna.Integration/CustomUI/ExcelCustomTaskPane.cs @@ -25,18 +25,73 @@ public static CustomTaskPane CreateCustomTaskPane(Type userControlType, string t return CreateCustomTaskPane(userControlType, title, Type.Missing); } + public static CustomTaskPane CreateCustomTaskPane(Type userControlType, string title, Guid clsIdCTPAddIn, string progIdCTPAddIn) + { + return CreateCustomTaskPane(userControlType, title, Type.Missing, clsIdCTPAddIn, progIdCTPAddIn); + } + public static CustomTaskPane CreateCustomTaskPane(Type userControlType, string title, object parent) { object userControl = Activator.CreateInstance(userControlType); return CreateCustomTaskPane(userControl, title, parent); } + public static CustomTaskPane CreateCustomTaskPane(Type userControlType, string title, object parent, Guid clsIdCTPAddIn, string progIdCTPAddIn) + { + object userControl = Activator.CreateInstance(userControlType); + return CreateCustomTaskPane(userControl, title, parent, clsIdCTPAddIn, progIdCTPAddIn); + } + public static CustomTaskPane CreateCustomTaskPane(object userControl, string title) { return CreateCustomTaskPane(userControl, title, Type.Missing); } + public static CustomTaskPane CreateCustomTaskPane(object userControl, string title, Guid clsIdCTPAddIn, string progIdCTPAddIn) + { + return CreateCustomTaskPane(userControl, title, Type.Missing, clsIdCTPAddIn, progIdCTPAddIn); + } + public static CustomTaskPane CreateCustomTaskPane(object userControl, string title, object parent) + { + return CreateCustomTaskPane((progId) => CreateCustomTaskPane(progId, title, parent), userControl); + } + + public static CustomTaskPane CreateCustomTaskPane(object userControl, string title, object parent, Guid clsIdCTPAddIn, string progIdCTPAddIn) + { + return CreateCustomTaskPane((progId) => CreateCustomTaskPane(progId, title, parent, clsIdCTPAddIn, progIdCTPAddIn), userControl); + } + + // UserControl as already registered. Just create via factory and add-in. + public static CustomTaskPane CreateCustomTaskPane(string controlProgId, string title) + { + return CreateCustomTaskPane(controlProgId, title, Type.Missing); + } + + // UserControl as already registered. Just create via factory and add-in. + public static CustomTaskPane CreateCustomTaskPane(string controlProgId, string title, Guid clsIdCTPAddIn, string progIdCTPAddIn) + { + return CreateCustomTaskPane(controlProgId, title, Type.Missing, clsIdCTPAddIn, progIdCTPAddIn); + } + + public static CustomTaskPane CreateCustomTaskPane(string controlProgId, string title, object parent) + { + return CreateCustomTaskPane(GetCTPFactory(null, null), controlProgId, title, parent); + } + + public static CustomTaskPane CreateCustomTaskPane(string controlProgId, string title, object parent, Guid clsIdCTPAddIn, string progIdCTPAddIn) + { + return CreateCustomTaskPane(GetCTPFactory(clsIdCTPAddIn, progIdCTPAddIn), controlProgId, title, parent); + } + + private static CustomTaskPane CreateCustomTaskPane(ICTPFactory factory, string controlProgId, string title, object parent) + { + CustomTaskPane newCTP = factory.CreateCTP(controlProgId, title, parent); + _customTaskPanes.Add(new WeakReference(newCTP)); // TODO: Only removed when add-in is unloaded...??? + return newCTP; + } + + private static CustomTaskPane CreateCustomTaskPane(Func ctpActivator, object userControl) { // I could use the ProgId and ClsId of the UserControl type here. // But then the registration has to be persistent or coordinated, which I dislike. @@ -58,7 +113,7 @@ public static CustomTaskPane CreateCustomTaskPane(object userControl, string tit using (new ProgIdRegistration(progId, clsId)) using (new ClsIdRegistration(clsId, progId)) { - return CreateCustomTaskPane(progId, title, parent); + return ctpActivator(progId); } } catch (UnauthorizedAccessException secex) @@ -69,27 +124,16 @@ public static CustomTaskPane CreateCustomTaskPane(object userControl, string tit } } - // UserControl as already registered. Just create via factory and add-in. - public static CustomTaskPane CreateCustomTaskPane(string controlProgId, string title) - { - return CreateCustomTaskPane(controlProgId, title, Type.Missing); - } - - public static CustomTaskPane CreateCustomTaskPane(string controlProgId, string title, object parent) - { - ICTPFactory factory = GetCTPFactory(); - CustomTaskPane newCTP = factory.CreateCTP(controlProgId, title, parent); - _customTaskPanes.Add(new WeakReference(newCTP)); // TODO: Only removed when add-in is unloaded...??? - return newCTP; - } - - private static ICTPFactory GetCTPFactory() + private static ICTPFactory GetCTPFactory(Guid? clsIdCTPAddIn, string progIdCTPAddIn) { if (_addin == null) { // Register and create addin _addin = new ExcelCustomTaskPaneAddIn { DnaLibrary = DnaLibrary.CurrentLibrary }; - ExcelComAddInHelper.LoadComAddIn(_addin); + if (clsIdCTPAddIn.HasValue && !string.IsNullOrWhiteSpace(progIdCTPAddIn)) + ExcelComAddInHelper.LoadComAddIn(_addin, clsIdCTPAddIn.Value, progIdCTPAddIn); + else + ExcelComAddInHelper.LoadComAddIn(_addin); } return _addin.Factory; } diff --git a/Source/ExcelDna.Test/Commmands.cs b/Source/ExcelDna.Test/Commmands.cs index 78b9929a..1cd4c5d3 100644 --- a/Source/ExcelDna.Test/Commmands.cs +++ b/Source/ExcelDna.Test/Commmands.cs @@ -20,5 +20,11 @@ public static void MyQueueMacro() { ExcelAsyncUtil.QueueMacro("MyTestCommand"); } + + [ExcelCommand(MenuText = "MyShowCustomPane")] + public static void MyShowCustomPane() + { + CustomPane.Show(); + } } } diff --git a/Source/ExcelDna.Test/CustomPane.cs b/Source/ExcelDna.Test/CustomPane.cs new file mode 100644 index 00000000..09fbadcc --- /dev/null +++ b/Source/ExcelDna.Test/CustomPane.cs @@ -0,0 +1,26 @@ +using ExcelDna.Integration.CustomUI; +using System; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace ExcelDna.Test +{ + internal class CustomPane + { + public static void Show() + { + var myControl = new MyUserControl(); + var customPane = CustomTaskPaneFactory.CreateCustomTaskPane(myControl, nameof(myControl), + new Guid("dfdd066f-a8ce-4be0-ac13-20a185333473"), "1a7ad958-f8f5-43d4-9161-5bbab6ecda62"); + + customPane.Visible = true; + } + } + + public interface IMyUserControl { } + + [ComVisible(true)] + [Guid("c5a18d1b-b798-49cf-9a3f-37a094905170")] + [ComDefaultInterface(typeof(IMyUserControl))] + public class MyUserControl : UserControl, IMyUserControl { } +} diff --git a/Source/ExcelDna.Test/RibbonController.cs b/Source/ExcelDna.Test/RibbonController.cs index 2898c94a..97790697 100644 --- a/Source/ExcelDna.Test/RibbonController.cs +++ b/Source/ExcelDna.Test/RibbonController.cs @@ -5,6 +5,8 @@ namespace Ribbon { [ComVisible(true)] + [ProgId("175c15e3-4dd8-49d0-94cf-f95800017594")] + [Guid("6242439e-ecc6-46eb-a666-edd3d93414a4")] public class RibbonController : ExcelRibbon { public override string GetCustomUI(string RibbonID)