Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
DOEVENTS - Absolute position of mouse
Message
Information générale
Forum:
Visual FoxPro
Catégorie:
Codage, syntaxe et commandes
Divers
Thread ID:
00155157
Message ID:
00155520
Vues:
58
George,

First let me say I wish MS would fix doevents. It fundamentally sucks the way it is. And the code presented here and in FastDoEvents() is the worst possible kludge, but heck it works. *LOL*

I just created a form, put a checkbox on it. With this IAC method:
* check1
do while this.Value
   with thisform
      .CurrentX = 0
      .CurrentY = this.Top
      .Print( str( seconds(), 10, 3 ) )
   endwith
   doevents
enddo
While the form is running and the checkbox is clicked the screen updates fairly fast while the mouse is moving anywhere within the confines of the VFP _screen. If I switch to the browser to type this reply, or stop moving the mouse in the vfp window it goes back to it's leisurely update pace. It's also worth noting that the VFP window does not need to have focus, if the mouse moves over it while I'm in the browser it runs fast. So VFP seems concerned about the mouse anytime the rodent is in a position to do something to VFP.

Then I got to thinking what other events could shake up doevents. Keypresses? So I did a second checkbox.
* check2
do while this.Value
   with thisform
      .CurrentX = 0
      .CurrentY = this.Top
      .Print( str( seconds(), 10, 3 ) )
   endwith
   keyboard " "
   =inkey()
   doevents
enddo
It flies! I'm not exactly sure why though. Because the inkey() should immediately clear the keypress from the event queue before the doevents is executed so there shouldn't be any events queued???

It's a rather nasty thing though if you are actually doing keyboard input in the form. It also causes a fair amount of cursor and mouse flicker while the mouse is over the form. But it is effective while the VFP app does not have focus. I tried playing with the arguments for inkey and found that it caused the keyboarded value to uncheck the checkbox sometimes. So evidently the inkey() didn't eat the keystroke. I've reported that bug. If there is a textbox on the form and it has focus while the checkbox is "running" it can sometimes freeze the loop when the textbox is empty, but that might just be a side effect of being inside the loop in the IAC method while actually inputting into the other control. Normally this doevents code would be doen from a short lived method like a timer.Timer() event.

I tried just a chrsaw() that doesn't speed up doevents.

>Assume you've got a command button that's responds to a keypress (a hot key, if you will). Assume further, that user intiates the action with the key and the mouse is outside the window (imagine a small SDI form launched from a short cut on the desk). Now you've a situation where the user would care how long VFP takes.

>I've been working with an OLE automation server (which is slow by itself). It's sending me an unknown number of records, so to let the user know that it was working, I added a spinning disk and threw in a DoEvents so that it would work. Of course, the DoEvents slowed the thing down by more than a factor of 20. While the spinning disk was nice, the performance was unacceptable. That's why I got interested in your solution.


I think it's still prudent to limit the number of doevents in a tight loop. If you do it once every 100 or 1000 iterations you are still better off. In the app where this was critical for me I've got a machine status display. 96 machines each one equals 6 objects on the form. It takes about 2 seconds to update the form every 10 seconds. During the refresh I was missing mouse clicks. So I seeded doevents into the Refresh() of 4 of the machine objects, that minimized the number of missed clicks and before fastdoevents slowed down the total refresh time to about 4 seconds.

>I guess what one could do to work around the "user working in another app" problem would be to make a call to the API to GetForegroundWindow (off the top of my head, but it might be better to use GetActiveWindow), to determine if the VFP app was active, and make sure the mouse was in proper position if it was.

I guess with the keyboard alternative, we could change FastDoEvents to:
* FastDoEvents.prg 30-Sep-98

* 07-Nov-98 added keyboard for when mouse is out of VFP

* this workaround speeds up a DoEvent call

local lnRow, lnCol, lcWindow

lcWindow = wontop()
lnRow = mrow( lcWindow )
lnCol = mcol( lcWindow )
if ( lnRow > 0 ) and ( lnCol > 0 )
   * mouse still within VFP window, so it's ok to mouse
   mouse at mrow(), mcol() window (lcWindow)
else
   * mouse not in VFP window, use a fake keypress event instead
   keyboard " "
   =inkey()
endif

DoEvents
It does seem to make the mouse sluggish while in the browser though. But that might just be because of the high processor load of the tight IAC loop. Sysmon reported about 30-35% CPU utilization while it was running. That's about twice as much as it shows while just moving the mouse around inside any window while nothing is running.

I guess we could get the WinAPI involved if needed.
df (was a 10 time MVP)

df FoxPro website
FoxPro Wiki site online, editable knowledgebase
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform