Okay, I see ou solved it, but it's puzzling me why you try to simulate a scrollbar click when you actually need to trigger a mousemove event of a container. You can simulate a mouse move as you can do MOUSE AT x1,y1 DRAG TO x2,y2, that even triggers a mouse move if (x2,y2) = (x1,y1), so all you need is one coordinate in the container that's actuall causing this event on the container level (if you pick a coordinate that's on a control within the container, its MouseMove occurs.
Besides, there is RAISEVENT(), it's not perfect, but it's a bit better than just calling container.mousemove(). A bindevent that's configured to not react to direct method calls will react if you instead use RAISEEVENT, for example. And to ActiveX controls this should also look like an event occured and they'd react, too, or any related events also occcr.
Just to demo all this differences:
Code:
Clear
_screen.AddObject("mycontainer1","mycontainer")
_screen.mycontainer1.visible = .t.
@ 10,1 say '' && move to line 10, after the container.
? 'Mousemove method call:'
_screen.mycontainer1.mousemove(0,0,9,9)
? 'RaiseEvent:'
RaiseEvent(_screen.mycontainer1,"MouseMove",0,0,10,10)
? 'Mouse at 0,0 Drag to 1,1 then ',_screen.mycontainer1.height+20,5
Activate Screen
Mouse at 0,0 Drag to 1,1
Mouse at 1,1 Drag to _screen.mycontainer1.height+20,5 pixels
Define Class mycontainer as Container
Procedure init()
BindEvent(This,"MouseMove",This,"MouseMoveBindevent",1+2)
* where 2 means: Do not allow an event to be triggered with a simple method call
EndProc
Procedure MouseMove()
LPARAMETERS nButton, nShift, nXCoord, nYCoord
? "MouseMove", nButton, nShift, nXCoord, nYCoord
EndProc
Procedure MouseMoveBindevent()
LPARAMETERS nButton, nShift, nXCoord, nYCoord
AEvents(laEvents,0)
? "MoseMoveBindevent", nButton, nShift, nXCoord, nYCoord, laEvents[3] && see AEVENTS
EndProc
EndDefine
For sake of simplicity make the VFP window fullscreen in the main display (matters, if you have multiple displays), then run it. That should be output:
1. calling the mousemove event doesn't trigger the MouseMoveBindevent, therefore only the mousemove output is done.
2. Raisevent causes both the mousebindevent and mousemove. Also, notice the 1 at the end of the output of MouseMoveBindevent, that means you can detect this event was caused by VFPs RaiseEvent function.
3. Mouse at...drag to also causes both the bindevent and the mousemove event. Here the last number 0 means it's detected as a system event. The MOUSE command actually causes the system mouse to move and that in turn means it's detected as system event.
In some cases I also get further events happening, also with the coordinates the mouse as previously to putting it to 0,0 but I don't get that reproducible. The two drag operations should at least cause two events at 0,0 and 1,1, the two starting points, but maybe it's a timing issue and too fastly occurring events are sometimes not forwarded or ignored. The final coordinates 95,5 mean the _screen (x,y) coordinates (5,95) and are picked outside the container (if VFP is fullscreen in the main display), so moving the mouse after running this code doesn't obliterate the screen with event output, but you can, of course, move the mouse to the container and will see output from that.
Both raisevent and actually causing the event by the MOUSE command also trigger the actual event. So the bound event, which is configured to not react to direct message calls, reacts, too. You can always also trigger events, even in case there is no such command as the MOUSE command by sending the Windows messages that cause these events, for example, WM_KEYDOWN and WMKEYUP to simulate a keyboard press of a key. There are limitations about which events you can raise in other processes, but within your own windows (forms) it would always be possible to get something like that going, in case you really need it.
When you realize you actually only have display update problems, then the most rigorous thing you can do to cause a complete repaint also is form.Cls(), but it's sensible to only use the least, which is control.setfocus() to the control that should update its own display, followed by control.refresh() and then also the full form.refresh() and form.cls() at the top of it all. You could even also cause the repaint of a rectangle within the form via Windows API:
Just look around a bit more next time, there are so many options you overlooked.
Chriss