9 Replies Latest reply on Sep 20, 2012 3:19 PM by jbarry-esristaff

    LayerBeforeDraw Event Crahses Application

    CorkyShunk
      Using MOLT 2.0
      I have the Map_BeforeLayerDraw sub running code to determine if a layer should be visible per the Map extent. I wrote this 2+ years ago and it has worked fine. Now I have a user that crashes the app. It appeared to be occurring during the LayerBeforeDraw. When I run that app on all office PCs it functions fine. When I step through the sub it causes the app to crash on the 'Exit Sub' or 'End Sub' ine execution? I never stepped through this sub before. I wrote it and it worked fine.
      App is written in MS Access 97, 2002, 2003, 2007, 2010 and has always functioned fine.

      Closes / Crashes Access at the 'Exit sub' or 'End Sub' line when stepping through the sub in A97, 2003 or 2007 (haven't tried in 2010)

      Tried to debug with Visual Sudio and it gave me this:
      'Unhandled exception at 0x2832d7bb in MSACCESS.EXE: 0xC0000005: Access violation reading location 0x00000004.'


      Private Sub Map1_BeforeLayerDraw(ByVal Idex As Integer, ByVal hDC As Long)
      On Error GoTo err_Before

              Dim iVis As Integer
              Dim strNm As String
              Dim ctl As Control
              Dim ILayer As Object
             
              Set ILayer = Me!Map1.Layers(Idex)
              strNm = ILayer.Name
              iVis = Val(fLayerInfo(strNm, 9))
             
                  If iVis > 1 Then
                  '' Depending on the extent & 'MaxVis' setting determines if layer is drawn
                  If Me!Map1.Extent.Width < Me!Map1.FullExtent.Width / iVis Then
                      '' check if the layer is to be visible
                      Dim bVis As Boolean           
                      For Each ctl In Forms!frmGISMap!sfrmLayers.Form.Controls
                          If ctl.ControlType = acCheckBox And ctl.Tag = strNm Then
                              bVis = ctl.Value
                              Exit For
                          End If
                      Next ctl
                      If bVis Then ILayer.Visible = True
                  Else
                      ILayer.Visible = False
                  End If
            
              DoEvents
         
      Exit_err:
          If Not ILayer Is Nothing Then Set ILayer = Nothing
          Exit Sub '' CRASH OCCURS WHEN THE 'Exit Sub' FIRES, IF THE ERROR HANDLER IS COMMENTED OUT CRASHES ON 'End Sub'
      err_Before:
          MsgBox "'Map1_BeforeLayerDraw' - " & Err.Description
          'Debug.Print "'Map1_BeforeLayerDraw' - " & Err.Description
          On Error Resume Next
          Resume Exit_err

      End Sub


      Cork Shunk
      CS-Graphx
        • Re: LayerBeforeDraw Event Crahses Application
          jbarry-esristaff
          Without setting up a similar environment, I'm doing an eyeball run thru your code and came up with some comments.  Too bad VBA doesn't have the new Try-Catch-Finally pattern.  It would've let you make this code a lot cleaner.  Not saying that any or all of them are related to the problem, but figured I'd take an initial swing at it and see what you think:

          1.  Just want to make sure I understand part of what you're saying...  Is it true that when the routine runs at full-speed on your deployed machines it works perfectly fine?  The only time the error or crash occurs is when you're debugging on your dev machine line-by-line with the Step tool (F8)?

          2.  I can't find an "End If" to close out your condition "If iVis > 1 Then".  You said this code runs on your deployed machines, and used to debug without error.  Otherwise you should always be getting a run-time compile error.  Did you miss a line during your copy paste?  If so, where exactly was that "End If"?

          3.  You said the app crashes when you step-debug at the "Exit Sub" line.  I can see two different ways it could've gotten there.  A bit of a difference between the two.  Can you tell which one it was?  It either:

          a.  The code starts at the top and steps all of the way thru "Do Events", then past the "Exit_err:" line, then "Exit Sub", then crashes.
          OR...
          b.  Started at the top, stepped thru a bit, errored out at some point which bounced it down to "err_Before:", then hit the "Resume Exit_err" and continued there, then hits "Exit Sub" then crashes.

          4.  I'm not sure the purpose of the line "On Error Resume Next".  All that does is when it Resumes back to "Exit_err" it'll keep running if it hits an error.  But at that point the only thing it does is Nothing out ILayer if it exists. 

          5.  Just a tip.  These four lines:

          If bVis Then ILayer.Visible = True
          Else
          ILayer.Visible = False
          End If

          ...you can just do that in one:

          ILayer.Visible = bVis

          6.  Are you sure the line "DoEvents" needs to be in there?  Of course, I didn't run your code but I don't know if that's needed.

          7.  I doubt setting ILayer to Nothing is needed.  It's a local variable that is going to go out of scope in the next line anyway.

          8.  What is the value of "Idex" just before the app crashes?  Also what is the value of Me!Map1.Layers.Count?
          • Re: LayerBeforeDraw Event Crahses Application
            CorkyShunk
            Barry,

            Thank you for getting back to me. (sorry about the spelling 'Crahses').

            1. Just want to make sure I understand part of what you're saying... Is it true that when the routine runs at full-speed on your deployed machines it works perfectly fine? The only time the error or crash occurs is when you're debugging on your dev machine line-by-line with the Step tool (F8)?
            YES

            2. I can't find an "End If" to close out your condition "If iVis > 1 Then". You said this code runs on your deployed machines, and used to debug without error. Otherwise you should always be getting a run-time compile error. Did you miss a line during your copy paste? If so, where exactly was that "End If"?
            MISSED IT PASTING

            3. You said the app crashes when you step-debug at the "Exit Sub" line. I can see two different ways it could've gotten there. A bit of a difference between the two. Can you tell which one it was? It either:

            a. The code starts at the top and steps all of the way thru "Do Events", then past the "Exit_err:" line, then "Exit Sub", then crashes. YES
            OR...
            b. Started at the top, stepped thru a bit, errored out at some point which bounced it down to "err_Before:", then hit the "Resume Exit_err" and continued there, then hits "Exit Sub" then crashes. NO

            4. I'm not sure the purpose of the line "On Error Resume Next". All that does is when it Resumes back to "Exit_err" it'll keep running if it hits an error. But at that point the only thing it does is Nothing out ILayer if it exists.
            REMOVED

            5. Just a tip. These four lines:

            If bVis Then ILayer.Visible = True
            Else
            ILayer.Visible = False
            End If

            ...you can just do that in one:

            ILayer.Visible = bVis
            OK, MUCH BETTER

            6. Are you sure the line "DoEvents" needs to be in there? Of course, I didn't run your code but I don't know if that's needed.
            NOW REMOVED

            7. I doubt setting ILayer to Nothing is needed. It's a local variable that is going to go out of scope in the next line anyway.
            REMOVED

            8. What is the value of "Idex" just before the app crashes? Also what is the value of Me!Map1.Layers.Count?
            WHAT EVER LAYER PRIOR TO REDRAW


            Since I last posted I have revised the code but it still crashes. If it runs through without debugging it is fine. It also compiles and runs fine on other PCs...
            but if I step through it with F8 it crashes at the Exit Sub

            Private Sub Map1_BeforeLayerDraw(ByVal index As Integer, ByVal hDC As Long)
            On Error GoTo err_Before

                       Dim iVis As Variant
                       Dim strNm As String
                       Dim ctl As Control
                
                strNm = Me!Map1.Layers(index).Name
                       iVis = Val(fLayerInfo(strNm, 9))
                       If iVis > 1 Then
                              '' Depending on the extent & 'MaxVis' setting determines if layer is drawn
                              If Me!Map1.Extent.Width < Map1.FullExtent.Width / iVis Then!
                                     '' check if the layer is to be visible
                                     Dim bVis As Boolean
                                     For Each ctl In Forms!frmGISMap!sfrmLayers.Form.Controls
                                             If ctl.ControlType = acCheckBox Then
                                                    If ctl.Tag = strNm Then bVis = ctl.Value
                                             End If
                                     Next ctl
                                     If bVis Then Me!Map1.Layers(index).Visible = True
                             Else
                                     Me!Map1.Layers(index).Visible = False
                             End If
                      End If

            Exit_err:   
                  Exit Sub 'Crashes here
            err_Before:
                  'MsgBox "'Map1_BeforeLayerDraw' - " & Err.Description
                  Debug.Print "'Map1_BeforeLayerDraw' - " & Err.Description
                  On Error Resume Next
                  Resume Exit_err

            End Sub


            Cork Shunk
            CS-Graphx
            • Re: LayerBeforeDraw Event Crahses Application
              jbarry-esristaff
              I'm still not seeing anything that sticks out as to why the code crashes when you're in step-by-step debug mode.  I suppose in a way that sort of makes sense because if there was something wrong with the code, then it should also not work at runtime.  I made some additional adjustments to your code.  Nothing significant.  One part about setting the layer's visibility based on bVis, then the other is inside the For Each, when ctl.Tag = strNm, you set bVis to the ctl.Value.  At that point you can actually Exit the For.  (That is, assuming each layer has a unique name.)

              So, I wonder if it would be possible for you to create an .mdb that is portable, you could zip up and post here.  Something that doesn't necessarily use your actual data, but reproduces the problem.  That way I can test it here.

              Private Sub Map1_BeforeLayerDraw(ByVal index As Integer, ByVal hDC As Long)
              On Error GoTo err_Before
              
              Dim iVis As Variant
              Dim strNm As String
              Dim ctl As Control
              
              strNm = Me!Map1.Layers(index).Name
              iVis = Val(fLayerInfo(strNm, 9))
              If iVis > 1 Then
                '' Depending on the extent & 'MaxVis' setting determines if layer is drawn
                If Me!Map1.Extent.Width < Map1.FullExtent.Width / iVis Then!
                  '' check if the layer is to be visible
                  Dim bVis As Boolean
                  For Each ctl In Forms!frmGISMap!sfrmLayers.Form.Controls
                    If ctl.ControlType = acCheckBox Then
                      If ctl.Tag = strNm Then 
                        bVis = ctl.Value
                        Exit For
                      End If
                  Next ctl
                  Me!Map1.Layers(index).Visible= bVis
              End If
              
              Exit_err:
                Exit Sub 'Crashes here
              
              err_Before:
                'MsgBox "'Map1_BeforeLayerDraw' - " & Err.Description
                Debug.Print "'Map1_BeforeLayerDraw' - " & Err.Description
                On Error Resume Next
                Resume Exit_err
              
              End Sub
              
              
              • Re: LayerBeforeDraw Event Crahses Application
                CorkyShunk
                Jim,

                Sorry it took me so long to respond. I was very busy for awhile...
                Attached is very stripped down Access97 mdb w/ mapLT2.0 control. It does not seem to matter what version of Access it is in though.
                As soon as you try to walk through the BeforeLayerDraw event it crashes, even if you remove all the code in the event?

                Thanks again for trying to figure this out,

                Cork Shunk
                CS-Graphx
                • Re: LayerBeforeDraw Event Crahses Application
                  jbarry-esristaff
                  Ok thanks Cork, I'll take a look at it.
                  • Re: LayerBeforeDraw Event Crahses Application
                    CorkyShunk
                    Thanks for trying Jim.
                    I just converted it to A2K & tried it with Access2000, same result.
                    Works when run but crashes stepping through?
                    Same result with A97, 2K, 2002, 2003, 2007, 2010

                    Cork Shunk
                    CS-Graphx
                    • Re: LayerBeforeDraw Event Crahses Application
                      jbarry-esristaff
                      Ok, I got my hands on a copy of Access 2000.  I'll get it installed and check it out against the .mdb you posted here.
                      • Re: LayerBeforeDraw Event Crahses Application
                        CorkyShunk
                        Was anyone able to determine the problem with this issue?
                        • Re: LayerBeforeDraw Event Crahses Application
                          jbarry-esristaff
                          Was anyone able to determine the problem with this issue?


                          Sorry Corky, I think I dropped the ball on this one.  My apologies.  I still have your app and data and I have Access 2002 running on a WinXP VM.   I'll post back here asap.