Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.
As their names suggest, these two events fire when data is dragged over an object or dropped onto an object, using OLE Drag and Drop
. They give you a chance to respond programmatically to the drag or the drop.
PROCEDURE oObject.OLEDragOver
LPARAMETERS oDataObject, nEffect, nButton,
nShift, nXCoord, nYCoord, nState
PROCEDURE oObject.OLEDragDrop
LPARAMETERS oDataObject, nEffect, nButton,
nShift, nXCoord, nYCoord
Parameter |
Value |
Meaning |
oDataObject |
Object |
A reference to a DataObject containing the data being dragged and information about it. |
nEffect (all applicable values are added together) |
0 |
This target won't accept this drop. |
1 |
The drop results in a copy. |
|
2 |
The drop results in a move. |
|
4 |
The drop copies the dropped data into the target and creates a link between the original source and the target. Because of VFP's caching of resources, this isn't useful for drop targets in VFP. |
|
nButton (all applicable values are added together) |
1 |
The left button was used for the drag. |
2 |
The right button was used for the drag. |
|
4 |
The middle button was used for the drag. |
|
nShift (all applicable values are added together) |
1 |
The Shift key was held down. |
2 |
The Ctrl key was held down. |
|
4 |
The Alt key was held down. |
|
nXCoord, nYCoord |
Numeric |
The mouse position in pixels, relative to the form, when the event fired. |
nState |
0 |
The mouse is entering the object. |
1 |
The mouse is leaving the object. |
|
2 |
The mouse is inside the object. |
First, we think some of the parameter names are less than illuminating. We’d use nTargetReaction rather than nEffect, nModifierKeys rather than nShift, and nWhereAreWe instead of nState. However, since the parameter declarations are automatically placed in the methods, we show the official names in the table.
These events belong to the drop target in OLE Drag and Drop
. That is, they fire for the object under the mouse to indicate that the user is either dragging something over the object (OLEDragOver) or attempting to drop something into the object (OLEDragDrop). The drag source has events that fire right after these: OLEGiveFeedback fires after OLEDragOver, while OLECompleteDrag fires after OLEDragDrop. However, if either the source or the target is not a VFP object, you don’t have access to one set or the other of these methods.
These events fire only for objects whose OLEDropMode is set to 1-Enabled. If OLEDropMode is set to 2-Pass to Container, the container’s OLEDragOver and OLEDragDrop events fire instead.
Several of the parameters are bit-math things. The value you see is the sum of all the choices that apply. So, for example, if the user holds down Shift and Alt, nModifierKeys contains 5.
Both nButton and nShift are unreliable when nState is 1; that is, when the mouse is leaving the object. Sometimes they contain the right value, but often they contain 0. |
Some ActiveX controls don't fire these events, while others do. We can't blame this on the VFP team, of course, since they didn't write these controls. Bottom line here is that you need to test whether the control you're using pays attention. The simplest way to do so is to put WAIT WINDOW PROGRAM() NOWAIT in each of the relevant events on a test form and run it. We'd rather recommend DEBUGOUT, but we haven't found it to be reliable even in the controls that do fire these events. Sometimes we see a WAIT WINDOW when a DEBUGOUT in the same method produces no results. Frankly, we think the problem is with the controls, not with VFP, because some controls handle DEBUGOUT just fine. |
So, what is it you use these events for? To take action based on the user’s movements. You can inquire as to whether the data being dragged is available in a format this object can accept and set the target’s properties accordingly. You can also reject a drop if you don’t like its looks.
For OLEDragDrop, there are various default behaviors based on the objects involved and the buttons pressed. For example, dragging text from a text box to an edit box moves the highlighted text normally, but copies it if Ctrl is pressed.
You can change the results by writing appropriate code involving the DataObject’s GetFormat and GetData methods, as well as, perhaps, checking the nButton and nShift values. However, the default behavior still occurs at the end of the method unless you also include NODEFAULT. In addition, the drag source’s OLECompleteDrag is called at the end of OLEDragDrop. It receives as parameters the current value of nEffect, so if you do something different from what was indicated by the value received, you should give nEffect a new, appropriate value, so OLECompleteDrag can respond correctly.
* You might put this code in a form's DragOver event
* to allow it to accept data passed from one of its controls
IF oDataObject.GetFormat(1)
This.OleDropHasData = 1
This.OLEDropEffects = 1
ENDIF
* Suppose I want a drop into an edit box to copy rather than
* move, despite the default. This code could go in OLEDragDrop
nEffect = 1 && reset nEffect so OLECompleteDrag knows the score
This.Value = oDataObject.GetData(1) && copy the data
NODEFAULT && prevent the default behavior
DataObject, GetData, GetFormat, NoDefault, OLE drag and drop, OLECompleteDrag, OLEDrag, OLEDropEffects, OLEDropHasData, OLEDropMode, OLEGiveFeedback, OLEStartDrag