13 Replies Latest reply on Mar 9, 2017 5:28 AM by Peter Brinkhuis

    How to distinguish between unsaved drawings via API?

    Peter Brinkhuis

      I'm currently building an add-in that creates drawings. When switching between models, the task pane switches to show the appropriate controls for parts/assemblies/drawings. I'm now looking for a way to distinguish between multiple unsaved drawing files. Is there a proper, robust way to do that?

       

      Persistent IDs sounded great, but those are only attached to features and entities. I did find this forum topic about file IDs, where it is told that we cannot access the internal file ID. Comparing creation dates would be the best solution.

       

      File/Component ID's

       

      My problem is that the drawing files are still unsaved. At least by the user. Is there maybe a temp file created somewhere?

        • Re: How to distinguish between unsaved drawings via API?
          Deepak Gupta

          You can use the GetPathName or GetSaveFlag for the drawing/model to see if it is saved or not.

          • Re: How to distinguish between unsaved drawings via API?
            Amen Allah Jlili

            There should be a way if you attach event handlers to the documents when they get saved. You thus create your own save/history. Please make sure you attach and unattach event handlers in the life cycle of the document/add-in. They can be very nasty.

              • Re: How to distinguish between unsaved drawings via API?
                Peter Brinkhuis

                I'd like to handle the files before they get saved though.

                  • Re: How to distinguish between unsaved drawings via API?
                    Amen Allah Jlili
                    SolidWorks.Interop.sldworks Namespace : DDrawingDocEvents_FileSaveNotifyEventHandler Delegate

                    Pre-notifies the user program when a file is about to be saved and passes the current document name.

                    Remarks

                    When a user selects File, Save for a document that has never been saved, SOLIDWORKS generates FileSaveAsNotify2 instead of FileSaveNotify. You can return S_false to stop SOLIDWORKS from proceeding with the action that generated the notification.

                     

                    If the user attempts to close the document and S_false is returned, then the document does not close; it remains open and is not saved.

                     

                    If developing a C++ application, use swDrawingFileSaveAsNotify2 to register for this notification.
                      • Re: How to distinguish between unsaved drawings via API?
                        Peter Brinkhuis

                        I see now that my remark can be interpreted in multiple ways. Let's clarify. My program will have nothing to do with the save command. It works with unsaved drawing files and there might be multiple ones present at the same time. The trouble is to keep them apart when the user is switching back and forth between files.

                          • Re: How to distinguish between unsaved drawings via API?
                            Amen Allah Jlili

                            I don't understand this bit "The trouble is to keep them apart when the user is switching back and forth between files.".
                            Thanks for more clarificatio

                            • Re: How to distinguish between unsaved drawings via API?
                              Jim Sculley

                              Keep track of them in a collection of some sort.  Use the ActiveDocChangeNotify event to keep track of them.  Here's a simpel C# macro that adds newly opened documents to a list and let s you know if a new document has been activated or one that it already knows about.

                              using SolidWorks.Interop.sldworks;

                              using SolidWorks.Interop.swconst;

                              using System.Runtime.InteropServices;

                              using System;

                              using System.Collections.Generic;

                               

                              namespace IDTest.csproj
                              {
                                  public partial class SolidWorksMacro
                                  {
                                      private List<ModelDoc2> openDocs = new List<ModelDoc2>();
                              
                                      public void Main()
                                      {
                                          swApp.ActiveDocChangeNotify += new DSldWorksEvents_ActiveDocChangeNotifyEventHandler(handleDocumentChange);
                                      }
                              
                                      /// <summary>
                                      ///  The SldWorks swApp variable is pre-assigned for you.
                                      /// </summary>
                                      public SldWorks swApp;
                              
                                      public int handleDocumentChange()
                                      {
                                          ModelDoc2 currentDoc = swApp.ActiveDoc as ModelDoc2;
                                          if (openDocs.Contains(currentDoc))
                                          {
                                              swApp.SendMsgToUser("Switched to known document");
                                          }
                                          else
                                          {
                                              openDocs.Add(currentDoc);
                                              swApp.SendMsgToUser("Added new doc");
                                          }
                                          return 0;
                                      }
                                  }
                              }
                              
                                • Re: How to distinguish between unsaved drawings via API?
                                  Peter Brinkhuis

                                  Thanks for the suggestion Jim, I've given it a go immediately. When switching between documents, the "Added new doc" message comes up every time. I guess the ModelDoc2 items don't stay unchanged completely. I could override the Equals method, but then I would need to now what to compare and that is the whole issue.

                                    • Re: How to distinguish between unsaved drawings via API?
                                      Amen Allah Jlili

                                      Hi Peter!
                                      How about creating a wrapper class over your ModelDoc2s? add a compare method to the class. Not really sure how you'd override the equals method because com class forbid inheritance.

                                      I think what you need to compare is the windows title. When changes are not committed, there is a * at the end of the windows' title's text. I think that's your best shot. You'd need to get the handle of the windows and use WinAPI to get the microsoft's windows title text. I wish it could be easier but SolidWorks's ModelDoc2's GetTitle sallows the "*". I think you add this to Jim Sculley's approach.


                                      Here's my example:

                                      Dim swApp As SldWorks.SldWorks

                                      Dim swmodeldoc2 As SldWorks.ModelDoc2

                                      Dim swframe As SldWorks.Frame

                                      Public Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As LongLong) As Long

                                      Public Declare PtrSafe Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long

                                      Sub main()

                                      Set swApp = Application.SldWorks

                                      Set swmodeldoc2 = swApp.ActiveDoc

                                      Set swframe = swApp.Frame

                                      Dim v As Variant

                                      For i = 0 To swframe.GetModelWindowCount - 1

                                      Dim swmodelwindows As ModelWindow

                                      Set swmodelwindows = swframe.IGetModelWindows(i)

                                      Dim handle As Long

                                      handle = swmodelwindows.hwnd

                                      Debug.Print (getNameFromHwnd(handle))

                                      Next

                                      End Sub

                                      Public Function getNameFromHwnd(hwnd As Long) As String

                                      Dim title As String * 255

                                      Dim tLen As Long

                                      tLen = GetWindowTextLength(hwnd)

                                      GetWindowText hwnd, title, 255

                                      getNameFromHwnd = Left(title, tLen)

                                      End Function

                                       

                                      preview.png

                                       

                                       

                                      Let me know if that works for you

                                       

                                       

                                      Cheers,
                                      Amen
                                      www.cadhero.com

                                      • Re: How to distinguish between unsaved drawings via API?
                                        Jim Sculley

                                        This is strange.  I tried it yesterday and it worked as expected.  This morning, it doesn't work at all.  The macro just exits and doesn't seen to register the event handler.

                                         

                                        Anyway, I recreated it as an add-in and once again it works as expected.  When a new document is created, the "Added new doc" message is shown.  Creating a second new document again shows "Added new doc".  Switching back to the first document displays the "Switched to known document" message.  This was done using SOLIDWORKS 2017 SP2.