?
Solved

OnKeyPress = "=somefunction()" how function can receive the key pressed?

Posted on 2006-10-22
7
Medium Priority
?
489 Views
Last Modified: 2008-02-01
The event procedure for OnKeyPress starts:
Private Sub xxx_KeyPress(KeyAscii As Integer).

However when I change it to a function call:
OnKeyPress = "=somefunction()"
there does not seem to be a way to send the KeyAscii value to the function. Is there some way for the function to get the key pressed?

Why do I want this? To avoid having to write lots of keypress event subroutines. I have code that scans a form when it opens for certain comboboxes, and sets them up in certain ways. The only place I'm stuck is handling keypress.
0
Comment
Question by:ramrom
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 10

Expert Comment

by:Luke Chung
ID: 17784940
It sounds like you're trying to do something outside the "natural" behavior of Access' event model.  Subverting the natural behavior of Access keystrokes is dangerous because people who are used to the behavior in other instances of Access may end up fighting your application.  But that could quickly get into a religious argument, so I'll refrain.

Unfortunately, if you want to handle the keystrokes, you're going to need to use the Event Procedure, and pass that to your function. Good luck.

Luke
0
 
LVL 11

Expert Comment

by:donaldmaloney
ID: 17784969
Is this what umean?

in form  text box?

Private Sub FIELDNAME_KeyPress(KeyAscii As Integer)
testfunction (KeyAscii)

End Sub


in modules


Public Function testfunction(key As Integer)
MsgBox key
End Function

don
0
 
LVL 17

Author Comment

by:ramrom
ID: 17785607
donaldmaloney: no. I want to avoid writing event procedures, and use a function instead.

LukeChung-FMS: I want my combo box to respond to ctrl-e. There is currently no action triggered by ctrl-e in combo boxes so I think I am safe.

Of course if I could intercept right click then I'd have no problem (I'd use that instead). But the only way to do that (again) is with a mouse event procedure, which I choose to avoid.
0
Nothing ever in the clear!

This technical paper will help you implement VMware’s VM encryption as well as implement Veeam encryption which together will achieve the nothing ever in the clear goal. If a bad guy steals VMs, backups or traffic they get nothing.

 
LVL 44

Accepted Solution

by:
Leigh Purvis earned 500 total points
ID: 17785619
<Warning - substantial post>
Hi ramrom - how goes it?
(I do like your questions ;-)

When you asked the question my first thought (apart from the point Luke raises - but you're an experienced developer, so I'm sure you'll be doing this for a good reason) was that you'll need to create a class (or two) to catch these keypresses.

First off - I'm assuming you really don't want to be making alterations to your existing functions.
For example sticking in a bunch of new code to whatever function calls might be going in to the Event properties - I'm assuming you want to avoid that.

So - back to the classes.
To successfully hook into a control's event - you'd need to have [Event Procedure] in the event property.
So - that kyboshes that one.
However the Form's keypress remains (hopefully!!) to be set to an [Event Procedure].
Is that a fair enough statement?
And if not - then is there a definite need for both control *and* form to have function calls in the keypress?  Could we live without one?

If the controls could be sacrificed then it's easier.
If not the we can still use the form - and I'll push on with that, as it's the more involved of the two (and you've mentioned controls specifically in your question).

A class which sinks the keypress event of the form.
Checks the current control of that form.
If it's one of the "certain comboboxes" then a class property makes available (through the parameter which it still receives) the ASCII character of the key that's just been pressed.
Of course the value needs to be retrieved by your functions somehow.
That could be simply by the form setting a public property of its own - or perhaps a global variable.

At a simple level - you could pass to the class a string delimited list of the controls which you're wanting to include (I assume they have some obvious identifier - perhaps a flag in the tag property or a common naming convention).
So they could always be enumerated at runtime - either in the code with which you pass the property to the class - or within the class itself once it has a form object to examine the controls of.

I'm sure this all sounds about as clear as mud.
Please feel free to post back why this wouldn't work (i.e. both keypress events are spoken for - which would be a shame) or if it's just not clear what I'm getting at.
And with more details too if you like - of how you identify the special combos for example.

I'll post here what I envisage the start of a class which should be enough to get back usable information.

Private WithEvents mfrmKey As Access.Form
Private mstrCtrlList As String
Private mintLastKey As Integer

Public Event BeenPressed()

Private Sub mfrmKey_KeyPress(KeyAscii As Integer)
   
    Dim strControl As String
   
    strControl = mfrmKey.ActiveControl.Name
    Debug.Print "In Class pressed " & KeyAscii & "  " & Chr(KeyAscii)
   
    'Check the current control is one we care about
    If InStr(1, mstrCtrlList, strControl) > 0 Then
        mintLastKey = KeyAscii
    Else
        mintLastKey = 0
    End If
   
    RaiseEvent BeenPressed
   
End Sub

Public Property Set CurFormKey(pfrm As Access.Form)
   
    Set mfrmKey = pfrm
   
End Property

Public Property Let ControlList(pstrList As String)

    mstrCtrlList = pstrList
   
End Property

Public Property Get LastKeyCode() As Integer

    LastKeyCode = mintLastKey
   
End Property



lol of course another possiblity could be to just use the control Keydown before the keypress to tell what would have been aquired.
(Or the form event more directly).
But why simplify matters when there's fun to be had.
I honestly don't think it would take long to set up.
And once done - it's done for use throughout... from then on. :-)
0
 
LVL 17

Author Comment

by:ramrom
ID: 17786088
Yep. That's the approach I took. Nice to have it confirmed. Let me expound.

I wrote a Sub OpenForm which amongst other things calls docmd.openform, and a class (FormHelper) which contains code similar to what you posted.

User requests for forms are sent to OpenForm.

OpenForm checks to see if the form has an instance of the FormHelper class, and if not, writes "Dim Helper as New FormHelper" to the declarations of the form's module. It also ensures that the form's OnKeyUp = "[event procedure]" and keypreview = True.

It loops thru the form's controls looking for those of type combobox that have a tag. The tag contains directives used to set the combo box properties.

FormHelper watches for KeyUp events, examines the ActiveControl.tag, and acts as needed.

FWIW OpenForm also checks to see if the form has a Sub reinit(), and if not, writes the code for it to the form's module.
Subsequently it calls this method, passing up to 6 arguments (which are at the end of the argument list for OpenForm).

This totally overcomes the limitations of openargs.

The place I ran into trouble was that subforms did not benefit from this passage thru openform, as they are opened automatically. So I lacked a way to apply the above technology to the subforms. So I was looking to function call instead of eventy procedure to help.

I now work around that by having openform visit the subforms and update them as well.

I sure do miss the ease I had in FoxPro of just subclassing combobox. Sigh.


0
 
LVL 44

Expert Comment

by:Leigh Purvis
ID: 17788870
So you're using Keyup events in your class - and hence are free to have an "[Event Procedure]" there?
So no need for a form object?
Or do you do so to keep it simple (i.e. watching for the keyup on that form - rather than any of the controls.)

Another option would be to have a couple of classes (parent and child) where the child holds a combo object and watches for the events of your very particular controls - and the parent maintains a collection of those classes.

If you were adding controls then I suppose whether a form was a main or subform - then if it added the controls to the class itself it wouldn't matter.

But it's just semantics now - you're up and running :-)


Not that I've ever used Foxpro (or are ever likely to now) - but how does it subclass combos in a widespread way?
i.e. All combos?  You could subclass the entire combo type class? (Rather than an individual control at a time?)
0
 
LVL 17

Author Comment

by:ramrom
ID: 17790867
In FoxPro one may:

DEFINE CLASS xxx AS combobox
  borderstyle = 1
  backcolor = 999
  PROCEDURE KeyPress(nKeyCode, nShiftAltCtrl)
    * code to act on KeyPress
  ENDPROC
ENDDEFINE

Then add any number of controls to forms based on this class.

One may then define other classes based on combobox, or on xxx (subclassing).

DEFINE CLASS yyy AS xxx
  caption = "Foo"
  backcolor = 9989
  PROCEDURE LostFocus()
    * code to act on LostFocus
  ENDPROC
ENDDEFINE

yyy "inherits" backstyle and KeyPress from xxx, creates some new things, and "overrides backcolor.

These definitions can also be made using a Visual Class Designer. Just like laying out a form! One may then drag-drop the visual class onto a form to create an instance of the class (control or whatever).
0

Featured Post

Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you need a simple but flexible process for maintaining an audit trail of who created, edited, or deleted data from a table, or multiple tables, and you can do all of your work from within a form, this simple Audit Log will work for you.
This article shows how to get a list of available printers for display in a drop-down list, and then to use the selected printer to print an Access report or a Word document filled with Access data, using different syntax as needed for working with …
In Microsoft Access, learn different ways of passing a string value within a string argument. Also learn what a “Type Mis-match” error is about.
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

719 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question