| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- Drag-and-Drop Support in wxWindows
- ==================================
- 1. Overview
- --------
- a) What is it?
- We're calling drag-and-drop (or d&d for short) the OLE mechanism of data
- transfer. Please note that it's not the same thing as the file oriented d&d
- of Windows 3.1 "File Manager" which is designed for and limited to the file
- names only.
- OLE d&d allows application to transfer data of any type to the same or
- another process.
- b) How is it done? (user's point of view)
- To start a d&d operation the user presses the mouse button 1 (left) and
- drags the selected object to another window (which must be at least partially
- visible on the screen) or to an icon on the taskbar in which case the
- corresponding window will be automatically restored. To finish the operation,
- the user releases the button. Default d&d operation is "move", but several key
- act as modifiers: keeping down the <Ctrl> key at the moment of drop does
- "copy", while <Shift> or <Alt> force the "move" (makes sense if default isn't
- "move").
- c) How is it done? (programmer's point of view)
- There are several objects participating in a d&d operation. First of all,
- there is the data object itself. Second, there is the drop source which is
- responsible for creating the data object (if it doesn't exist yet) and starting
- the d&d operation. Finally, the drop target receives the notification when
- the data is dropped onto the associated window (see below) and is responsible
- for pasting the data and returning the result code (copy, move or failure).
- There is one class for each one of these roles in wxWindows d&d implementation,
- plese see their descriptions below for details.
- 2. Drop Target
- -----------
- a) Being a drop target
- ... is as easy as deriving your window class from wxDropTarget and
- associating it with a wxWindow object (or perhaps some wxWindow-derived class,
- such as wxFrame). The pure virtual function wxDropTarget::OnDrop() must be
- implemented in your application and will be called whenever the mouse button
- is released over the window in question. Other virtual functions that will be
- called in the process of the d&d operation are OnEnter and OnLeave.
- @@ should OnDragOver() be user overridable also?
- You should associate wxDropTarget and wxWindow calling SetDropTarget:
- wxWindow *pWindow = GetTopWindow();
- pWindow->SetDropTarget(new MyDropTarget);
- The object created passed to SetDropTarget becomes the propriety of wxWindow
- and will be deleted with the window (or when you call SetDropTarget next
- time). You can always break the association by calling SetDropTarget(NULL).
- When some data is dragged over a window, the program must decide if it's
- going to accept this data or not. The virtual function IsAcceptedData() is
- called to do it. The default implementation takes care of OLE interface
- pointer manipulations and only requires you to override GetCountFormats()
- and GetFormat(n) functions to let it know what data formats you support.
- If it's not flexible enough for your application (i.e. the set of supported
- formats changes over time...), you should override IsAcceptedData(). In 99%
- of cases the default implementation is ok and you only have to return count
- of supported formats (CF_xxx constants or one of your custom formats which
- must have been registered) and their values.
- b) OnDrop(long x, long y, const void *pData)
- (x, y) are drop point (client) coordinates, pData is the pointer to data
- (whatever it is).
- If 'true' is returned from OnDrop, the operation is considered to be
- successful and the corresponding code (MOVE or COPY depending on the
- keyboard control keys) is returned. Otherwise, the operation is cancelled.
- Please remember that returning 'true' here may mean 'move' and so the
- drop source will delete the corresponding data - which would lead to
- data loss if you didn't paste it properly.
- c) OnEnter()
- called when the mouse enters the window: you might use this function to
- give some additional visual feedback.
- d) OnLeave()
- called when the mouse leaves the window; might be a good place to clean
- up things allocated in OnEnter.
- e) Simple wxDropTarget specializations
- Two (very simple) wxDropTarget-derived classes are provided for two most
- common situations: d&d of text and file d&d. To use them you only need to
- override one virtual function OnDropText in wxTextDropTarget's case and
- OnDropFiles for wxFileDropTarget.
- The (x, y) are the same as for OnDrop() function. OnDropText's last
- parameter points to a (always ANSI, not Unicode) text string, while
- OnDropFiles() parameter is the array of file names just dropped (and the
- count of them is passed in the 3rd parameter).
- 3. Data Object
- -----------
- a) Drag and drop and clipboard
- The effect of a d&d operation is the same as using the clipboard to
- cut/copy and paste data and it would be nice to use the same code to implement
- these two data transfer mechanisms. The wxDataObject allows you to do exactly
- this. It encapsulates the data which can be passed either through the clipboard
- or d&d.
- b) Data format
- There are several standard clipboard formats, such as text, bitmap or
- metafile picture. All of them are defined in wxDataObject::StdFormats
- enumeration. Of course, it's not always enough and you'll often need your
- own format for data transfer. The simple helper class wxDataFormat may help
- you: when you create an object of this class, it registers a new clipboard
- data format identified by the string passed to its ctor.
- After your new format is registered, you may use it as any other one.
- 4. Drop Source
- -----------
- a) Starting the d&d operation
-
- In order to start the d&d operation you should call the DoDragDrop function
- (typically in reply to a "mouse button press" message). NB: DoDragDrop() is a
- blocking function which enters into its own message loop and may return after
- an arbitrarily long time interval. During it, the QueryContinueDrag() is called
- whenever the mouse or keyboard state changes. The default behaviour is quite
- reasonable for 99% of cases: the drag operation is cancelled if the <Esc> key
- is preessed and the drop is initiated if the mouse button is released.
- b) After the end of d&d
- The drop source behaviour depends on DoDragDrop() return code. If it
- returns wxDropSource::None or wxDropSource::Copy there is normally nothing to
- do, but you shouldn't forget to delete your data if it returns the
- wxDropSource::Move code.
- c) DoDragDrop
- d) QueryContinueDrag
- 5. Remarks
- -------
- @@@@ TODO: support tymed != TYMED_HGLOBAL;
- better support of CF_BMP, CF_METAFILE
- scrolling support!! (how?)
- sample demonstrating use of user-defined formats
- sample which really does something useful
|