On Dec 30, 2005, at 6:11 PM, Charles Yeomans wrote:
I'm seeing a curious problem in the interaction of a KeyDown event
handler and Valentina. I have an EditField that holds a date. When
the date is changed, I retrieve some data from the database and load
it into a Listbox. The + and - minus keys increment and decrement the
date, and so trigger the database search.
The immediate problem is that when I type several + or - quickly, my
application crashes silently. Vigorous logging shows that a call is
made to Valentina's SQLSelect function before the previous one has
returned, which I suspect is causing Valentina to crash. This happens
because the EditField.KeyDown event handler is being called in
response to a key press before the previous KeyDown event handler has
exited; the log data suggests that REALbasic is calling the next
KeyDown while Valentina is in the middle of its SQLSelect call.
I wonder how this can happen. I guess that somehow a cycle of the
event loop is occurring while Valentina is executing an SQLSelect ot
something; I am most perplexed. This only occurs when connecting to a
remote database; I don't know if Valentina is just so much faster
locally that no timing problem occurs, or if there is something more
fundamentally different.
I assume you already have a workaround, but just in case you don't...
Make a subclass of your EditField that has the following:
::Properties::
Protected Property fKeyStillPressed As Boolean
Protected Property fKeypressTimer As KeyPressTimer
::Methods::
Public Sub KeyTimer(o As KeyPressTimer)
fKeyPressTimer = o
End Sub
Public Sub ClearKeyFlag()
fKeyStillPressed = False
End If
Now, in your KeyDown() event, protect it with
Public Function KeyDown(Key As String)
If (Not fKeyStillPressed) Then
// Your handler code here
fKeyStillPressed = True'
fKeyPressTimer.Period = 10 // Experiment here...
fKeypressTimer.Mode = 1
End If
End Sub
Then, create a new Timer subclass, KeyPressTimer:
::Properties::
Protected fEditFieldSocket As EditField // <- Replace with the name of
the custom EditField subclass!
::Methods::
<none>
Put in its Action() event:
Public Sub Action()
fEditFieldSocket.ClearKeyFlag()
End Sub
This will form the software equivalent of a hardware circuit called a
'missing-pulse' detector (usu. implemented with a 555 timer... :) Maybe
I should have called the Timer subclass 'FiveFiveFiveTimer' instead,
no?) Though, in this case, I should call it a 'missing-keypress'
detector instead.
Don't forget to 'connect' the EditField subclass and the
KeyPressTimer through the EditField's 'KeyTimer()' method, or it won't
do much at all... (after the first keypress, anyway) :O
Of course, you could have the EditField instantiate the KeyPressTimer
itself instead, or just put both on the same window. Personally, if I
were doing it, I'd try to make the 'system' as self-contained (and OO)
as possible by making the EditField subclass instantiate the timer.
Also, note that the period of the timer should be >= the time it
takes to make the database call.
--------------
Charles Yeomans
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>
Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>
William H Squires Jr
4400 Horizon Hill #4006
San Antonio, TX 78229
wsquires at satx dot rr dot com dot nospam <- remove the .nospam
_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>
Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>
|