Link to home
Start Free TrialLog in
Avatar of jlsyst
jlsyst

asked on

Keyboard activity - espec: <ESC> Interrupts module processing in Access Runtime 2007

I have a strange problem that I would love some help with.  As a background, the code base I am referring to here is a commercial database distributed under Access Runtime 2003 for a number of years now without issue.

Upon converting this application to Access Runtime 2007 and distributing it, the code all apparently works well except that I am seeing some strange behavior, specifically, that if you hit the <ESC> key on the keyboard at any time when some module code is running (e.g. when saving an order or adding a contact in my application) then Access immediately stops what it is doing in the background and indicates that the User has canceled the operation (error #3059).

My application has worked for many years on prior versions of Access where keyboard activity during code execution would not interrupt what was going on in the background.  This is particularly likely to happen with my users too since the <ESC> key is what closes a window in my app and many times people "type ahead" in order to have their windows close quickly so I need to figure this out!

Essentially as long as the user keeps his hands off the keyboard, all works well.  This was not a problem in Access 2003 and the code is the same so something must be different in the environment.  I have explored several options such as:

1) DoCmd.SetWarnings False when the application first opens (Result= no effect - msg came up regardless so this 3059 is apparently not considered a warning and is more of an error)

2) Using the AutoKeys macro to intercept the {ESC} key (Result= wasn't allowed.  Apparently only a subset of the SendKeys character set can be used in this macro and the {ESC} key is not one of them)

3) Trying to suppress the error using the OnError function in the forms (Result=no effect - msg would come up without being trapped)

My questions:
*Can anyone help me understand why this is different from the 2003 environment?
*Is there a way to disable the keyboard during code exec?
* Is there a later version of the Access 2007 Runtime?  I am using version 12.0.6237.1003 which I believe incorporated the post SP1 fixes but I am not sure.
*Any other ideas on what I can do?!

Thanks in advance
Jerry
Avatar of MikeToole
MikeToole
Flag of United Kingdom of Great Britain and Northern Ireland image

Turn on Key Preview for your form - it's at the bottom of the Events list - then add a handler for the Key Down event that sets the KeyCode to 0 when Escape is pressed and you don't want it to have any effect. In this example I added a Checkbox to the form to toggle between normal behaviour and Escape supression:
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = vbKeyEscape Then
        If Not Me.chkEnableEscape Then
            KeyCode = 0
            MsgBox "There is no escape..."
        End If
    End If
End Sub
If you can reproduce the problem on a new very small database Then
----- Attach it here, to look at

Avatar of jlsyst
jlsyst

ASKER

I appreciate your response Mike.  The key preview may work but there's only one problem with the solution and that is as it pertains to the application flow.  Specifically, I need the users to be able to hit <ESC> in order to close the form.  In the Access 2003 version of the same code, the user can hit the <ESC> key while the form was processing it's magic and the system would wait (a few milliseconds mind you) to finish what it was doing and then apply their input to the UI (closing the form) and not take the keyboard entry as some sort of signal to stop what it was processing.

That is the fine line I am trying to get to  and I know it is possible as that worked in every version of Access Runtime since Access 97.  So disabling the key and "retraining" my users may be something I eventually resort to but I'd like the ability to keep the <ESC> key active.

Additionally, some of the code that gets interrupted sits out in modules that are not specific to the form.  Would dcaputring/disabling the key in the form carry over to code called in these modules from the forms module code?

I will try to get a small snippet together.  Any other ideas on what I have written here so far?
Thanks!
It will be interesting to look at the snippet
<Additionally, some of the code that gets interrupted sits out in modules that are not specific to the form.  Would dcaputring/disabling the key in the form carry over to code called in these modules from the forms module code?>
While the form has the focus it will intercept and check the keystrokes, the modules in the background have no awareness of them.
Avatar of jlsyst

ASKER

Thanks - I will try to extract a couple of forms and send to see if I can show the issue in action without muddling it with the surrounding code.  This is  quite a large app but I believe I can reproduce the problem using a small sample.  I will work on that and attach it here later today ...stay tuned!
Avatar of jlsyst

ASKER

Hi again.  Ok, I pared down the database to just 3 basic forms (see attached).

Main - click on the button to open...
Contact Manager  click on the button to open...
New Contact

I left the New Contact Form close to the original GUI in order to have some code running to be interrupted by the <ESC> key.  When I tried having pared down forms the problem did not manifest, but when there is code running in the background such as a check for unsaved data, the operation indicates that it was canceled by the user.

Understand that I have removed a lot of code and screen function but the problem still remains in this very simple code that has worked in all previous versions of Access Runtime.  

Steps to see what I am talking about:

1) Open the Main form and click on the single pushbutton on there (Contact Manager) to open yet another form (again this is a pared down version of the code)
2) Click on Add New Contact to open the next form
3) Hit <ESC> and the screen should close without issue.  This is typical screen flow.

Now try steps 1-3 again except populate a few fields such as name prefix, first name, address, last name and then put your focus in the Name Prefix field and hit <ESC> a couple of times very quickly and see if you get the msg that you have canceled the operation (I believe because the check for unsaved data has been invoked prior to closing the form and you are now interrupting it).  In preious runtime verions, this code would finish and then the <ESC> character would be interpreted and the layered screens would all close.  Note:  This error occurs about 7 in 10 times that I do the steps above in the snippet (happens 10 of 10 times in the real product) so try a few times if you don't see the error right away.

Hope this makes sense!!  I look forward to your next reply and a million thanks!

Jerry
Jerry,
I don't see an attachment...but then I'm done for the day, I'll pickup on it again tomorrow
Mike
Avatar of jlsyst

ASKER

Hi there - I see what happened on the attachment.  It is a zip file with a accdb (Access 2007) db.  The upload facility did not detect that accdb was a legal extension.  I have subsequently renamed the file to have a .mdb extension.  After unzipping, please immediately rename the file to have the original accdb extension before running it.  Thanks much for your help.  Type to you tomorrow.
Database-Snippet.zip
Not my area of expertise, but it looks like later versions of Access support a function called UNDO that is associated with the ESC key.

Perhaps if you can capture (and ignore) the UNDO event, then the normal uses of the ESC key could still be available.
Avatar of jlsyst

ASKER

Ok thanks for the suggestion - I will look at that too as I search for a solution and report back here what I find.  Thanks for the tip Dan.

Jerry
Avatar of jlsyst

ASKER

Ok I looked into that UNDO deal and it does not appear to be helpful here but thank you for trying on that one Dan.  What is frustrating here is I feel that I am coding around a Runtime Bug introduced in 2007 since this code worked in 3 previous runtimne editions.

I have attached a bitmap of the error as it appears when using the database that I attached earlier to help give everyone a visual to work with.
ESCError.bmp
ASKER CERTIFIED SOLUTION
Avatar of MikeToole
MikeToole
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
As an aside:
When I want to take the same action for an event on several different controls I usually put the event handling in a Class module.
The snippet shows the code for a class that cancels the Keycode and raises an event when it detects the Escape Key in the KeyDown event.
To use it in a form...
' Declare the class as a form level, I called the class module CEscapeKeyHandler
Private WithEvents clsEscapeKeyHandler As CEscapeKeyHandler
' Instantiate it when the form opens
Private Sub Form_Open(Cancel As Integer)
    Set clsEscapeKeyHandler = New CEscapeKeyHandler
    ' rest of the form_open code ...
End Sub
' Handle the Event it raises
Private Sub clsEscapeKeyHandler_EscapeKeyPressed()
    Pb_Reset.SetFocus
    CloseCurrForm
End Sub
' Then you only need a single line of code in the Enter event of any control that you want to work this way
Private Sub Ef_Name_Pfx_Enter()
    Set clsEscapeKeyHandler.TextBox = Screen.ActiveControl
End Sub

Event EscapeKeyPressed()
Private WithEvents mTextBox As TextBox
 
Public Property Set TextBox(Value As TextBox)
    Set mTextBox = Value
    mTextBox.OnKeyDown = "[Event Procedure]"
End Property
 
Private Sub mTextBox_KeyDown(KeyCode As Integer, Shift As Integer)
   If KeyCode = vbKeyEscape Then
      KeyCode = 0
      RaiseEvent EscapeKeyPressed
   End If
End Sub

Open in new window

Avatar of jlsyst

ASKER

Thank you Mike!!  I believe that was the ticket.  Your comment regarding "Events can have multiple handlers, each one is just called in turn. You've coded a specific handler for the KeyDown event, but any built-in handling for the Escape key will also happen. You can stop that by setting the Keycode to 0 when you're processing it yourself " was the key.

I have simply added a statement:
KeyCode = 0   'helps prevent interruption of module code running by masking the fact that {ESC} was hit

...be calls to CloseCurrForm and it appears to have taken care of the issue in some places.  Now the trick will be to proagate to the hundreds of forms in the actual app - what a pain to get around this runtime bug.

Many thanks again!!
Avatar of jlsyst

ASKER

Very pleased with the input - thanks.  Still proving it out but appears to be what will help me past the problem.  Still unclear if Microsoft will address.