15 Replies Latest reply on Aug 18, 2017 5:15 PM by Checkcheck Master

    Get focus on SolidWorks while running an add-in with a User Form

    Checkcheck Master

      Hi there,

       

      I have a SolidWorks Add-in running opening a User Form.

      While the User Form/Add-in is active I can not acces SolidWorks.

      The User Form has two(2) DataGridViews on it representing data from the SW files in the current directory.

      Loading the data for the DataGridViews is taking some time so I was wondering if it is possible to keep the Add-in running in the background and get focus on SolidWork.

      The Add-in acts like a file browser so I like to update when a file is saved just like the Windows File Explorer does.

       

      Anybody?

       

      Greetings!

        • Re: Get focus on SolidWorks while running an add-in with a User Form
          Alex Burnett

          What is the code you are using to open/launch your user form? Are you using a VBA macro or is it a standalone program written outside of SolidWorks? Some specifics would help narrow down what is keeping focus on your form.

          • Re: Get focus on SolidWorks while running an add-in with a User Form
            Christian Chu

            How you called the window form? I guess it's still looking for SW API functions or for the link from datagridviews

              • Re: Get focus on SolidWorks while running an add-in with a User Form
                Alex Burnett

                Without knowing what is going on withing the API code or user form, it's hard to pinpoint the issue. I am trying to figure out if the program is preventing switching to SW for one of the following reasons:

                 

                1. The user form is called in such a way that it demands focus until its task is complete. This behavior would act similar to the window that pops up when you click File -> Open. The open dialog needs to be completed before you move back to using the software.

                 

                2. SolidWorks is hung up on the API calls causing both the user form you described and SolidWorks to hang while they process the API calls back and forth.

                 

                I am leaning more toward the second option after thinking about it. My suggestion would be to put time stamps in your code that indicate which tasks are taking so long to process. If there's another way to perform those tasks then it may help your performance. Again, I can't give better suggestions without knowing more so I hope that helps.

                  • Re: Get focus on SolidWorks while running an add-in with a User Form
                    Christian Chu

                    1. The user form is called in such a way that it demands focus until its task is complete. This behavior would act similar to the window that pops up when you click File -> Open. The open dialog needs to be completed before you move back to using the software.

                     

                    2. SolidWorks is hung up on the API calls causing both the user form you described and SolidWorks to hang while they process the API calls back and forth.

                    Totally agreed ! I think he'd better comment all the SW API calls (might be running in the back) and replace with a "Hello world !"  and to make sure the form is loaded properly !

                      • Re: Get focus on SolidWorks while running an add-in with a User Form
                        Checkcheck Master

                        Dear Alex and Christian,

                         

                        Thanks for your reactions, I'l try to explain what I tried.

                        It is an Add-in written in VB.NET, like: Create and register SolidWorks C# and VB.NET AddIns in 3 Steps

                        See: https://www.youtube.com/watch?v=5Qy7KKy8-fE

                         

                        The Add-in needs to be registered and is creating a Tab for the Add-in with a Command Item with some action, like:

                        cmdIndex0 = cmdGroup.AddCommandItem2("SWPlus", -1, "SWPlus", "SWPlus", 0, "LaunchForm1", "", mainItemID1, menuToolbarOption)

                         

                        As you see, the Command Item is starting 'Public Sub LaunchForm1()'.

                        In which I launch the User Form like:

                        Dim MyForm1 As New FormPartOrAssy(SwApp)

                                MyForm1.ShowDialog()

                         

                        Next in the called form all other actions take place, most off them in the code itself and sometimes calling another module/class.

                         

                        Hope it's enough...

                         

                        Greetings!

                          • Re: Get focus on SolidWorks while running an add-in with a User Form
                            Alex Burnett

                            That actually helps a lot. First things first, change the MyForm1.ShowDialog() to MyForm1.Show().

                             

                            The difference between these is subtle but it's causing your problem I believe. The ShowDialog function keeps focus until it is closed while the Show function doesn't care whether it is in focus or not.

                             

                            Hope that helps. If not, we can keep digging.

                            • Re: Get focus on SolidWorks while running an add-in with a User Form
                              Christian Chu

                              OK - I understand now

                              You used form.showdialog so it behaves like a messagebox which blocks the execution code until the dialog box, userform MyForm1, is closed - That's why you can't access to the SW

                              As Alex suggested, replacing .showdialog with .show then you can access to SW while loading the userform

                              • Re: Get focus on SolidWorks while running an add-in with a User Form
                                roberto gennari

                                You could use the form property TopMost property to true to keep it in the foreground without blocking access to the SolidWorks interface, always allowing you to minimize it.

                                  • Re: Get focus on SolidWorks while running an add-in with a User Form
                                    Christian Chu

                                    I'm kind of confusing here - what TopMost Prop has something to do with blocking access to SW?

                                      • Re: Get focus on SolidWorks while running an add-in with a User Form
                                        Alex Burnett

                                        This is a setting in Visual Studio when creating an external application which communicates with SolidWorks using the API. See below for the option on one of my projects. I circled the description. It is a setting similar to the option in something like the Windows Task Manager under Options -> Always On Top. It simply places the window on top of everything else even if it doesn't have focus.

                                         

                                        Capture.PNG

                                          • Re: Get focus on SolidWorks while running an add-in with a User Form
                                            Christian Chu

                                            What I meant is setting topmost to true or false has nothing to do with blocking access to SW

                                              • Re: Get focus on SolidWorks while running an add-in with a User Form
                                                Alex Burnett

                                                The issue isn't with the TopMost property. That is a way to just keep the form in the foreground so you can monitor its progress. The issue came from the ShowDialog() rather than Show() I believe.

                                                 

                                                ShowDialog will hold focus and prevent the user from using the parent form until the dialog form is closed. The parent form is the application window that calls the ShowDialog for another form to open. In this case, that is the main SW application. This is typically used in cases where it requires variables to be input by the user on a form in order to be used by the parent form for something. I don't think that is the intent of the OP.

                                                 

                                                Show will bring up the secondary window without preventing the user from going back to the parent window.

                                                 

                                                I hope that helps answer your question.

                                                  • Re: Get focus on SolidWorks while running an add-in with a User Form
                                                    Checkcheck Master

                                                    Thank you guys for the correct answers, 'Show' instead of 'ShowDialog' does the trick, how logic!

                                                    As already mentioned, 'Topmost' as Roberto suggested seems to be relevant in case of a 'Stand Alone' application.

                                                     

                                                    I'm so free to describe one and other and ask some questions.

                                                    As said before, on the form there are two(2) DataGridViews representing data from the SW files in the current directory.

                                                    DataGridView1 is a kind of 'Windows File Explorer style' grid view, every file has it's own row with some columns showing data from Custom Properties(CP's) and/or Configuration Specific Custom Properties(CSCP's).

                                                    DataGridView2 is acting like a ribbon showing the pictures from the files.

                                                    Navigating trough the files is possible in both DataGridViews where you can select(single click) or open(double click) the files from.

                                                    Selecting a file will populate some combo boxes on the user form which can be changed or filled.

                                                    Collecting the data for both the DataGridViews is based on iterate trough the current directory and treat all SW files when showing the form.

                                                    My system is 'CP Description' based in combination with file names which I called 'semi intelligent'.

                                                    Semi intelligent file names within the meaning of suitable for using them for a Pack and Go, both in- or outside the specific project, and including a 3-digit random number for acting 'only' as a placeholder when 'just in the project'.

                                                    Sorting the files is based on a 2-digit 'Group Number' and a 3-digit 'Index Number' within the Description, these numbers easily can be changed without affecting the file name and in the end they will be part of a unique Drawing Number.

                                                    Based on what I wrote above you will understand that I need the value from the CP 'Description' when iterating trough the files to do some actions.

                                                    As far as I know you can only acces those CP values when SolidWorks can open these files.

                                                    To open the files and get the CP values I use 2 approaches:

                                                    1st, when the file is not in use I open the file by the Document Manager(the one with the license key number), in my opinion the fastest way to open and close a SW file.

                                                    2nd, when SW has the file 'in use', it can not be accessed by the Document Manager, in that case I get focus on the file by open it in the background.

                                                    After getting the values the file is closed when not is use to not overload the internal memory, otherwise the file will stay open, this will look like:

                                                    ' Set to not show the opening operation for next opened parts and assemblies.

                                                                swApp.DocumentVisible(False, swDocumentTypes_e.swDocPART)

                                                                swApp.DocumentVisible(False, swDocumentTypes_e.swDocASSEMBLY)

                                                                swApp.DocumentVisible(False, swDocumentTypes_e.swDocDRAWING)

                                                     

                                                                ' Open the file in the background by SolidWorks.

                                                                ' Close file if NOT in use, else keep open.

                                                                If FileInUse(file) Then

                                                                    swModel = swApp.OpenDoc6(file, nDocType, swOpenDocOptions_e.swOpenDocOptions_Silent, "", nErrors, nWarnings)

                                                     

                                                    Here raises my next question:

                                                    To check if the file is 'in use' I've got:

                                                    Public Function FileInUse(ByVal sFile As String) As Boolean

                                                            If System.IO.File.Exists(sFile) Then

                                                                Try

                                                                    Dim F As Short = FreeFile()

                                                                    FileOpen(F, sFile, OpenMode.Binary, OpenAccess.ReadWrite, OpenShare.LockReadWrite)

                                                                    FileClose(F)

                                                                Catch

                                                                    'Debug.Print(sFile)

                                                                    'Debug.Print("File is in Use")

                                                                    Return True

                                                                End Try

                                                            End If

                                                            Return False       

                                                        End Function

                                                     

                                                    For some unknown to me reason this function is return True for some files while I expect a return False, as said, can't get my finger on it.

                                                    So I decided to try this:

                                                    Public Function FileInUse(ByVal sFile As String) As Boolean

                                                            Dim swModelCheck As SolidWorks.Interop.sldworks.ModelDoc2

                                                            swModelCheck = swApp.GetFirstDocument

                                                            'Debug.Print "1st Doc. swModelCheck: " & swModelCheck.GetPathName

                                                            While Not swModelCheck Is Nothing

                                                                'Debug.Print("swModelCheck: " & swModelCheck.GetPathName)

                                                     

                                                                If swModelCheck.GetPathName = sFile Then

                                                                    swModelCheck = Nothing

                                                                    Return True

                                                                    Exit Function

                                                                End If

                                                                swModelCheck = swModelCheck.GetNext

                                                            End While

                                                     

                                                            swModelCheck = Nothing

                                                            Return False

                                                     

                                                        End Function

                                                     

                                                    This seems to work however, when the Add-in tries to save a part or assy and there related drawing file(s), I get the message that the drawing file is opened read only because it is already opened.

                                                    At that moment I, when I check for opened files with a little vba macro, there are no drawing files opened, I have the idea the mentioned little macro works fine, btw, the code is almost similar as the code above.

                                                    So I do not understand why the drawing file is opened read only, anyone?

                                                     

                                                    I've also got some questions regarding how to fill the DataGridViews and the possibility to keep them updated while the Add-in stays opened, how can I fire an event in that case?

                                                    Anyway, how to run some tasks in the background within an Add-in while not in focus?

                                                    I just compare it to the Windows File Explorer which is updating when a file is saved, can I get this behavior for the DataGridViews easily?

                                                    Next time, if you like, I can describe how I deal with the DataGridViews right now.

                                                     

                                                    Greetings!

                                                      • Re: Get focus on SolidWorks while running an add-in with a User Form
                                                        Alex Burnett

                                                        Okay, that's a lot of information to deal with.

                                                         

                                                        1. File in use - What scenario are you looking for here. Are you checking to see if SolidWorks has the file you are looking at currently open in memory? It's not great practice to rely on a catch exception block as a part of your code. It should be there in order to catch issues that you can't check for.

                                                         

                                                        I would recommend a check of the open files by comparing the path to open with each of your open documents. See here for a basic example of how to iterate through the open documents. If the filenames match then you return true, otherwise return false. Do this before attempting to open the file with your program.

                                                         

                                                        2. Event based updates - Yes, there are ways to subscribe to events that SolidWorks has built in. There is a huge list of them here. Some helpful ones are as follows. A quick search will show easy examples of how to create functions in your program that get called when these events are triggered automatically.

                                                             Application:

                                                                  ActiveModelDocChangeNotify

                                                                  FileOpenPreNotify

                                                                  FileOpenPostNotify

                                                                  FileCloseNotify

                                                             Model: (This includes drawing, assembly and part types)

                                                                  ActiveConfigChangePostNotify

                                                                  DestroyNotify

                                                                  FileSavePostNotify

                                                                  ClearSelectionsNotify

                                                                  AddCustomPropertyNotify

                                                                  ChangeCustomPropertyNotify

                                                                  DeleteCustomPropertyNotify

                                                         

                                                        I hope that helps.