With each year's rollout of SOLIDWORKS, what's new in the API often gets overlooked or relegated to footnotes, so it is about time to have an entire series of blog posts on what is new in the API for the SOLIDWORKS product line.

Add custom tabs to a PDM vault view in Windows Explorer

This is an exciting new feature that will allow you to customize your vault view to add custom user interface tabs built right into your vault view.  You can now embed any .NET control into the vault view to create a seamless integration to external systems or to allow other .NET functions be called without having to create links to the code through your data cards.  You can use a custom name and icon to identify your new custom tab.  These features are implemented using the new IEdmCmdMgr6 interface.

GSC Custom Tab

Here is the code used to create the custom tab in a 2018 PDM vault.

    public class CustomTabs : IEdmAddIn5 {
        
        private String tabName = "GSC";
        private String iconName = "GSC.png";
        private String toolTip = "GSC Custom Tab View";
        private String uniqueId = "F4C84E2B-3D7B-4FD2-B65A-3323C82D65BD"; // generated a guid to use, can be any unique string

        public void GetAddInInfo(ref EdmAddInInfo poInfo, IEdmVault5 poVault, IEdmCmdMgr5 poCmdMgr) {
            try {
                poInfo.mbsAddInName = "PDM Custom Tab API Example";
                poInfo.mbsCompany = "GSC";
                poInfo.mbsDescription = "This AddIn will show the basics of what is needed to create your own custom tab in PDM Professional.";
                poInfo.mlAddInVersion = 20170926;
                poInfo.mlRequiredVersionMajor = 17;
                poInfo.mlRequiredVersionMinor = 5;  // Need to use 17.5 until 18 SP0 is released
                
                // need to add both a hook and a command to create the tab.  Since I am not using the command, I am only showing it in admin tool
                poCmdMgr.AddHook(EdmCmdType.EdmCmd_PreExploreInit);
                poCmdMgr.AddCmd(12321415, "CTC", (int)EdmMenuFlags.EdmMenu_NeverInContextMenu + (int)EdmMenuFlags.EdmMenu_Administration);
                // hook to intercept when the tab is activated
                poCmdMgr.AddHook(EdmCmdType.EdmCmd_ActivateAPITab);
            } catch (System.Runtime.InteropServices.COMException ex) {
                MessageBox.Show($"HRESULT = 0x{ex.ErrorCode.ToString("X")} {ex.Message}", "Interop Error", MessageBoxButton.OK, MessageBoxImage.Error);
            } catch (Exception ex) {
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        public void OnCmd(ref EdmCmd poCmd, ref EdmCmdData[] ppoData) {
            try {
                switch (poCmd.meCmdType) {
                    case EdmCmdType.EdmCmd_PreExploreInit:
                        createCustomTabView(poCmd.mpoExtra);
                        break;
                    case EdmCmdType.EdmCmd_ActivateAPITab:
                        MessageBox.Show("The custom tab has been activated!", "Activate", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                        break;
                    default:
                        break;
                }
            } catch (System.Runtime.InteropServices.COMException ex) {
                MessageBox.Show($"HRESULT = 0x{ex.ErrorCode.ToString("X")} {ex.Message}", "Interop Error", MessageBoxButton.OK, MessageBoxImage.Error);
            } catch (Exception ex) {
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void createCustomTabView(Object poCmdMgr) {

            String iconLocation = Path.Combine(getAssemblyDirectory(), iconName);

            // create control
            WinForm wf = new WinForm();

            // get control id
            long windowHandle = wf.Handle.ToInt64();

            // call to add the tab
            ((IEdmCmdMgr6)poCmdMgr).AddVaultViewTab(windowHandle, tabName, iconLocation, toolTip, uniqueId);
        }

        // method to allow the png to be saved in the vault
        private String getAssemblyDirectory() {
            String codeBase = Assembly.GetExecutingAssembly().CodeBase;
            UriBuilder uri = new UriBuilder(codeBase);
            String path = Uri.UnescapeDataString(uri.Path);
            return Path.GetDirectoryName(path);
        }
    }

Get a list of values associated with a drop-down control on a data card

We no longer have to create a direct SQL connection to the database to get this information, using the IEdmCardControl7 interface, we now can get the card list data from a handy API call.

Card List Values

Card List Program Example Screenshot

 

Here is a small code sample of how you could populate a collection from a selected file's card variable.

String selectedFile = @"C:\2018-WHATS-NEW-API\New Folder\GSC.png";
String selectedVariable = "Material";
IEdmFile5 file = vault.GetFileFromPath(selectedFile, out IEdmFolder5 folder);
IEdmCard5 card = folder.GetCard(Path.GetExtension(selectedFile).Substring(1));
Object variableName = selectedVariable;
IEdmCardControl7 cardControl = (IEdmCardControl7)card.GetControl(card.GetControlID(ref variableName));
if (cardControl.GetControlVariableList(file.ID, out String[] cardListStrings)) {
    cardListEntries.Clear();
    foreach (String cardListItem in cardListStrings) {
        cardListEntries.Add(cardListItem);
    }
}

You can download and look through the entire code samples on GitHub.