| Methods Index |
CMouseHandlerSubclass:
CAttachment, CViewSource
CDragSource is a mouse handler used to implement "drag-and-drop" behavior.
CDragSource handles mouse events and converts them into drag-and-drop events propagated to zero or more CDragSinks. CDragSinks are objects representing an area on the screen that can receive drag-and-drop events.
CDragSource and CDragSink have a many-to-many association: a source can service zero or more sinks, and a sink can be registered with zero or more sources. This association is automatically managed: destruction of a sink automatically unregisters it with a source. In addition, destruction of a source unregisters all of its sinks and destroys those not registered with another drag source.As a mouse handler,
CDragSource ignores all events until it enters a drag-and-drop mode. It is up to the owner of the drag source to start the drag-and-drop mode by calling DoDrag(). Upon receiving this call, CDragSource starts managing mouse events by translating them into drag-and-drop events for the registered sinks. The drag-and-drop mode is automatically ended when CDragSource receives a mouse-up event.For each drag-and-drop event,
CDragSource searches its list of registered sinks for an appropriate target. The order of the search depends on the OrderPolicy of the CDragSource. When the policy is STATIC (the default), sinks are searched in the order of registration. When the order is DYNAMIC, the sinks are searched in the order defined by virtual method ShuffleSinks(). CDragSource's implementation of this method (which you may override) is to order sinks according to their window stacking order.For an example of a
CDragSource implementation which automatically enters drag-and-drop mode, see the CViewSink class.The following example shows common usage of this class:
// Instantiate CDragSourceNone
itsDragSource = new CDragSource();
...
// Register drag sinks with the drag source
CDragSink *aSinkOne;
CDragSink *aSinkTwo;
CDragSink *aSinkThree;
...
itsDragSource->RegisterSink(aSinkOne);
itsDragSource->RegisterSink(aSinkTwo);
itsDragSource->RegisterSink(aSinkThree, FALSE);
// FALSE as the 2nd argument for RegisterSink causes the
// drag sink being registered to be "behind" the previously
// registered drag sinks. This means the newly registered
// drag sink be the last sink to be tested for IsInSink.
//
// The default behavior (or TRUE as the 2nd argument to
// RegisterSink) is to place the newly registered drag sink
// "on top of" the previously registered drag sinks. In
// other words, the newly registered drag sink will have
// IsInSink called on it before the previously registered
// drag sinks.
...
// Start the drag with some drag data (which will be passed
// to methods.
// Also, indicate the CWindow to trap the pointer to and
// the cursor to use for dragging.
itsDragSource->DoDrag(
someDragCommand, someDragData, aWindow,
CURSOR_CROSS);
// While dragging, the registered CDragSinks will receive
// notification of enter, leave, drag, and drop on a sink
// as follows:
//
// CDragSink::DoEnter() will be called
// for a particular drag sink every time the dragging item
// "enters" the sink. The term "enters" is defined by any
// time the CDragSink::IsInSink returns TRUE when it had
// previously returned FALSE.
...
// destroy the drag source
// note that this deletes all registered sinks which are not
// shared by another CDragSource
delete itsDragSource;
Public Data Members
CDragSource();
CDragSource(const CDragSource& theDragSource);
CMouseHandler constructor ensures the mouse handlers are registered with the same managers.
CDragSource& operator=(const CDragSource& theDragSource);
CMouseHandler assignment operator ensures the mouse handlers are registered with the same managers.
virtual ~CDragSource();
CDragSource which unregisters all of its sinks and destroys those not registered with another drag source.
virtual void RegisterSink(
CDragSink *theDragSink,
BOOLEAN isInFront =TRUE);
isInFront is TRUE, the new sink is registered in front of other sinks so that it can be consulted first. Sinks can be registered with more than one drag source, however, the CDragSource destructor automatically unregisters the sink and destroys it if it is not also registered elsewhere.
virtual void UnregisterSink(CDragSink *theDragSink);
CDragSource.
virtual void DoDrag(
long theDragCommand,
void* theDragData,
CWindow *theTrapWindow,
CURSOR theDragCursor = CURSOR_ARROW);
CDragSource ignores all events until it enters a drag-and-drop mode. It is up to the owner of the drag source to start the drag-and-drop mode by calling DoDrag(). Upon receiving this call, CDragSource starts managing mouse events by translating them into drag-and-drop events for the registered sinks. The drag-and-drop mode is automatically ended when CDragSource receives a mouse-up event. The method requires the following parameters:
void SetSinkOrder(OrderPolicy aPolicy);
OrderPolicy as an enumeration of orders in which sinks can be searched for drag-and-drop event notification:
For each drag-and-drop event,enum OrderPolicy// On each drag, visit sinks in the
order ... {
STATIC, // ... of registration
DYNAMIC // ... defined by virtual method
ShuffleSinks()
};
CDragSource searches its list of registered sinks for an appropriate target. The order of the search depends on the OrderPolicy of the CDragSource. When the policy is STATIC (the default), sinks are searched in the order of registration. When the order is DYNAMIC, the sinks are searched in the order defined by virtual method ShuffleSinks(). The CDragSource implementation of this method (which you may override) is to order sinks according to their window stacking order.Basically, you should call this method with a value of
DYNAMIC if you will be registering several sinks with the drag source, and each sink could be associated with a different window.
OrderPolicy GetSinkOrder() const;
virtual BOOLEAN DoUp(Overrides of
CPoint& theLocation,
short& theButton,
BOOLEAN& isShiftKey,
BOOLEAN& isControlKey); virtual BOOLEAN DoDown(
CPoint& theLocation,
short& theButton,
BOOLEAN& isShiftKey,
BOOLEAN& isControlKey); virtual BOOLEAN DoDouble(
CPoint& theLocation,
short& theButton,
BOOLEAN& isShiftKey,
BOOLEAN& isControlKey); virtual BOOLEAN DoMove(
CPoint& theLocation,
short& theButton,
BOOLEAN& isShiftKey,
BOOLEAN& isControlKey);
CMouseHandler mouse event methods. These methods iterate the registered sinks, calling CDragSink::IsInSink() for each, until one returns TRUE. At that point an appropriate drag-and-drop event is passed on to the sink.
virtual BOOLEAN UsesGlobalCoords(void);
TRUE.
virtual void ShuffleSinks(void);
itsSinkOrder is set to DYNAMIC (see SetSinkOrder() under "Public Methods"). This implementation reorders sinks according to window stack order and may be overridden to supply a different dynamic ordering criteria. The ordering implementation is done by ordering the sinks stored in the RWDlist member itsSinks.