OLE drag and drop
When we first learned that VFP 6 would support OLE drag and drop, we thought, "That's nice. Now we'll be able to drag between ActiveX controls and native controls." Then we realized it applied to the development environment, too, and that we'd be able to drag from VFP to Word or drag files from Explorer into the Project Manager or the Command Window. Even better, but still nothing to write home about.Then we started to actually play with the programmatic elements of OLE drag and drop. The farther we went, the closer our jaws got to the floor. This is cool stuff!OLE drag and drop is, of course, not just a VFP thing. This is the model used throughout Windows to allow applications to share data through drag and drop. So what we use in VFP to move data from a calendar control to a text box is the same set of PEMs that the Windows programmers use to move files from one directory to another, or that Word and Excel use to drag data from one application to the other.The design of OLE drag and drop is truly elegant. It involves three objects, each with a job to do, and each with the appropriate tools to do it.The first two objects are fairly obvious. First, there's the drag source, the control or application from which the data is being dragged. Second, there's the drop target, the control or application onto which the data might be dropped. So far, so good, but what's the third? The third is a COM object called the data object. It contains the data from the drag source in various formats, and makes that data available to the drop target upon request.In VFP's native drag and drop, responsibilities are partitioned between the drag source and the drop target. The drag source starts things off and specifies the icon to be used; the drop target responds to the drag in a couple of events. But that's all there is.OLE drag and drop is much more complex, but that complexity gives you much more control. With OLE drag and drop, it's possible that either the drag source or the drop target belongs to another application and thus isn't accessible to you programmatically. For example, if you drag files into VFP from Explorer, VFP owns only the drop target, not the drag source.To deal with this, both the drag source and the drop target have a chance to respond every step of the way. For example, whenever the drop target's OLEDragOver event fires, indicating that data is passing over the object, it also fires the drag source's OLEGiveFeedback event, so the drag source can decide whether or not it likes the drop target and behave accordingly. Even if the drop target is outside VFP, a VFP drag source's OLEGiveFeedback event fires. Similarly, when the drag source comes from outside VFP, a VFP drop target's events fire as expected. This table shows the order of events when both participants are VFP objects; when one of them is an outsider, you won't see all the events fire. OLEDragOver and OLEGiveFeedback fire repeatedly. The form DragDropSample.SCX in the Developer Downloads available at www.hentzenwerke.com shows the firing sequence as you drag and drop data.
Event |
Object |
MouseDown |
Drag source |
OLEStartDrag |
Drag source |
OLEDragOver |
Drop target (which may be the drag source itself, if OLEDropMode is enabled) |
OLEGiveFeedback |
Drag source |
OLEDragDrop |
Drop target |
OLESetData |
Drag source |
OLECompleteDrag |
Drag source |
Debugging OLE drag and drop sequences is incredibly difficult. It's almost impossible to get to the debugger when an error occurs, and you can't set breakpoints successfully or use SUSPEND in the OLE drag and drop events. (If you try, you get the error "CANCEL or SUSPEND is not allowed" and, if that's not bad enough, the error dialog has Cancel, Suspend, Ignore and Help buttons.) In addition, you can put the data object in the Watch window, but you can't actually find out anything about it. We do understand what the problem is here. As soon as you're in the debugger, your drag and drop operation ends, so you're not in the relevant method anymore and the data object no longer exists. Rather than deal with that issue, you simply can't stop there. We've had some success using DEBUGOUT and WAIT WINDOW statements and the Event Tracker from OLE drag and drop methods to see what's going on, but it's certainly much harder than normal debugging. |