12 Replies Latest reply on Feb 4, 2011 5:18 PM by cpl

    ContextChanged troubles

      Hi all,

       

      Im having some problems that i think are related to my use of the ContextChanged method. 

       

      I am using this method, triggered when an MDB Module is selected, to drive some functions that change the time ranges of a bunch of symbols, namely Bars and Trends.

       

      The trouble is that although these methods successfully update all the symbol's time ranges, the moment the ContextChange sub finishes all the time ranges revert back to the ProcessBook default of *-2h to *. I have watched each element update through my IDE' debugger and it appears that they revert the moment it steps out of the ContextChanged. 

       

      I presume that when changing the screen's MDB context that another method is called in the background causing the display to revert. Can anyone shed any light on this, or suggest a work around?

       

      Cheers.

       

       

       

       

        • Re: ContextChanged troubles
          dhollebeek

          Yes, ContextChanged gets early on in the context changing process, and then a Revert is done by most symbols.  The way we get around this in the Playback toolbar is to set a flag that the context changed and then apply the time ranges the next time Application.OnIdle fires ...

            • Re: ContextChanged troubles

              I see, i will try this approach. Thanks for the suggestion.

               

              On the same note; could you provide an example code snippet on how to use  .OnIdle, im not sure how i could get a handle on this event.

               

              Cheers,

                • Re: ContextChanged troubles
                  dhollebeek
                  Dim WithEvents gApp As Application
                  
                  Private Sub Display_Open()
                      gApp = ThisDisplay.Application
                  End Sub
                  
                  Private Sub gApp_OnIdle()
                  
                  End Sub
                  

                   

                    • Re: ContextChanged troubles

                      I got it working using your solution. Thanks for the help David.

                        • Re: ContextChanged troubles
                          cpl

                          I've got a similar problem that is resolved by OnIdle; however, when using OnIdle, the CPU utilization runs up to 60+% and the performance becomes very sluggish.  I'm new to PB  programming and just trying to figure this stuff out.

                            • Re: ContextChanged troubles
                              andreas

                              Tom,

                               

                              I guess this depends on what you are doing in OnIdle - could you post some code?

                                • Re: ContextChanged troubles
                                  cpl

                                  Andreas, what I am trying to accomplish...I've got a PDI with several trends with upto 6 pens per trend. With a context change, a pen may or maynot be active; therefore, I would like to ShowTrance=False for the pens that are not active. Now to the code...

                                   
                                  Private Sub Display_Open()
                                  
                                  Set myCH = Application.ContextHandlers("ModuleContext")
                                  
                                  Set myApp = Thisdisplay.Application
                                  
                                  End Sub
                                  
                                  Private Sub myCH_ContextChanged(FromDisplay As Display, FromCH As ContextHandler)
                                  
                                  chngCH = True
                                  
                                  End Sub
                                  
                                  Private Sub myApp_OnIdle()
                                  
                                  If chngCH Then
                                  
                                     Call setDummyTracesInactive
                                  
                                     chngCH = False
                                  
                                  End If
                                  
                                  End Sub
                                  

                                   

                                    • Re: ContextChanged troubles
                                      andreas

                                      mmh - until someone comes up with a better idea - i think you should send your OnIdle function to sleep for some time.

                                       

                                      you need to define the sleep function first:

                                       
                                      Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
                                      

                                      afterwards you may add a

                                       
                                      Sleep (100)
                                      

                                      to your OnIdle - that should lower the CPU load.

                                        • Re: ContextChanged troubles
                                          dhollebeek

                                          What does setDummyTracesInactive do?  If that causes a context change to fire, you will be in a case where OnIdle does significant processing every time it fires.

                                           

                                          Also, sleeping in OnIdle isn't the greatest idea.  If you want to restrict how often it processes, just keep a global timestamp for the last time chngCH was true in OnIdle and ignore the flag until a certain number of milliseconds have passed.  This would limit how much setDummyTracesInactive gets called without locking the UI thread (which is what sleeping in OnIdle will do).

                                            • Re: ContextChanged troubles
                                              cpl

                                              chngCH is set TRUE when a context module is selected from the available modules. with OnIdle running, it detects the change and calls setDummyTracesInactive which sets the various pens' ShowTrace attribute. It appears when OnIdle is running, it is spinning its wheels until chngCH is TRUE...here's is the code. If there is an easier way to accomplish my task, I'd love to hear it.

                                               
                                              Private Sub setDummyTracesInactive()
                                              
                                              Dim mySymbol As Symbol
                                              
                                              Dim myTrend As Trend
                                              
                                              Dim xx As Integer
                                              
                                              ' for all trends, deactivate traces mapped to dummy tags
                                              
                                              For Each mySymbol In ThisDisplay.Symbols
                                              
                                                 If mySymbol.Type = pbSymbolTrend Then
                                              
                                                     Set myTrend = mySymbol
                                              
                                                     If InStr(1, myTrend.GetTagName(2), ".OP") = 0 Then
                                              
                                                         For xx = 1 To myTrend.TraceCount
                                              
                                                             myTrend.CurrentTrace = xx
                                              
                                                             myTrend.ShowTrace = IIf(myTrend.TraceValuesCount > 1, True, False)
                                              
                                                         Next
                                              
                                                     End If
                                              
                                                 End If
                                              
                                              Next mySymbol
                                              
                                              End Sub
                                              

                                               

                                                • Re: ContextChanged troubles
                                                  dhollebeek

                                                  It doesn't look like there's anything there that would fire context changed events (though you might want to set some breakpoints and check to make sure).  OnIdle is a funny method.  It gets called alot when Window is idle, but doesn't get called when Windows is busy (it's effectively a low-priority task).  Therefore, even though you are experiencing high CPU load when the app is idle, it shouldn't degrade performance when the app is busy.  I wouldn't worry about it too much ...

                                                    • Re: ContextChanged troubles
                                                      cpl

                                                      David, thanks for all the feedback.  My second post above shows where the context change is fired. I implemented Andreas' SLEEP suggestion  and it reduced the CPU to about 15%. Now when the module context is changed, the unnassigned trend pens are set SowTrace=FALSE. Thanks again for all the help.