Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

KeyDown and Keyup versus Keypress 2

Status
Not open for further replies.

JackTheC

Programmer
Feb 25, 2002
324
NL
I want to control an IP Camera from within a VFP Form.

I have several arrow images on the form with mousedown and mouseup events. e.g.

MouseDown
thisform.olecontrol1.DecoderControl(6) && keeps moving the camera to the left until......

MouseUp
thisform.olecontrol1.DecoderControl(1) && stops moving the camera, triggered by the mousedown event.

-----------------

I want to do the same with the arrow keys on the keyboard. But there is no KeyDown and KeyUp event.
I use KeyPreview=.t. so the form intercepts the keypress. I can start moving the camera, but all subsequent keypresses are built up in the buffer. I can clear the buffer with clear typeahead, but this won't work properly. I have to release and press again. I want to move for as long as the key is pressed...

Code:
KeyPress event
if nkeycode=19 
	thisform.olecontrol1.DecoderControl(6)
	sleep(1000)  && move for 1 second, sleep declared earlier
	thisform.olecontrol1.DecoderControl(1)
	nodefault
        clear typeahead
endif
Question: How to simulate KeyDown and KeyUp, like the Mouse events?
 
<< I want to move for as long as the key is pressed...>>

I don't think you can do that with an OLE control. As you have found, the keydown events will be buffered (by Windows, not VFP), and (as far as I know) there is no way of dealing with that in VFP.

But I wonder if this is really what you want. If you want to let the user move the control by means of the keyboard, can you not simply use the Keypress instead? It's true that this will mean that the user has to keep on pressing the key, rather than holding it down, but that's more in line with normal Windows behaviour. Off-hand, I can't think of any Windows function or application that relies on a key being pressed continuously.

If you agree, then you would just need to write code in the Keypress event to test for the key being pressed. If it's an arrow key, you would then move the control accordingly.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike thanks,

But take scrolling on a page for instance. Scrolling happens for as long as arrow down is pressed. Many, many functions in Windows operate as long as a key is pressed and stops when released. That is the normal behaviour imho, not press, press, press, press.

I don't have to use a KeyDown in an OleControl, that's beside the point. I use KeyPreview, so I would need a KeyDown in the form. The Olecontrol is just an example of what i want to do with the keys. But there is no, not anywhere, a KeyDown or KeyUp event in VFP. In Visual Basic on the other hand, there these events do exist (KeyDown, KeyUp, KeyPress). But not in VFP alas. So i'm looking for a smart way to simulate this.

 
You can use BindEvent to bind to Windows events, too, mainly react to events WM_KEYDOWN and WM_KEYUP.

Bye, Olaf.
 
I think I got it.

In the main program:
Code:
Declare integer GetKeyState in user32 Integer

In the form with KeyPreview=.T.
Code:
[b]KeyPress event[/b]
if nkeycode=4 && right arrow key pressed
   nodefault  && no normal key movement around the form
   if getkeystate(39)< -126  && check if right key is down
         thisform.olecontrol1.DecoderControl(4)   && start moving the camera, it keeps moving until stopped.
   endif
   do while getkeystate(39)< -126    && check as long as the right key is down
   enddo
   thisform.olecontrol1.DecoderControl(1)   && stop camera from moving
endif

if nkeycode=19   && left arrow key
   nodefault
   if getkeystate(37)< -126    && check left arrow key is down
         thisform.olecontrol1.DecoderControl(6)
   endif
   do while getkeystate(37)< -126   && still down?
   enddo
   thisform.olecontrol1.DecoderControl(1)
endif

This works great. I have to check each key two times because the buffer fills with unnecessary keypressing and clear typeahead slows the proces down. So the first getkeystate checks if it is a first key time pressed or unwanted buffered keys.

 
B.t.w. The GetKeyState returns sometimes -127 and sometimes-128 when down en 0 or 1 when up. That is the reason i check for < -126

You can test this without a camera by replacing the olecontrol lines with
Thisform.backcolor=rand()*255*255*255 && instead of start moving the camera you'll see the form color changing each first time
and
Thisform.backcolor=0 && camera stop, form becomes black




 
And GetKeyState(40) for Arrow Down and GetKeyState(38) for Arrow Up.
Just in case someone in the future needs a KeyDown or KeyUp event.
 
I'd prefer BindEvents in conjunction with a keyhandler class with the keydown and keyup events, but thanks anyway.

Bye, Olaf.
 
I didn't use BindEvents because:
A. I don't understand it yet. It looks quite difficult.
B. It is not available in all versions of VFP.
 
A. There are examples in the solutions app
B. Yes, only VFP9, but is that an important restriction? If you have VFP9 you can use it.

You don't have to change, as you already have found a solution, no need to change. BindEvents just enables you more general to bind to all kind of events of OS, devices, etc, you don't depend on events of the VFP object model or language.

GetKeyState is a very specific solution to your problem and that's also very fine.

Bye, Olaf.
 
Thanks Tamar, that's quite a document.

I've tested a bit with Bindevent. It's not that difficult and it seems to work too:

A. I created two Methods in a Testform: KeyDown and KeyUp
B. In the Init of the Testform:

Code:
public moves
moves=0

=bindevent(0,256,this,'KeyDown')   && 256 = KeyDown
=bindevent(0,257,this,'KeyUp')     && 257 = KeyUp

See for the codes (from Tamar document)

C. In the KeyDown Method
Code:
lparameters aa,bb,cc,dd

if moves=0
	moves=1
	? 'Down key',cc,' and '
endif

D. In the KeyUp Method
Code:
lparameters aa,bb,cc,dd

?? 'Stop key',cc
moves=0

If a (arrow) key is pressed and released, this will appear on the form:
Down Key 39 and Stop Key 39
Down Key 37 and Stop Key 37

Because KeyDown keeps firing, I introduced a moves flag so the ? routine is only printed once.
 
>Because KeyDown keeps firing
That depends on a setting about auto repeat of keys.

Your lparameters should be lparameters hWnd, Msg, wParam, lParam, that'll make it easier to talk about standard parameter values and meanings and read MSDN documentation about events.
In case of WM_KEYDOWN (256) the lParam bit 30 of lParam is giving you the previous state, eg if it's 1 the key was already down and you can disregard this event, you don't need your own flag for that.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top