]> git.saurik.com Git - wxWidgets.git/commitdiff
wxDataObject changes - ok for MSW, still not for GTK/Motif/...
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 21 Oct 1999 01:58:57 +0000 (01:58 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 21 Oct 1999 01:58:57 +0000 (01:58 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4090 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

17 files changed:
include/wx/clipbrd.h
include/wx/dataobj.h
include/wx/defs.h
include/wx/dnd.h
include/wx/gtk/dnd.h
include/wx/gtk1/dnd.h
include/wx/msw/ole/dataobj.h
include/wx/msw/ole/dropsrc.h
include/wx/msw/ole/droptgt.h
samples/dnd/dnd.cpp
src/common/appcmn.cpp
src/common/dobjcmn.cpp
src/msw/clipbrd.cpp
src/msw/ole/dataobj.cpp
src/msw/ole/dropsrc.cpp
src/msw/ole/droptgt.cpp
src/msw/window.cpp

index 6ce90e1982ccba9b101be9c6912953c43fc9adca..ad50734933779ac3dcca5b8c65e9d83f7f2ef51e 100644 (file)
@@ -115,7 +115,7 @@ class wxClipboardModule : public wxModule
 {
 public:
     bool OnInit()
-        { wxTheClipboard = new wxClipboard; }
+        { wxTheClipboard = new wxClipboard; return TRUE; }
     void OnExit()
         { delete wxTheClipboard; wxTheClipboard = (wxClipboard *)NULL; }
 
index 9ef5f2bc7fd7b37465433d9ef7d7a4b136881208..572b4f12d216eb7cc9b04824e379b23d83db45ef 100644 (file)
@@ -134,7 +134,10 @@ public:
     // get data from the buffer of specified length (in the given format),
     // return TRUE if the data was read successfully, FALSE otherwise
     virtual bool SetData(const wxDataFormat& format,
-                         size_t len, const void *buf) = 0;
+                         size_t len, const void *buf)
+    {
+        return FALSE;
+    }
 };
 
 // ----------------------------------------------------------------------------
@@ -334,31 +337,25 @@ private:
 
 // ----------------------------------------------------------------------------
 // wxFileDataObject contains a list of filenames
+//
+// NB: notice that this is a "write only" object, it can only be filled with
+//     data from drag and drop operation.
 // ----------------------------------------------------------------------------
 
 class WXDLLEXPORT wxFileDataObjectBase : public wxDataObjectSimple
 {
 public:
-    // ctor: you can specify the bitmap here or in SetBitmap(), or override
-    // GetBitmap()
+    // ctor: use AddFile() later to fill the array
     wxFileDataObjectBase() : wxDataObjectSimple(wxDF_FILENAME) { }
 
-    // get a reference to our array - you may modify it (i.e. add/remove
-    // filenames to it then)
-    wxArrayString& GetFilenames() { return m_filenames; }
+    // get a reference to our array
+    const wxArrayString& GetFilenames() { return m_filenames; }
 
-    // a helper function
-    void AddFile(const wxString& filename) { m_filenames.Add(filename); }
+    // the Get() functions do nothing for us
+    virtual size_t GetDataSize() const { return 0; }
+    virtual bool GetDataHere(void *WXUNUSED(buf)) const { return FALSE; }
 
-    // virtual functions which you may override if you want to provide data on
-    // demand only - otherwise, the trivial default versions will be used.
-    //
-    // they work with a NUL-separated string of filenames, the base class
-    // versions concatenate/extract filenames from this string
-    virtual wxString GetFilenames() const;
-    virtual void SetFilenames(const wxChar* filenames);
-
-private:
+protected:
     wxArrayString m_filenames;
 };
 
index 0eb6c98144d5e8d49e52e1cdf64634b9ba37c558..96699360413cedcdd52b24d7e4cd02dbb1e802fc 100644 (file)
@@ -1243,29 +1243,29 @@ typedef enum
 #define    wxTOOL_LEFT       3
 #define    wxTOOL_RIGHT       4
 
-
-// tyhe ids of standard data formats
+// the values of the format constants should be the same as correspondign
+// CF_XXX constants in Windows API
 enum wxDataFormatId
 {
-  wxDF_INVALID =          0,
-  wxDF_TEXT =             1,  /* CF_TEXT */
-  wxDF_BITMAP =           2,  /* CF_BITMAP */
-  wxDF_METAFILE =         3,  /* CF_METAFILEPICT */
-  wxDF_SYLK =             4,
-  wxDF_DIF =              5,
-  wxDF_TIFF =             6,
-  wxDF_OEMTEXT =          7,  /* CF_OEMTEXT */
-  wxDF_DIB =              8,  /* CF_DIB */
-  wxDF_PALETTE =          9,
-  wxDF_PENDATA =          10,
-  wxDF_RIFF =             11,
-  wxDF_WAVE =             12,
-  wxDF_UNICODETEXT =      13,
-  wxDF_ENHMETAFILE =      14,
-  wxDF_FILENAME =         15, /* CF_HDROP */
-  wxDF_LOCALE =           16,
-  wxDF_PRIVATE =          20,
-  wxDF_MAX
+    wxDF_INVALID =          0,
+    wxDF_TEXT =             1,  /* CF_TEXT */
+    wxDF_BITMAP =           2,  /* CF_BITMAP */
+    wxDF_METAFILE =         3,  /* CF_METAFILEPICT */
+    wxDF_SYLK =             4,
+    wxDF_DIF =              5,
+    wxDF_TIFF =             6,
+    wxDF_OEMTEXT =          7,  /* CF_OEMTEXT */
+    wxDF_DIB =              8,  /* CF_DIB */
+    wxDF_PALETTE =          9,
+    wxDF_PENDATA =          10,
+    wxDF_RIFF =             11,
+    wxDF_WAVE =             12,
+    wxDF_UNICODETEXT =      13,
+    wxDF_ENHMETAFILE =      14,
+    wxDF_FILENAME =         15, /* CF_HDROP */
+    wxDF_LOCALE =           16,
+    wxDF_PRIVATE =          20,
+    wxDF_MAX
 };
 
 /* Virtual keycodes */
index c201cf999261d05f96e0c9bd412ac64c5e9fbe6c..36d3e506cd1e68ac40e64dc9b975350d57e81309 100644 (file)
@@ -49,7 +49,7 @@ public:
     // start drag action, see enum wxDragResult for return value description
     //
     // if bAllowMove is TRUE, data can be moved, if not - only copied
-    virtual wxDragResult DoDragDrop( bool bAllowMove = FALSE );
+    virtual wxDragResult DoDragDrop(bool bAllowMove = FALSE) = 0;
 
     // override to give feedback depending on the current operation result
     // "effect"
@@ -65,7 +65,13 @@ protected:
 
 // ----------------------------------------------------------------------------
 // wxDropTarget should be associated with a window if it wants to be able to
-// receive data via drag and drop
+// receive data via drag and drop.
+//
+// To use this class, you should derive from wxDropTarget and implement
+// OnData() pure virtual method. You may also wish to override OnDrop() if you
+// want to accept the data only inside some region of the window (this may
+// avoid having to copy the data to this application which happens only when
+// OnData() is called)
 // ----------------------------------------------------------------------------
 
 class WXDLLEXPORT wxDropTargetBase
@@ -99,7 +105,7 @@ public:
     // called after OnDrop() returns TRUE: you will usually just call
     // GetData() from here and, probably, also refresh something to update the
     // new data
-    virtual bool OnData() = 0;
+    virtual bool OnData(wxCoord x, wxCoord y) = 0;
 
     // may be called *only* from inside OnData() and will fill m_dataObject
     // with the data from the drop source if it returns TRUE
@@ -109,12 +115,16 @@ protected:
     wxDataObject *m_dataObject;
 };
 
+// ----------------------------------------------------------------------------
+// the platform-specific headers also define standard wxDropTarget
+// implementations wxTextDropTarget and wxFileDropTarget
+// ----------------------------------------------------------------------------
+
 // ----------------------------------------------------------------------------
 // include platform dependent class declarations
 // ----------------------------------------------------------------------------
 
 #if defined(__WXMSW__)
-    #include "wx/dataobj.h"
     #include "wx/msw/ole/dropsrc.h"
     #include "wx/msw/ole/droptgt.h"
 #elif defined(__WXMOTIF__)
index c43eeca35b9488b6397e351b4640c191faf1fb76..c67cb053e8ef1339ccceceb660ed4b058a79471e 100644 (file)
@@ -15,8 +15,6 @@
 #pragma interface
 #endif
 
-#include "wx/defs.h"
-
 #if wxUSE_DRAG_AND_DROP
 
 #include "wx/object.h"
@@ -46,87 +44,153 @@ class wxDropSource;
 class wxDropTarget: public wxObject
 {
 public:
-    wxDropTarget( wxDataObject *data );
-    ~wxDropTarget();
 
-    /* may be overridden to react to events */
-    virtual bool OnEnter( int x, int y );
-  
-    virtual void OnLeave();
+  wxDropTarget();
+  ~wxDropTarget();
+
+  /* may be overridden to react to events */
+  virtual void OnEnter();
+  virtual void OnLeave();
+
+  /* may be overridden to reject certain formats or drops
+     on certain areas. always returns TRUE by default
+     indicating that you'd accept the data from the drag. */
+  virtual bool OnMove( long x, long y );
+
+  /* has to be overridden to accept a drop event. call
+     IsSupported() to ask which formats are available
+     and then call RequestData() to indicate the format
+     you request. */
+  virtual bool OnDrop( long x, long y );
 
-    /* may be overridden to reject certain formats or drops
-       on certain areas. always returns TRUE by default
-       indicating that you'd accept the data from the drag. */
-    virtual bool OnMove( int x, int y );
+  /* this gets called once the data has actually arrived. get
+     it with GetData(). this has to be overridden. */
+  virtual bool OnData( long x, long y );
 
-    /* has to be overridden to accept a drop event. call
-       IsSupported() to ask which formats are available
-       and then call RequestData() to indicate the format
-       you request. */
-    virtual bool OnDrop( int x, int y );
+  /* called from within OnDrop() to request a certain format
+     from the drop event. */
+  bool RequestData( wxDataFormat format );
 
-    /* this gets called once the data has actually arrived.
-       it will call GetData() to fill up its wxDataObject */
-    virtual bool OnData( int x, int y );
+  /* called to query what formats are available */
+  bool IsSupported( wxDataFormat format );
 
-    /* fill data with data from the dragging source */
-    bool GetData();
+  /* fill data with data from the dragging source */
+  bool GetData( wxDataObject *data );
 
+  virtual size_t GetFormatCount() const = 0;
+  virtual wxDataFormat GetFormat(size_t n) const = 0;
+  
 // implementation
 
-    GdkAtom GetMatchingPair();
+  void RegisterWidget( GtkWidget *widget );
+  void UnregisterWidget( GtkWidget *widget );
+
+  GdkDragContext     *m_dragContext;
+  GtkWidget          *m_dragWidget;
+  GtkSelectionData   *m_dragData;
+  guint               m_dragTime;
+  bool                m_firstMotion;     /* gdk has no "gdk_drag_enter" event */
+
+  void SetDragContext( GdkDragContext *dc ) { m_dragContext = dc; }
+  void SetDragWidget( GtkWidget *w ) { m_dragWidget = w; }
+  void SetDragData( GtkSelectionData *sd ) { m_dragData = sd; }
+  void SetDragTime( guint time ) { m_dragTime = time; }
+};
+
+//-------------------------------------------------------------------------
+// wxTextDropTarget
+//-------------------------------------------------------------------------
 
-    void RegisterWidget( GtkWidget *widget );
-    void UnregisterWidget( GtkWidget *widget );
+class wxTextDropTarget: public wxDropTarget
+{
+public:
 
-    wxDataObject       *m_data;
-    GdkDragContext     *m_dragContext;
-    GtkWidget          *m_dragWidget;
-    GtkSelectionData   *m_dragData;
-    guint               m_dragTime;
-    bool                m_firstMotion;     /* gdk has no "gdk_drag_enter" event */
+  wxTextDropTarget() {}
 
-    void SetDragContext( GdkDragContext *dc ) { m_dragContext = dc; }
-    void SetDragWidget( GtkWidget *w ) { m_dragWidget = w; }
-    void SetDragData( GtkSelectionData *sd ) { m_dragData = sd; }
-    void SetDragTime( guint time ) { m_dragTime = time; }
+  virtual bool OnData( long x, long y );
+
+  /* you have to override OnDropData to get at the text */
+  virtual bool OnDropText( long x, long y, const wxChar *text ) = 0;
+
+  virtual size_t GetFormatCount() const
+    { return 1; }
+  virtual wxDataFormat GetFormat(size_t n) const
+    { return wxDF_TEXT; }
 };
 
 //-------------------------------------------------------------------------
-// wxDropSource
+// wxPrivateDropTarget
 //-------------------------------------------------------------------------
 
-enum wxDragResult
+/*
+class wxPrivateDropTarget: public wxDropTarget
 {
-  wxDragError,    // error prevented the d&d operation from completing
-  wxDragNone,     // drag target didn't accept the data
-  wxDragCopy,     // the data was successfully copied
-  wxDragMove,     // the data was successfully moved (MSW only)
-  wxDragCancel    // the operation was cancelled by user (not an error)
+public:
+
+  wxPrivateDropTarget();
+  wxPrivateDropTarget( const wxString &id );
+
+  virtual bool OnMove( long x, long y );
+  virtual bool OnDrop( long x, long y );
+  virtual bool OnData( long x, long y );
+
+  virtual bool OnDropData( long x, long y, void *data, size_t size ) = 0;
+
+  void SetId( const wxString& id ) { m_id = id; }
+  wxString GetId() { return m_id; }
+
+private:
+
+    wxString   m_id;
 };
+*/
 
-class wxDropSource: public wxObject
+//----------------------------------------------------------------------------
+// A drop target which accepts files (dragged from File Manager or Explorer)
+//----------------------------------------------------------------------------
+
+class wxFileDropTarget: public wxDropTarget
 {
 public:
 
-  /* constructor. set data later with SetData() */
-  wxDropSource( wxWindow *win, const wxIcon &go = wxNullIcon, const wxIcon &stop = wxNullIcon );
+  wxFileDropTarget() {}
+
+  virtual bool OnData( long x, long y );
 
-  wxDropSource( wxDataObject& data, wxWindow *win, const wxIcon &go = wxNullIcon, const wxIcon &stop = wxNullIcon );
-  ~wxDropSource();
+  virtual bool OnDropFiles( long x, long y, size_t nFiles, const wxChar * const aszFiles[] ) = 0;
+  
+  virtual size_t GetFormatCount() const
+    { return 1; }
+  virtual wxDataFormat GetFormat(size_t n) const
+    { return wxDF_FILENAME; }
+};
 
-  void SetData( wxDataObject& data );
+//-------------------------------------------------------------------------
+// wxDropSource
+//-------------------------------------------------------------------------
+
+class wxDropSource: public wxObject
+{
+public:
+    /* constructor. set data later with SetData() */
+    wxDropSource( wxWindow *win,
+                  const wxIcon &go = wxNullIcon,
+                  const wxIcon &stop = wxNullIcon );
 
-  /* start drag action */
-  wxDragResult DoDragDrop( bool bAllowMove = FALSE );
+    /* constructor for setting one data object */
+    wxDropSource( wxDataObject& data,
+                  wxWindow *win,
+                  const wxIcon &go = wxNullIcon,
+                  const wxIcon &stop = wxNullIcon );
 
-  /* override to give feedback */
-  virtual bool GiveFeedback( wxDragResult WXUNUSED(effect), bool WXUNUSED(bScrolling) ) { return TRUE; }
+    ~wxDropSource();
 
-  /* GTK implementation */
+    /* start drag action */
+    virtual wxDragResult DoDragDrop( bool bAllowMove = FALSE );
 
-  void RegisterWindow();
-  void UnregisterWindow();
+    /* GTK implementation */
+    void RegisterWindow();
+    void UnregisterWindow();
 
     GtkWidget     *m_widget;
     wxWindow      *m_window;
index c43eeca35b9488b6397e351b4640c191faf1fb76..c67cb053e8ef1339ccceceb660ed4b058a79471e 100644 (file)
@@ -15,8 +15,6 @@
 #pragma interface
 #endif
 
-#include "wx/defs.h"
-
 #if wxUSE_DRAG_AND_DROP
 
 #include "wx/object.h"
@@ -46,87 +44,153 @@ class wxDropSource;
 class wxDropTarget: public wxObject
 {
 public:
-    wxDropTarget( wxDataObject *data );
-    ~wxDropTarget();
 
-    /* may be overridden to react to events */
-    virtual bool OnEnter( int x, int y );
-  
-    virtual void OnLeave();
+  wxDropTarget();
+  ~wxDropTarget();
+
+  /* may be overridden to react to events */
+  virtual void OnEnter();
+  virtual void OnLeave();
+
+  /* may be overridden to reject certain formats or drops
+     on certain areas. always returns TRUE by default
+     indicating that you'd accept the data from the drag. */
+  virtual bool OnMove( long x, long y );
+
+  /* has to be overridden to accept a drop event. call
+     IsSupported() to ask which formats are available
+     and then call RequestData() to indicate the format
+     you request. */
+  virtual bool OnDrop( long x, long y );
 
-    /* may be overridden to reject certain formats or drops
-       on certain areas. always returns TRUE by default
-       indicating that you'd accept the data from the drag. */
-    virtual bool OnMove( int x, int y );
+  /* this gets called once the data has actually arrived. get
+     it with GetData(). this has to be overridden. */
+  virtual bool OnData( long x, long y );
 
-    /* has to be overridden to accept a drop event. call
-       IsSupported() to ask which formats are available
-       and then call RequestData() to indicate the format
-       you request. */
-    virtual bool OnDrop( int x, int y );
+  /* called from within OnDrop() to request a certain format
+     from the drop event. */
+  bool RequestData( wxDataFormat format );
 
-    /* this gets called once the data has actually arrived.
-       it will call GetData() to fill up its wxDataObject */
-    virtual bool OnData( int x, int y );
+  /* called to query what formats are available */
+  bool IsSupported( wxDataFormat format );
 
-    /* fill data with data from the dragging source */
-    bool GetData();
+  /* fill data with data from the dragging source */
+  bool GetData( wxDataObject *data );
 
+  virtual size_t GetFormatCount() const = 0;
+  virtual wxDataFormat GetFormat(size_t n) const = 0;
+  
 // implementation
 
-    GdkAtom GetMatchingPair();
+  void RegisterWidget( GtkWidget *widget );
+  void UnregisterWidget( GtkWidget *widget );
+
+  GdkDragContext     *m_dragContext;
+  GtkWidget          *m_dragWidget;
+  GtkSelectionData   *m_dragData;
+  guint               m_dragTime;
+  bool                m_firstMotion;     /* gdk has no "gdk_drag_enter" event */
+
+  void SetDragContext( GdkDragContext *dc ) { m_dragContext = dc; }
+  void SetDragWidget( GtkWidget *w ) { m_dragWidget = w; }
+  void SetDragData( GtkSelectionData *sd ) { m_dragData = sd; }
+  void SetDragTime( guint time ) { m_dragTime = time; }
+};
+
+//-------------------------------------------------------------------------
+// wxTextDropTarget
+//-------------------------------------------------------------------------
 
-    void RegisterWidget( GtkWidget *widget );
-    void UnregisterWidget( GtkWidget *widget );
+class wxTextDropTarget: public wxDropTarget
+{
+public:
 
-    wxDataObject       *m_data;
-    GdkDragContext     *m_dragContext;
-    GtkWidget          *m_dragWidget;
-    GtkSelectionData   *m_dragData;
-    guint               m_dragTime;
-    bool                m_firstMotion;     /* gdk has no "gdk_drag_enter" event */
+  wxTextDropTarget() {}
 
-    void SetDragContext( GdkDragContext *dc ) { m_dragContext = dc; }
-    void SetDragWidget( GtkWidget *w ) { m_dragWidget = w; }
-    void SetDragData( GtkSelectionData *sd ) { m_dragData = sd; }
-    void SetDragTime( guint time ) { m_dragTime = time; }
+  virtual bool OnData( long x, long y );
+
+  /* you have to override OnDropData to get at the text */
+  virtual bool OnDropText( long x, long y, const wxChar *text ) = 0;
+
+  virtual size_t GetFormatCount() const
+    { return 1; }
+  virtual wxDataFormat GetFormat(size_t n) const
+    { return wxDF_TEXT; }
 };
 
 //-------------------------------------------------------------------------
-// wxDropSource
+// wxPrivateDropTarget
 //-------------------------------------------------------------------------
 
-enum wxDragResult
+/*
+class wxPrivateDropTarget: public wxDropTarget
 {
-  wxDragError,    // error prevented the d&d operation from completing
-  wxDragNone,     // drag target didn't accept the data
-  wxDragCopy,     // the data was successfully copied
-  wxDragMove,     // the data was successfully moved (MSW only)
-  wxDragCancel    // the operation was cancelled by user (not an error)
+public:
+
+  wxPrivateDropTarget();
+  wxPrivateDropTarget( const wxString &id );
+
+  virtual bool OnMove( long x, long y );
+  virtual bool OnDrop( long x, long y );
+  virtual bool OnData( long x, long y );
+
+  virtual bool OnDropData( long x, long y, void *data, size_t size ) = 0;
+
+  void SetId( const wxString& id ) { m_id = id; }
+  wxString GetId() { return m_id; }
+
+private:
+
+    wxString   m_id;
 };
+*/
 
-class wxDropSource: public wxObject
+//----------------------------------------------------------------------------
+// A drop target which accepts files (dragged from File Manager or Explorer)
+//----------------------------------------------------------------------------
+
+class wxFileDropTarget: public wxDropTarget
 {
 public:
 
-  /* constructor. set data later with SetData() */
-  wxDropSource( wxWindow *win, const wxIcon &go = wxNullIcon, const wxIcon &stop = wxNullIcon );
+  wxFileDropTarget() {}
+
+  virtual bool OnData( long x, long y );
 
-  wxDropSource( wxDataObject& data, wxWindow *win, const wxIcon &go = wxNullIcon, const wxIcon &stop = wxNullIcon );
-  ~wxDropSource();
+  virtual bool OnDropFiles( long x, long y, size_t nFiles, const wxChar * const aszFiles[] ) = 0;
+  
+  virtual size_t GetFormatCount() const
+    { return 1; }
+  virtual wxDataFormat GetFormat(size_t n) const
+    { return wxDF_FILENAME; }
+};
 
-  void SetData( wxDataObject& data );
+//-------------------------------------------------------------------------
+// wxDropSource
+//-------------------------------------------------------------------------
+
+class wxDropSource: public wxObject
+{
+public:
+    /* constructor. set data later with SetData() */
+    wxDropSource( wxWindow *win,
+                  const wxIcon &go = wxNullIcon,
+                  const wxIcon &stop = wxNullIcon );
 
-  /* start drag action */
-  wxDragResult DoDragDrop( bool bAllowMove = FALSE );
+    /* constructor for setting one data object */
+    wxDropSource( wxDataObject& data,
+                  wxWindow *win,
+                  const wxIcon &go = wxNullIcon,
+                  const wxIcon &stop = wxNullIcon );
 
-  /* override to give feedback */
-  virtual bool GiveFeedback( wxDragResult WXUNUSED(effect), bool WXUNUSED(bScrolling) ) { return TRUE; }
+    ~wxDropSource();
 
-  /* GTK implementation */
+    /* start drag action */
+    virtual wxDragResult DoDragDrop( bool bAllowMove = FALSE );
 
-  void RegisterWindow();
-  void UnregisterWindow();
+    /* GTK implementation */
+    void RegisterWindow();
+    void UnregisterWindow();
 
     GtkWidget     *m_widget;
     wxWindow      *m_window;
index 09dff76e9654660310fb6e7ce5967e11c5bcfc64..fe47ce3bf3a5dfc3a09392481331af1b2a5b9280 100644 (file)
@@ -22,54 +22,23 @@ struct IDataObject;
 // wxDataObject is a "smart" and polymorphic piece of data.
 // ----------------------------------------------------------------------------
 
-class WXDLLEXPORT wxDataObject
+class WXDLLEXPORT wxDataObject : public wxDataObjectBase
 {
 public:
     // ctor & dtor
     wxDataObject();
     virtual ~wxDataObject();
 
-    // pure virtuals to override
-        // get the best suited format for rendering our data
-    virtual wxDataFormat GetPreferredFormat() const = 0;
-        // get the number of formats we support: it is understood that if we
-        // can accept data in some format, then we can render data in this
-        // format as well, but the contrary is not necessarily true. For the
-        // default value of the argument, all formats we support should be
-        // returned, but if outputOnlyToo == FALSE, then we should only return
-        // the formats which our SetData() understands
-    virtual size_t GetFormatCount(bool outputOnlyToo = TRUE) const
-        { return 1; }
-        // return all formats in the provided array (of size GetFormatCount())
-    virtual void GetAllFormats(wxDataFormat *formats,
-                              bool outputOnlyToo = TRUE) const
-        { formats[0] = GetPreferredFormat(); }
-        // get the (total) size of data for the given format
-    virtual size_t GetDataSize(const wxDataFormat& format) const = 0;
-        // copy raw data (in the specified format) to provided pointer
-    virtual bool GetDataHere(const wxDataFormat& format, void *buf) const = 0;
-        // get data from the buffer (in the given format)
-    virtual bool SetData(const wxDataFormat& format, const void *buf) = 0;
-
-    // accessors
-        // retrieve IDataObject interface (for other OLE related classes)
+    // retrieve IDataObject interface (for other OLE related classes)
     IDataObject *GetInterface() const { return m_pIDataObject; }
-        // a simpler name which makes more sense for data objects supporting
-        // only one format
-    wxDataFormat GetFormat() const { return GetPreferredFormat(); }
-
-    // old interface
-        // decide if we support this format (can be either standard or custom
-        // format) -- now uses GetAllFormats()
-    virtual bool IsSupportedFormat(const wxDataFormat& format) const;
-
-    // implementation only from now on
-    // -------------------------------
 
     // tell the object that it should be now owned by IDataObject - i.e. when
     // it is deleted, it should delete us as well
     void SetAutoDelete();
 
+    // return TRUE if we support this format in "Get" direction
+    bool IsSupportedFormat(const wxDataFormat& format) const;
+
 #ifdef __WXDEBUG__
     // function to return symbolic name of clipboard format (for debug messages)
     static const char *GetFormatName(wxDataFormat format);
@@ -79,73 +48,4 @@ private:
     IDataObject *m_pIDataObject; // pointer to the COM interface
 };
 
-// ----------------------------------------------------------------------------
-// wxTextDataObject is a specialization of wxDataObject for text data
-// ----------------------------------------------------------------------------
-
-class WXDLLEXPORT wxTextDataObject : public wxDataObject
-{
-public:
-    // ctors
-    wxTextDataObject() { }
-    wxTextDataObject(const wxString& strText) : m_strText(strText) { }
-    void Init(const wxString& strText) { m_strText = strText; }
-
-    // implement base class pure virtuals
-    virtual wxDataFormat GetPreferredFormat() const
-        { return wxDF_TEXT; }
-    virtual bool IsSupportedFormat(const wxDataFormat& format) const
-        { return format == wxDF_TEXT || format == wxDF_LOCALE; }
-    virtual size_t GetDataSize(const wxDataFormat& format) const
-        { return m_strText.Len() + 1; } // +1 for trailing '\0'of course
-    virtual bool GetDataHere(const wxDataFormat& format, void *buf) const
-        { memcpy(buf, m_strText.c_str(), GetDataSize(format)); return TRUE; }
-    virtual bool SetData(const wxDataFormat& format, const void *buf)
-        { m_strText = (const wxChar *)buf; return TRUE; }
-
-    // additional helpers
-    void SetText(const wxString& strText) { m_strText = strText; }
-    wxString GetText() const { return m_strText; }
-
-private:
-    wxString  m_strText;
-};
-
-// ----------------------------------------------------------------------------
-// wxBitmapDataObject is a specialization of wxDataObject for bitmap data
-// ----------------------------------------------------------------------------
-
-#include "wx/bitmap.h"
-
-class WXDLLEXPORT wxBitmapDataObject : public wxDataObject
-{
-public:
-    // ctors
-    wxBitmapDataObject() { }
-    wxBitmapDataObject(const wxBitmap& bitmap): m_bitmap(bitmap) { }
-
-    // set/get our bitmap
-    void SetBitmap(const wxBitmap& bitmap) { m_bitmap = bitmap; }
-    const wxBitmap GetBitmap() const { return m_bitmap; }
-
-    // implement base class pure virtuals
-    virtual wxDataFormat GetPreferredFormat() const { return wxDF_BITMAP; }
-    virtual size_t GetFormatCount(bool outputOnlyToo = TRUE) const;
-    virtual void GetAllFormats(wxDataFormat *formats,
-                               bool outputOnlyToo = TRUE) const;
-    virtual size_t GetDataSize(const wxDataFormat& format) const;
-    virtual bool GetDataHere(const wxDataFormat& format, void *buf) const;
-    virtual bool SetData(const wxDataFormat& format, const void *buf);
-
-private:
-    wxBitmap m_bitmap;
-};
-
-// ----------------------------------------------------------------------------
-// wxMetaFileDataObject: see metafile.h is a specialization of wxDataObject for bitmap data
-// ----------------------------------------------------------------------------
-
-// TODO: wxFileDataObject.
-
 #endif  //_WX_MSW_OLE_DATAOBJ_H
-
index aa9283f65cf82e3c067c322403cb4612bf05d1a0..36badcc6a12c0719892943043c603a77d58023f1 100644 (file)
@@ -33,7 +33,7 @@ class WXDLLEXPORT wxWindow;
 // wxDataObject object. It's responsible for giving UI feedback while dragging.
 // ----------------------------------------------------------------------------
 
-class WXDLLEXPORT wxDropSource
+class WXDLLEXPORT wxDropSource : public wxDropSourceBase
 {
 public:
     // ctors: if you use default ctor you must call SetData() later!
index 1a7716f2a51843e9fe3b9e2662b28c740f2cdfe9..2e4a4f4f989c15ae1d36eac6de5fa04052766b11 100644 (file)
@@ -9,9 +9,6 @@
 // Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
-// ============================================================================
-// prolog
-// ============================================================================
 #ifndef   _WX_OLEDROPTGT_H
 #define   _WX_OLEDROPTGT_H
 
 #endif
 
 #if !wxUSE_DRAG_AND_DROP
-  #error  "You should #define wxUSE_DRAG_AND_DROP to 1 to compile this file!"
+    #error  "You should #define wxUSE_DRAG_AND_DROP to 1 to compile this file!"
 #endif  //WX_DRAG_DROP
 
 // ----------------------------------------------------------------------------
 // forward declarations
 // ----------------------------------------------------------------------------
+
 class  wxIDropTarget;
 struct IDataObject;
 
@@ -38,11 +36,12 @@ struct IDataObject;
 // your own class from it implementing pure virtual function in order to use it
 // (all of them, including protected ones which are called by the class itself)
 // ----------------------------------------------------------------------------
-class WXDLLEXPORT wxDropTarget
+
+class WXDLLEXPORT wxDropTarget : public wxDropTargetBase
 {
 public:
     // ctor & dtor
-    wxDropTarget();
+    wxDropTarget(wxDataObject *dataObject = NULL);
     virtual ~wxDropTarget();
 
     // normally called by wxWindow on window creation/destruction, but might be
@@ -50,62 +49,57 @@ public:
     bool Register(WXHWND hwnd);
     void Revoke(WXHWND hwnd);
 
+    // provide default implementation for base class pure virtuals
+    virtual bool OnDrop(wxCoord x, wxCoord y);
+    virtual bool GetData();
+
+    // implementation only from now on
+    // -------------------------------
+
     // do we accept this kind of data?
-    virtual bool IsAcceptedData(IDataObject *pIDataSource) const;
-
-    // called when mouse enters/leaves the window: might be used to give
-    // some visual feedback to the user
-    virtual void OnEnter() { }
-    virtual void OnLeave() { }
-
-    // this function is called when data is dropped.
-    // (x, y) are the coordinates of the drop
-    virtual bool OnDrop(long x, long y, const void *pData) = 0;
-
-protected:
-    // Override these to indicate what kind of data you support: the first
-    // format to which data can be converted is used. The classes below show
-    // how it can be done in the simplest cases.
-        // how many different (clipboard) formats do you support?
-    virtual size_t GetFormatCount() const = 0;
-        // return the n-th supported format
-    virtual wxDataFormat GetFormat(size_t n) const = 0;
+    bool IsAcceptedData(IDataObject *pIDataSource) const;
+
+    // give us the data source from IDropTarget::Drop() - this is later used by
+    // GetData() when it's called from inside OnData()
+    void SetDataSource(IDataObject *pIDataSource);
 
 private:
-    wxIDropTarget    *m_pIDropTarget; // the pointer to COM interface
+    // helper used by IsAcceptedData() and GetData()
+    wxDataFormat GetSupportedFormat(IDataObject *pIDataSource) const;
+
+    wxIDropTarget *m_pIDropTarget; // the pointer to our COM interface
+    IDataObject   *m_pIDataSource; // the pointer to the source data object
 };
 
 // ----------------------------------------------------------------------------
 // A simple wxDropTarget derived class for text data: you only need to
 // override OnDropText() to get something working
 // ----------------------------------------------------------------------------
+
 class WXDLLEXPORT wxTextDropTarget : public wxDropTarget
 {
 public:
-  virtual bool OnDrop(long x, long y, const void *pData);
-  virtual bool OnDropText(long x, long y, const wxChar *psz) = 0;
+    wxTextDropTarget();
 
-protected:
-  virtual size_t GetFormatCount() const;
-  virtual wxDataFormat GetFormat(size_t n) const;
+    virtual bool OnDropText(wxCoord x, wxCoord y, const wxString& text) = 0;
+
+    virtual bool OnData(wxCoord x, wxCoord y);
 };
 
 // ----------------------------------------------------------------------------
 // A drop target which accepts files (dragged from File Manager or Explorer)
 // ----------------------------------------------------------------------------
+
 class WXDLLEXPORT wxFileDropTarget : public wxDropTarget
 {
 public:
-  virtual bool OnDrop(long x, long y, const void *pData);
+    wxFileDropTarget();
 
-  // params: the number of files and the array of file names
-  virtual bool OnDropFiles(long x, long y,
-                           size_t nFiles, const wxChar * const aszFiles[]) = 0;
+    // parameters are the number of files and the array of file names
+    virtual bool OnDropFiles(wxCoord x, wxCoord y,
+                             const wxArrayString& filenames) = 0;
 
-protected:
-  virtual size_t GetFormatCount() const;
-  virtual wxDataFormat GetFormat(size_t n) const;
+    virtual bool OnData(wxCoord x, wxCoord y);
 };
 
-// ============================================================================
 #endif  //_WX_OLEDROPTGT_H
index 9ce9518b12ac0b1fcf51f0d2dad4a82ce2509b75..ebadcfcd0c03e18790df6e3270faf8bac2aba5fc 100644 (file)
 // file names) we drop on them
 // ----------------------------------------------------------------------------
 
-typedef long wxDropPointCoord;
-
 class DnDText : public wxTextDropTarget
 {
 public:
     DnDText(wxListBox *pOwner) { m_pOwner = pOwner; }
 
-    virtual bool OnDropText(wxDropPointCoord x, wxDropPointCoord y,
-                            const wxChar* psz);
+    virtual bool OnDropText(wxCoord x, wxCoord y, const wxString& text);
 
 private:
     wxListBox *m_pOwner;
@@ -62,8 +59,8 @@ class DnDFile : public wxFileDropTarget
 public:
     DnDFile(wxListBox *pOwner) { m_pOwner = pOwner; }
 
-  virtual bool OnDropFiles(wxDropPointCoord x, wxDropPointCoord y,
-                           size_t nFiles, const wxChar* const aszFiles[] );
+    virtual bool OnDropFiles(wxCoord x, wxCoord y,
+                             const wxArrayString& filenames);
 
 private:
     wxListBox *m_pOwner;
@@ -146,6 +143,10 @@ public:
     {
     }
 
+    // this is for debugging - lets us see when exactly an object is freed
+    // (this may be later than you think if it's on the clipboard, for example)
+    virtual ~DnDShape() { }
+
     // the functions used for drag-and-drop: they dump and restore a shape into
     // some bitwise-copiable data (might use streams too...)
     // ------------------------------------------------------------------------
@@ -213,6 +214,11 @@ public:
     {
     }
 
+    virtual ~DnDTriangularShape()
+    {
+        wxLogMessage("DnDTriangularShape is being deleted");
+    }
+
     virtual Kind GetKind() const { return Triangle; }
     virtual void Draw(wxDC& dc)
     {
@@ -244,6 +250,11 @@ public:
     {
     }
 
+    virtual ~DnDRectangularShape()
+    {
+        wxLogMessage("DnDRectangularShape is being deleted");
+    }
+
     virtual Kind GetKind() const { return Rectangle; }
     virtual void Draw(wxDC& dc)
     {
@@ -275,6 +286,11 @@ public:
     {
     }
 
+    virtual ~DnDEllipticShape()
+    {
+        wxLogMessage("DnDEllipticShape is being deleted");
+    }
+
     virtual Kind GetKind() const { return Ellipse; }
     virtual void Draw(wxDC& dc)
     {
@@ -299,9 +315,24 @@ class DnDShapeDataObject : public wxDataObject
 public:
     // ctor doesn't copy the pointer, so it shouldn't go away while this object
     // is alive
-    DnDShapeDataObject(DnDShape *shape)
+    DnDShapeDataObject(DnDShape *shape = (DnDShape *)NULL)
     {
-        m_shape = shape;
+        if ( shape )
+        {
+            // we need to copy the shape because the one we're handled may be
+            // deleted while it's still on the clipboard (for example) - and we
+            // reuse the serialisation methods here to copy it
+            void *buf = malloc(shape->DnDShape::GetDataSize());
+            shape->GetDataHere(buf);
+            m_shape = DnDShape::New(buf);
+
+            free(buf);
+        }
+        else
+        {
+            // nothing to copy
+            m_shape = NULL;
+        }
 
         // this string should uniquely identify our format, but is otherwise
         // arbitrary
@@ -312,36 +343,38 @@ public:
         m_hasBitmap = FALSE;
     }
 
+    virtual ~DnDShapeDataObject() { delete m_shape; }
+
     // accessors
     DnDShape *GetShape() const { return m_shape; }
 
     // implement base class pure virtuals
     // ----------------------------------
 
-    virtual wxDataFormat GetPreferredFormat() const
+    virtual wxDataFormat GetPreferredFormat(Direction WXUNUSED(dir)) const
     {
         return m_formatShape;
     }
 
-    virtual size_t GetFormatCount(bool outputOnlyToo) const
+    virtual size_t GetFormatCount(Direction dir) const
     {
         // our custom format is supported by both GetData() and SetData()
         size_t nFormats = 1;
-        if ( outputOnlyToo )
+        if ( dir == Get )
         {
             // but the bitmap format(s) are only supported for output
-            nFormats += m_dataobj.GetFormatCount();
+            nFormats += m_dataobj.GetFormatCount(dir);
         }
 
         return nFormats;
     }
 
-    virtual void GetAllFormats(wxDataFormat *formats, bool outputOnlyToo) const
+    virtual void GetAllFormats(wxDataFormat *formats, Direction dir) const
     {
         formats[0] = m_formatShape;
-        if ( outputOnlyToo )
+        if ( dir == Get )
         {
-            m_dataobj.GetAllFormats(&formats[1]);
+            m_dataobj.GetAllFormats(&formats[1], dir);
         }
     }
 
@@ -356,7 +389,7 @@ public:
             if ( !m_hasBitmap )
                 CreateBitmap();
 
-            return m_dataobj.GetDataSize(format);
+            return m_dataobj.GetDataSize();
         }
     }
 
@@ -375,11 +408,12 @@ public:
             if ( !m_hasBitmap )
                 CreateBitmap();
 
-            return m_dataobj.GetDataHere(format, pBuf);
+            return m_dataobj.GetDataHere(pBuf);
         }
     }
 
-    virtual bool SetData(const wxDataFormat& format, const void *buf)
+    virtual bool SetData(const wxDataFormat& format,
+                         size_t len, const void *buf)
     {
         wxCHECK_MSG( format == m_formatShape, FALSE, "unsupported format" );
 
@@ -483,11 +517,9 @@ class DnDShapeDropTarget : public wxDropTarget
 {
 public:
     DnDShapeDropTarget(DnDShapeFrame *frame)
+        : wxDropTarget(new DnDShapeDataObject)
     {
         m_frame = frame;
-
-        // the same as used by DnDShapeDataObject
-        m_formatShape.SetId(shapeFormatId);
     }
 
     // override base class (pure) virtuals
@@ -495,21 +527,23 @@ public:
         { m_frame->SetStatusText("Mouse entered the frame"); }
     virtual void OnLeave()
         { m_frame->SetStatusText("Mouse left the frame"); }
-    virtual bool OnDrop(long x, long y, const void *pData)
+    virtual bool OnData(wxCoord x, wxCoord y)
     {
-        m_frame->OnDrop(x, y, DnDShape::New(pData));
+        if ( !GetData() )
+        {
+            wxLogError("Failed to get drag and drop data");
+
+            return FALSE;
+        }
+
+        m_frame->OnDrop(x, y,
+                        ((DnDShapeDataObject *)GetDataObject())->GetShape());
 
         return TRUE;
     }
 
-protected:
-    virtual size_t GetFormatCount() const { return 1; }
-    virtual wxDataFormat GetFormat(size_t WXUNUSED(n)) const
-        { return m_formatShape; }
-
 private:
     DnDShapeFrame *m_frame;
-    wxDataFormat m_formatShape;
 };
 
 // ----------------------------------------------------------------------------
@@ -1012,21 +1046,21 @@ void DnDFrame::OnPaste(wxCommandEvent& WXUNUSED(event))
 // Notifications called by the base class
 // ----------------------------------------------------------------------------
 
-bool DnDText::OnDropText( wxDropPointCoord, wxDropPointCoord, const wxChar *psz )
+bool DnDText::OnDropText(wxCoord, wxCoord, const wxString& text)
 {
-    m_pOwner->Append(psz);
+    m_pOwner->Append(text);
 
     return TRUE;
 }
 
-bool DnDFile::OnDropFiles( wxDropPointCoord, wxDropPointCoord, size_t nFiles,
-                           const wxChar* const aszFiles[])
+bool DnDFile::OnDropFiles(wxCoord, wxCoord, const wxArrayString& filenames)
 {
+    size_t nFiles = filenames.GetCount();
     wxString str;
     str.Printf( _T("%d files dropped"), nFiles);
     m_pOwner->Append(str);
     for ( size_t n = 0; n < nFiles; n++ ) {
-        m_pOwner->Append(aszFiles[n]);
+        m_pOwner->Append(filenames[n]);
     }
 
     return TRUE;
@@ -1224,6 +1258,18 @@ void DnDShapeFrame::OnDrag(wxMouseEvent& event)
     //else: status text already set
 }
 
+void DnDShapeFrame::OnDrop(long x, long y, DnDShape *shape)
+{
+    ms_lastDropTarget = this;
+
+    wxString s;
+    s.Printf("Shape dropped at (%ld, %ld)", x, y);
+    SetStatusText(s);
+
+    shape->Move(ScreenToClient(wxPoint(x, y)));
+    SetShape(shape);
+}
+
 void DnDShapeFrame::OnEditShape(wxCommandEvent& event)
 {
     DnDShapeDialog dlg(this, m_shape);
@@ -1287,18 +1333,6 @@ void DnDShapeFrame::OnPaint(wxPaintEvent& event)
         event.Skip();
 }
 
-void DnDShapeFrame::OnDrop(long x, long y, DnDShape *shape)
-{
-    ms_lastDropTarget = this;
-
-    wxString s;
-    s.Printf("Shape dropped at (%ld, %ld)", x, y);
-    SetStatusText(s);
-
-    shape->Move(ScreenToClient(wxPoint(x, y)));
-    SetShape(shape);
-}
-
 // ----------------------------------------------------------------------------
 // DnDShape
 // ----------------------------------------------------------------------------
index 33d0cc195646f0626d8ecd67dfc741b42561df02..8cb28408e7bcdf4eb427c7c8dad95367c44b4553 100644 (file)
@@ -33,6 +33,7 @@
 #endif
 
 #include "wx/thread.h"
+#include "wx/clipbrd.h"
 
 // ===========================================================================
 // implementation
index f806dcdec6b798a940f9e2fe36090606b2c29644..9c5e5ddc390b9af2bb77d6e6f948b9823243780e 100644 (file)
@@ -175,6 +175,10 @@ bool wxTextDataObject::SetData(size_t WXUNUSED(len), const void *buf)
 // wxFileDataObjectBase
 // ----------------------------------------------------------------------------
 
+// VZ: I don't need this in MSW finally, so if it is needed in wxGTK, it should
+//     be moved to gtk/dataobj.cpp
+#if 0
+
 wxString wxFileDataObjectBase::GetFilenames() const
 {
     wxString str;
@@ -212,6 +216,8 @@ void wxFileDataObjectBase::SetFilenames(const wxChar* filenames)
     }
 }
 
+#endif // 0
+
 // ----------------------------------------------------------------------------
 // wxCustomDataObject
 // ----------------------------------------------------------------------------
@@ -257,7 +263,7 @@ bool wxCustomDataObject::GetDataHere(void *buf) const
     return TRUE;
 }
 
-bool wxCustomDataObject::SetData(size_t len, const void *buf)
+bool wxCustomDataObject::SetData(size_t size, const void *buf)
 {
     Free();
 
@@ -265,7 +271,7 @@ bool wxCustomDataObject::SetData(size_t len, const void *buf)
     if ( !m_data )
         return FALSE;
 
-    memcpy(m_data, buf, m_size = len);
+    memcpy(m_data, buf, m_size = size);
 
     return TRUE;
 }
index a24d4c3c5834fd993a35bf231d6ee607b7340ceb..f8287de98adcf6730466fbd31ff68759423a3ca3 100644 (file)
@@ -584,7 +584,7 @@ bool wxClipboard::GetData( wxDataObject *data )
     }
 
     // build the list of supported formats
-    size_t nFormats = data->GetFormatCount(FALSE /* for SetData() */);
+    size_t nFormats = data->GetFormatCount(wxDataObject::Set);
     wxDataFormat format, *formats;
     if ( nFormats == 1 )
     {
@@ -597,7 +597,7 @@ bool wxClipboard::GetData( wxDataObject *data )
         formats = new wxDataFormat[nFormats];
     }
 
-    data->GetAllFormats(formats, FALSE);
+    data->GetAllFormats(formats, wxDataObject::Set);
 
     // get the format enumerator
     bool result = FALSE;
index 14ae6ed6a880334eb1101f26f169ffa63e1e0166..46cfd66c4b35f2ce6e1f2d690fae43f7a80a8e44 100644 (file)
     static const wxChar *GetTymedName(DWORD tymed);
 #endif // Debug
 
+// to be moved into wx/msw/bitmap.h
+extern size_t wxConvertBitmapToDIB(BITMAPINFO *pbi, const wxBitmap& bitmap);
+extern wxBitmap wxConvertDIBToBitmap(const BITMAPINFO *bmi);
+
 // ----------------------------------------------------------------------------
 // wxIEnumFORMATETC interface implementation
 // ----------------------------------------------------------------------------
@@ -320,6 +324,12 @@ STDMETHODIMP wxIDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
                 return DV_E_FORMATETC;
             }
 
+            if ( !format.IsStandard() ) {
+                // for custom formats, put the size with the data - alloc the
+                // space for it
+                size += sizeof(size_t);
+            }
+
             HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, size);
             if ( hGlobal == NULL ) {
                 wxLogLastError("GlobalAlloc");
@@ -369,17 +379,25 @@ STDMETHODIMP wxIDataObject::GetDataHere(FORMATETC *pformatetc,
         case TYMED_HGLOBAL:
             {
                 // copy data
-                void *pBuf = GlobalLock(pmedium->hGlobal);
+                HGLOBAL hGlobal = pmedium->hGlobal;
+                void *pBuf = GlobalLock(hGlobal);
                 if ( pBuf == NULL ) {
                     wxLogLastError(wxT("GlobalLock"));
                     return E_OUTOFMEMORY;
                 }
 
-                wxDataFormat format = (wxDataFormatId)pformatetc->cfFormat;
+                if ( !wxDataFormat(pformatetc->cfFormat).IsStandard() ) {
+                    // for custom formats, put the size with the data
+                    size_t *p = (size_t *)pBuf;
+                    *p++ = GlobalSize(hGlobal);
+                    pBuf = p;
+                }
+
+                wxDataFormat format = pformatetc->cfFormat;
                 if ( !m_pDataObject->GetDataHere(format, pBuf) )
                     return E_UNEXPECTED;
 
-                GlobalUnlock(pmedium->hGlobal);
+                GlobalUnlock(hGlobal);
             }
             break;
 
@@ -390,7 +408,7 @@ STDMETHODIMP wxIDataObject::GetDataHere(FORMATETC *pformatetc,
     return S_OK;
 }
 
-// set data functions (not implemented)
+// set data functions
 STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
                                     STGMEDIUM *pmedium,
                                     BOOL       fRelease)
@@ -400,7 +418,7 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
     switch ( pmedium->tymed )
     {
         case TYMED_GDI:
-            m_pDataObject->SetData(wxDF_BITMAP, &pmedium->hBitmap);
+            m_pDataObject->SetData(wxDF_BITMAP, 0, &pmedium->hBitmap);
             break;
 
         case TYMED_MFPICT:
@@ -419,10 +437,47 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
                     return E_OUTOFMEMORY;
                 }
 
-                wxDataFormat format = (wxDataFormatId)pformatetc->cfFormat;
-                m_pDataObject->SetData(format, pBuf);
+                // we've got a problem with SetData() here because the base
+                // class version requires the size parameter which we don't
+                // have anywhere in OLE data transfer - so we need to
+                // synthetise it for known formats and we suppose that all data
+                // in custom formats starts with a DWORD containing the size
+                size_t size;
+                switch ( pformatetc->cfFormat )
+                {
+                    case CF_TEXT:
+                    case CF_OEMTEXT:
+                        size = strlen((const char *)pBuf);
+                        break;
+
+                    case CF_UNICODETEXT:
+                        size = wcslen((const wchar_t *)pBuf);
+                        break;
+
+                    case CF_BITMAP:
+                    case CF_HDROP:
+                        // these formats don't use size at all, anyhow (but
+                        // pass data by handle, which is always a single DWORD)
+                        size = 0;
+                        break;
+
+                    default:
+                        {
+                            // we suppose that the size precedes the data
+                            size_t *p = (size_t *)pBuf;
+                            size = *p++;
+                            pBuf = p;
+                        }
+                }
+
+                wxDataFormat format = pformatetc->cfFormat;
+                bool ok = m_pDataObject->SetData(format, size, pBuf);
 
                 GlobalUnlock(pmedium->hGlobal);
+
+                if ( !ok ) {
+                    return E_UNEXPECTED;
+                }
             }
             break;
 
@@ -474,7 +529,7 @@ STDMETHODIMP wxIDataObject::QueryGetData(FORMATETC *pformatetc)
     }
 
     // and now check the type of data requested
-    wxDataFormat format = (wxDataFormatId)pformatetc->cfFormat;
+    wxDataFormat format = pformatetc->cfFormat;
     if ( m_pDataObject->IsSupportedFormat(format) ) {
 #ifdef __WXDEBUG__
         wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: %s ok"),
@@ -482,11 +537,10 @@ STDMETHODIMP wxIDataObject::QueryGetData(FORMATETC *pformatetc)
 #endif // Debug
     }
     else {
-#ifdef __WXDEBUG__
         wxLogTrace(wxTRACE_OleCalls,
                    wxT("wxIDataObject::QueryGetData: %s unsupported"),
                    wxDataObject::GetFormatName(format));
-#endif
+
         return DV_E_FORMATETC;
     }
 
@@ -521,25 +575,18 @@ STDMETHODIMP wxIDataObject::GetCanonicalFormatEtc(FORMATETC *pFormatetcIn,
     return DATA_S_SAMEFORMATETC;
 }
 
-STDMETHODIMP wxIDataObject::EnumFormatEtc(DWORD dwDirection,
+STDMETHODIMP wxIDataObject::EnumFormatEtc(DWORD dwDir,
                                           IEnumFORMATETC **ppenumFormatEtc)
 {
     wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::EnumFormatEtc"));
 
-    bool allowOutputOnly = dwDirection == DATADIR_GET;
+    wxDataObject::Direction dir = dwDir == DATADIR_GET ? wxDataObject::Get
+                                                       : wxDataObject::Set;
 
-    size_t nFormatCount = m_pDataObject->GetFormatCount(allowOutputOnly);
+    size_t nFormatCount = m_pDataObject->GetFormatCount(dir);
     wxDataFormat format, *formats;
-    if ( nFormatCount == 1 ) {
-        // this is the most common case, this is why we consider it separately
-        formats = &format;
-        format = m_pDataObject->GetPreferredFormat();
-    }
-    else {
-        // bad luck, build the array with all formats
-        formats = new wxDataFormat[nFormatCount];
-        m_pDataObject->GetAllFormats(formats, allowOutputOnly);
-    }
+    formats = nFormatCount == 1 ? &format : new wxDataFormat[nFormatCount];
+    m_pDataObject->GetAllFormats(formats, dir);
 
     wxIEnumFORMATETC *pEnum = new wxIEnumFORMATETC(formats, nFormatCount);
     pEnum->AddRef();
@@ -552,7 +599,10 @@ STDMETHODIMP wxIDataObject::EnumFormatEtc(DWORD dwDirection,
     return S_OK;
 }
 
+// ----------------------------------------------------------------------------
 // advise sink functions (not implemented)
+// ----------------------------------------------------------------------------
+
 STDMETHODIMP wxIDataObject::DAdvise(FORMATETC   *pformatetc,
                                     DWORD        advf,
                                     IAdviseSink *pAdvSink,
@@ -656,66 +706,81 @@ const char *wxDataObject::GetFormatName(wxDataFormat format)
 #endif // Debug
 
 // ----------------------------------------------------------------------------
-// wxPrivateDataObject
+// wxBitmapDataObject supports CF_DIB format
 // ----------------------------------------------------------------------------
 
-wxPrivateDataObject::wxPrivateDataObject()
+size_t wxBitmapDataObject::GetDataSize() const
 {
-    m_size = 0;
-    m_data = NULL;
+    return wxConvertBitmapToDIB(NULL, GetBitmap());
 }
 
-void wxPrivateDataObject::Free()
+bool wxBitmapDataObject::GetDataHere(void *buf) const
 {
-    if ( m_data )
-        free(m_data);
+    return wxConvertBitmapToDIB((BITMAPINFO *)buf, GetBitmap()) != 0;
 }
 
-void wxPrivateDataObject::SetData( const void *data, size_t size )
+bool wxBitmapDataObject::SetData(size_t len, const void *buf)
 {
-    Free();
+    wxBitmap bitmap(wxConvertDIBToBitmap((const BITMAPINFO *)buf));
+
+    if ( !bitmap.Ok() ) {
+        wxFAIL_MSG(wxT("pasting/dropping invalid bitmap"));
 
-    m_size = size;
-    m_data = malloc(size);
+        return FALSE;
+    }
+
+    SetBitmap(bitmap);
 
-    memcpy( m_data, data, size );
+    return TRUE;
 }
 
-void wxPrivateDataObject::WriteData( void *dest ) const
+// ----------------------------------------------------------------------------
+// wxBitmapDataObject2 supports CF_BITMAP format
+// ----------------------------------------------------------------------------
+
+// the bitmaps aren't passed by value as other types of data (i.e. by copying
+// the data into a global memory chunk and passing it to the clipboard or
+// another application or whatever), but by handle, so these generic functions
+// don't make much sense to them.
+
+size_t wxBitmapDataObject2::GetDataSize() const
 {
-    WriteData( m_data, dest );
+    return 0;
 }
 
-size_t wxPrivateDataObject::GetSize() const
+bool wxBitmapDataObject2::GetDataHere(void *pBuf) const
 {
-    return m_size;
+    // we put a bitmap handle into pBuf
+    *(WXHBITMAP *)pBuf = GetBitmap().GetHBITMAP();
+
+    return TRUE;
 }
 
-void wxPrivateDataObject::WriteData( const void *data, void *dest ) const
+bool wxBitmapDataObject2::SetData(size_t len, const void *pBuf)
 {
-    memcpy( dest, data, GetSize() );
-}
+    HBITMAP hbmp = *(HBITMAP *)pBuf;
 
-// ----------------------------------------------------------------------------
-// wxBitmapDataObject: it supports standard CF_BITMAP and CF_DIB formats
-// ----------------------------------------------------------------------------
+    BITMAP bmp;
+    if ( !GetObject(hbmp, sizeof(BITMAP), &bmp) )
+    {
+        wxLogLastError("GetObject(HBITMAP)");
+    }
 
-size_t wxBitmapDataObject::GetFormatCount(bool outputOnlyToo) const
-{
-    return 2;
-}
+    wxBitmap bitmap(bmp.bmWidth, bmp.bmHeight, bmp.bmPlanes);
+    bitmap.SetHBITMAP((WXHBITMAP)hbmp);
 
-void wxBitmapDataObject::GetAllFormats(wxDataFormat *formats,
-                                       bool outputOnlyToo) const
-{
-    formats[0] = CF_BITMAP;
-    formats[1] = CF_DIB;
+    if ( !bitmap.Ok() ) {
+        wxFAIL_MSG(wxT("pasting/dropping invalid bitmap"));
+
+        return FALSE;
+    }
+
+    SetBitmap(bitmap);
+
+    return TRUE;
 }
 
-// the bitmaps aren't passed by value as other types of data (i.e. by copyign
-// the data into a global memory chunk and passing it to the clipboard or
-// another application or whatever), but by handle, so these generic functions
-// don't make much sense to them.
+#if 0
 
 size_t wxBitmapDataObject::GetDataSize(const wxDataFormat& format) const
 {
@@ -789,7 +854,8 @@ bool wxBitmapDataObject::GetDataHere(const wxDataFormat& format,
     return TRUE;
 }
 
-bool wxBitmapDataObject::SetData(const wxDataFormat& format, const void *pBuf)
+bool wxBitmapDataObject::SetData(const wxDataFormat& format,
+                                 size_t size, const void *pBuf)
 {
     HBITMAP hbmp;
     if ( format.GetFormatId() == CF_DIB )
@@ -833,10 +899,120 @@ bool wxBitmapDataObject::SetData(const wxDataFormat& format, const void *pBuf)
     return TRUE;
 }
 
+#endif // 0
+
+// ----------------------------------------------------------------------------
+// wxFileDataObject
+// ----------------------------------------------------------------------------
+
+bool wxFileDataObject::SetData(size_t WXUNUSED(size), const void *pData)
+{
+    m_filenames.Empty();
+
+    // the documentation states that the first member of DROPFILES structure is
+    // a "DWORD offset of double NUL terminated file list". What they mean by
+    // this (I wonder if you see it immediately) is that the list starts at
+    // ((char *)&(pDropFiles.pFiles)) + pDropFiles.pFiles. We're also advised
+    // to use DragQueryFile to work with this structure, but not told where and
+    // how to get HDROP.
+    HDROP hdrop = (HDROP)pData;   // NB: it works, but I'm not sure about it
+
+    // get number of files (magic value -1)
+    UINT nFiles = ::DragQueryFile(hdrop, (unsigned)-1, NULL, 0u);
+
+    // for each file get the length, allocate memory and then get the name
+    wxString str;
+    UINT len, n;
+    for ( n = 0; n < nFiles; n++ ) {
+        // +1 for terminating NUL
+        len = ::DragQueryFile(hdrop, n, NULL, 0) + 1;
+
+        UINT len2 = ::DragQueryFile(hdrop, n, str.GetWriteBuf(len), len);
+        str.UngetWriteBuf();
+        m_filenames.Add(str);
+
+        if ( len2 != len - 1 ) {
+            wxLogDebug(wxT("In wxFileDropTarget::OnDrop DragQueryFile returned"
+                           " %d characters, %d expected."), len2, len - 1);
+        }
+    }
+
+    return TRUE;
+}
+
 // ----------------------------------------------------------------------------
 // private functions
 // ----------------------------------------------------------------------------
 
+// otherwise VC++ would give here:
+//  "local variable 'bi' may be used without having been initialized"
+// even though in fact it may not
+#ifdef __VISUALC__
+    #pragma warning(disable:4701)
+#endif // __VISUALC__
+
+size_t wxConvertBitmapToDIB(BITMAPINFO *pbi, const wxBitmap& bitmap)
+{
+    // shouldn't be selected into a DC or GetDIBits() would fail
+    wxASSERT_MSG( !bitmap.GetSelectedInto(),
+                  wxT("can't copy bitmap selected into wxMemoryDC") );
+
+    HBITMAP hbmp = (HBITMAP)bitmap.GetHBITMAP();
+
+    BITMAPINFO bi;
+
+    // first get the info
+    ScreenHDC hdc;
+    if ( !GetDIBits(hdc, hbmp, 0, 0, NULL, pbi ? pbi : &bi, DIB_RGB_COLORS) )
+    {
+        wxLogLastError("GetDIBits(NULL)");
+
+        return 0;
+    }
+
+    if ( !pbi )
+    {
+        // we were only asked for size needed for the buffer, not to actually
+        // copy the data
+        return sizeof(BITMAPINFO) + bi.bmiHeader.biSizeImage;
+    }
+
+    // and now copy the bits
+    if ( !GetDIBits(hdc, hbmp, 0, pbi->bmiHeader.biHeight, pbi + 1,
+                    pbi, DIB_RGB_COLORS) )
+    {
+        wxLogLastError("GetDIBits");
+
+        return 0;
+    }
+
+    return sizeof(BITMAPINFO) + pbi->bmiHeader.biSizeImage;
+}
+
+#ifdef __VISUALC__
+    #pragma warning(default:4701)
+#endif // __VISUALC__
+
+wxBitmap wxConvertDIBToBitmap(const BITMAPINFO *pbmi)
+{
+    // here we get BITMAPINFO struct followed by the actual bitmap bits and
+    // BITMAPINFO starts with BITMAPINFOHEADER followed by colour info
+    const BITMAPINFOHEADER *pbmih = &pbmi->bmiHeader;
+
+    ScreenHDC hdc;
+    HBITMAP hbmp = CreateDIBitmap(hdc, pbmih, CBM_INIT,
+                                  pbmi + 1, pbmi, DIB_RGB_COLORS);
+    if ( !hbmp )
+    {
+        wxLogLastError("CreateDIBitmap");
+    }
+
+    wxBitmap bitmap(pbmih->biWidth, pbmih->biHeight, pbmih->biBitCount);
+    bitmap.SetHBITMAP((WXHBITMAP)hbmp);
+
+    return bitmap;
+}
+
 #ifdef __WXDEBUG__
 
 static const wxChar *GetTymedName(DWORD tymed)
index bd296c8abbb73d3f3f8bb7a191d84398d02918cc..3ddecc92ea70d20bf2748a4c0dcc61734428a48c 100644 (file)
 #if wxUSE_DRAG_AND_DROP
 
 #include "wx/log.h"
-#include "wx/dataobj.h"
-#include "wx/msw/ole/dropsrc.h"
+#include "wx/dnd.h"
 
 #include <windows.h>
+
 #ifdef wxUSE_NORLANDER_HEADERS
-#include <ole2.h>
+    #include <ole2.h>
 #endif
 
 #ifndef __WIN32__
-  #include <ole2.h>
-  #include <olestd.h>
+    #include <ole2.h>
+    #include <olestd.h>
 #endif
 
 #include <oleauto.h>
@@ -165,7 +165,6 @@ wxDropSource::wxDropSource(wxWindow* WXUNUSED(win),
                            const wxIcon & WXUNUSED(stop))
 {
   Init();
-  m_pData = NULL;
 }
 
 wxDropSource::wxDropSource(wxDataObject& data,
@@ -189,10 +188,10 @@ wxDropSource::~wxDropSource()
 // Notes   : you must call SetData() before if you had used def ctor
 wxDragResult wxDropSource::DoDragDrop(bool bAllowMove)
 {
-  wxCHECK_MSG( m_pData != NULL, wxDragNone, wxT("No data in wxDropSource!") );
+  wxCHECK_MSG( m_data != NULL, wxDragNone, wxT("No data in wxDropSource!") );
 
   DWORD dwEffect;
-  HRESULT hr = ::DoDragDrop(m_pData->GetInterface(),
+  HRESULT hr = ::DoDragDrop(m_data->GetInterface(),
                             m_pIDropSource,
                             bAllowMove ? DROPEFFECT_COPY | DROPEFFECT_MOVE
                                        : DROPEFFECT_COPY,
index 003a29891a328f6e347a8d4308e12377b3a18659..c9f5feb506068ab10aaf6cd1cbf0cc3d2d3d2488 100644 (file)
@@ -42,8 +42,7 @@
     #include <shellapi.h>
 #endif
 
-#include "wx/dataobj.h"
-#include "wx/msw/ole/droptgt.h"
+#include "wx/dnd.h"
 
 #ifndef __WIN32__
     #include <ole2.h>
@@ -70,19 +69,12 @@ public:
   STDMETHODIMP DragLeave(void);
   STDMETHODIMP Drop(LPDATAOBJECT, DWORD, POINTL, LPDWORD);
 
-  // we assume that if QueryGetData() returns S_OK, than we can really get data
-  // in this format, so we remember here the format for which QueryGetData()
-  // succeeded
-  void SetSupportedFormat(wxDataFormat cfFormat) { m_cfFormat = cfFormat; }
-
   DECLARE_IUNKNOWN_METHODS;
 
 protected:
   IDataObject   *m_pIDataObject;  // !NULL between DragEnter and DragLeave/Drop
   wxDropTarget  *m_pTarget;       // the real target (we're just a proxy)
 
-  wxDataFormat   m_cfFormat;      // the format in which to ask for data
-
 private:
   static inline DWORD GetDropEffect(DWORD flags);
 };
@@ -108,7 +100,6 @@ wxIDropTarget::wxIDropTarget(wxDropTarget *pTarget)
 {
   m_cRef         = 0;
   m_pTarget      = pTarget;
-  m_cfFormat     = wxDF_INVALID;
   m_pIDataObject = NULL;
 }
 
@@ -212,45 +203,33 @@ STDMETHODIMP wxIDropTarget::Drop(IDataObject *pIDataSource,
                                  POINTL       pt,
                                  DWORD       *pdwEffect)
 {
-  wxLogDebug(wxT("IDropTarget::Drop"));
-
-  // TODO I don't know why there is this parameter, but so far I assume
-  //      that it's the same we've already got in DragEnter
-  wxASSERT( m_pIDataObject == pIDataSource );
-
-  STGMEDIUM stm;
-  *pdwEffect = DROPEFFECT_NONE;
-
-  // should be set by SetSupportedFormat() call
-  wxASSERT( m_cfFormat != wxDF_INVALID );
-
-  FORMATETC fmtMemory;
-  fmtMemory.cfFormat  = m_cfFormat;
-  fmtMemory.ptd       = NULL;
-  fmtMemory.dwAspect  = DVASPECT_CONTENT;
-  fmtMemory.lindex    = -1;
-  fmtMemory.tymed     = TYMED_HGLOBAL;  // TODO to add other media
-
-  HRESULT hr = pIDataSource->GetData(&fmtMemory, &stm);
-  if ( SUCCEEDED(hr) ) {
-    if ( stm.hGlobal != NULL ) {
-      if ( m_pTarget->OnDrop(pt.x, pt.y, GlobalLock(stm.hGlobal)) )
-        *pdwEffect = GetDropEffect(grfKeyState);
-      //else: DROPEFFECT_NONE
-
-      GlobalUnlock(stm.hGlobal);
-      ReleaseStgMedium(&stm);
+    wxLogDebug(wxT("IDropTarget::Drop"));
+
+    // TODO I don't know why there is this parameter, but so far I assume
+    //      that it's the same we've already got in DragEnter
+    wxASSERT( m_pIDataObject == pIDataSource );
+
+    // by default, nothing happens
+    *pdwEffect = DROPEFFECT_NONE;
+
+    // first ask the drop target if it wants data
+    if ( m_pTarget->OnDrop(pt.x, pt.y) ) {
+        // it does, so give it the data source
+        m_pTarget->SetDataSource(pIDataSource);
+
+        // and now it has the data
+        if ( m_pTarget->OnData(pt.x, pt.y) ) {
+            // operation succeeded
+            *pdwEffect = GetDropEffect(grfKeyState);
+        }
+        //else: *pdwEffect is already DROPEFFECT_NONE
     }
-  }
-  else
-  {
-    // wxLogApiError("GetData", hr);
-  }
+    //else: OnDrop() returned FALSE, no need to copy data
 
-  // release the held object
-  RELEASE_AND_NULL(m_pIDataObject);
+    // release the held object
+    RELEASE_AND_NULL(m_pIDataObject);
 
-  return S_OK;
+    return S_OK;
 }
 
 // ============================================================================
@@ -261,17 +240,18 @@ STDMETHODIMP wxIDropTarget::Drop(IDataObject *pIDataSource,
 // ctor/dtor
 // ----------------------------------------------------------------------------
 
-wxDropTarget::wxDropTarget()
+wxDropTarget::wxDropTarget(wxDataObject *dataObj)
+            : wxDropTargetBase(dataObj)
 {
-  // create an IDropTarget implementation which will notify us about
-  // d&d operations.
-  m_pIDropTarget = new wxIDropTarget(this);
-  m_pIDropTarget->AddRef();
+    // create an IDropTarget implementation which will notify us about d&d
+    // operations.
+    m_pIDropTarget = new wxIDropTarget(this);
+    m_pIDropTarget->AddRef();
 }
 
 wxDropTarget::~wxDropTarget()
 {
-  ReleaseInterface(m_pIDropTarget);
+    ReleaseInterface(m_pIDropTarget);
 }
 
 // ----------------------------------------------------------------------------
@@ -280,140 +260,179 @@ wxDropTarget::~wxDropTarget()
 
 bool wxDropTarget::Register(WXHWND hwnd)
 {
-  HRESULT hr = ::CoLockObjectExternal(m_pIDropTarget, TRUE, FALSE);
-  if ( FAILED(hr) ) {
-    wxLogApiError("CoLockObjectExternal", hr);
-    return FALSE;
-  }
+    HRESULT hr = ::CoLockObjectExternal(m_pIDropTarget, TRUE, FALSE);
+    if ( FAILED(hr) ) {
+        wxLogApiError("CoLockObjectExternal", hr);
+        return FALSE;
+    }
 
-  hr = ::RegisterDragDrop((HWND) hwnd, m_pIDropTarget);
-  if ( FAILED(hr) ) {
-    ::CoLockObjectExternal(m_pIDropTarget, FALSE, FALSE);
+    hr = ::RegisterDragDrop((HWND) hwnd, m_pIDropTarget);
+    if ( FAILED(hr) ) {
+        ::CoLockObjectExternal(m_pIDropTarget, FALSE, FALSE);
 
-    wxLogApiError("RegisterDragDrop", hr);
-    return FALSE;
-  }
+        wxLogApiError("RegisterDragDrop", hr);
+        return FALSE;
+    }
 
-  return TRUE;
+    return TRUE;
 }
 
 void wxDropTarget::Revoke(WXHWND hwnd)
 {
-  HRESULT hr = ::RevokeDragDrop((HWND) hwnd);
+    HRESULT hr = ::RevokeDragDrop((HWND) hwnd);
 
-  if ( FAILED(hr) ) {
-    wxLogApiError("RevokeDragDrop", hr);
-  }
+    if ( FAILED(hr) ) {
+        wxLogApiError("RevokeDragDrop", hr);
+    }
 
-  ::CoLockObjectExternal(m_pIDropTarget, FALSE, TRUE);
+    ::CoLockObjectExternal(m_pIDropTarget, FALSE, TRUE);
 }
 
 // ----------------------------------------------------------------------------
-// determine if we accept data of this type
+// base class pure virtuals
 // ----------------------------------------------------------------------------
-bool wxDropTarget::IsAcceptedData(IDataObject *pIDataSource) const
+
+// OnDrop() is called only if we previously returned TRUE from
+// IsAcceptedData(), so no need to check anything here
+bool wxDropTarget::OnDrop(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y))
+{
+    return TRUE;
+}
+
+// copy the data from the data source to the target data object
+bool wxDropTarget::GetData()
 {
-  // this strucutre describes a data of any type (first field will be
-  // changing) being passed through global memory block.
-  static FORMATETC s_fmtMemory = {
-    0,
-    NULL,
-    DVASPECT_CONTENT,
-    -1,
-    TYMED_HGLOBAL
-  };
-
-  // cycle thorugh all supported formats
-  for ( size_t n = 0; n < GetFormatCount(); n++ ) {
-    s_fmtMemory.cfFormat = GetFormat(n);
-    // NB: don't use SUCCEEDED macro here: QueryGetData returns 1 (whatever it
-    //     means) for file drag and drop
-    if ( pIDataSource->QueryGetData(&s_fmtMemory) == S_OK ) {
-      // remember this format: we'll later ask for data in it
-      m_pIDropTarget->SetSupportedFormat((unsigned int)s_fmtMemory.cfFormat);
-      return TRUE;
+    wxDataFormat format = GetSupportedFormat(m_pIDataSource);
+    if ( format == wxDF_INVALID ) {
+        // this is strange because IsAcceptedData() succeeded previously!
+        wxFAIL_MSG(wxT("strange - did supported formats list change?"));
+
+        return FALSE;
+    }
+
+    STGMEDIUM stm;
+    FORMATETC fmtMemory;
+    fmtMemory.cfFormat  = format;
+    fmtMemory.ptd       = NULL;
+    fmtMemory.dwAspect  = DVASPECT_CONTENT;
+    fmtMemory.lindex    = -1;
+    fmtMemory.tymed     = TYMED_HGLOBAL;  // TODO to add other media
+
+    bool rc = FALSE;
+
+    HRESULT hr = m_pIDataSource->GetData(&fmtMemory, &stm);
+    if ( SUCCEEDED(hr) ) {
+        IDataObject *dataObject = m_dataObject->GetInterface();
+
+        hr = dataObject->SetData(&fmtMemory, &stm, TRUE);
+        if ( SUCCEEDED(hr) ) {
+            rc = TRUE;
+        }
+        else {
+            wxLogLastError("IDataObject::SetData()");
+        }
+    }
+    else {
+        wxLogLastError("IDataObject::GetData()");
     }
-  }
 
-  return FALSE;
+    return rc;
 }
 
-// ============================================================================
-// wxTextDropTarget
-// ============================================================================
+// ----------------------------------------------------------------------------
+// callbacks used by wxIDropTarget
+// ----------------------------------------------------------------------------
 
-bool wxTextDropTarget::OnDrop(long x, long y, const void *pData)
+// we need a data source, so wxIDropTarget gives it to us using this function
+void wxDropTarget::SetDataSource(IDataObject *pIDataSource)
 {
-  return OnDropText(x, y, (const wxChar *)pData);
+    m_pIDataSource = pIDataSource;
 }
 
-size_t wxTextDropTarget::GetFormatCount() const
+// determine if we accept data of this type
+bool wxDropTarget::IsAcceptedData(IDataObject *pIDataSource) const
 {
-  return 1;
+    return GetSupportedFormat(pIDataSource) != wxDF_INVALID;
 }
 
-wxDataFormat wxTextDropTarget::GetFormat(size_t WXUNUSED(n)) const
+// ----------------------------------------------------------------------------
+// helper functions
+// ----------------------------------------------------------------------------
+
+wxDataFormat wxDropTarget::GetSupportedFormat(IDataObject *pIDataSource) const
 {
-  return wxDF_TEXT;
+    // this strucutre describes a data of any type (first field will be
+    // changing) being passed through global memory block.
+    static FORMATETC s_fmtMemory = {
+        0,
+        NULL,
+        DVASPECT_CONTENT,
+        -1,
+        TYMED_HGLOBAL       // TODO is it worth supporting other tymeds here?
+    };
+
+    // get the list of supported formats
+    size_t nFormats = m_dataObject->GetFormatCount(wxDataObject::Set);
+    wxDataFormat format, *formats;
+    formats = nFormats == 1 ? &format :  new wxDataFormat[nFormats];
+
+    m_dataObject->GetAllFormats(formats, wxDataObject::Set);
+
+    // cycle through all supported formats
+    size_t n;
+    for ( n = 0; n < nFormats; n++ ) {
+        s_fmtMemory.cfFormat = formats[n];
+
+        // NB: don't use SUCCEEDED macro here: QueryGetData returns S_FALSE
+        //     for file drag and drop (format == CF_HDROP)
+        if ( pIDataSource->QueryGetData(&s_fmtMemory) == S_OK ) {
+            format = formats[n];
+
+            break;
+        }
+    }
+
+    if ( formats != &format ) {
+        // free memory if we allocated it
+        delete [] formats;
+    }
+
+    return n < nFormats ? format : wxDF_INVALID;
 }
 
-// ============================================================================
-// wxFileDropTarget
-// ============================================================================
+// ----------------------------------------------------------------------------
+// wxTextDropTarget
+// ----------------------------------------------------------------------------
 
-bool wxFileDropTarget::OnDrop(long x, long y, const void *pData)
+wxTextDropTarget::wxTextDropTarget()
+                : wxDropTarget(new wxTextDataObject)
 {
-  // the documentation states that the first member of DROPFILES structure
-  // is a "DWORD offset of double NUL terminated file list". What they mean by
-  // this (I wonder if you see it immediately) is that the list starts at
-  // ((char *)&(pDropFiles.pFiles)) + pDropFiles.pFiles. We're also advised to
-  // use DragQueryFile to work with this structure, but not told where and how
-  // to get HDROP.
-  HDROP hdrop = (HDROP)pData;   // NB: it works, but I'm not sure about it
-
-  // get number of files (magic value -1)
-  UINT nFiles = ::DragQueryFile(hdrop, (unsigned)-1, NULL, 0u);
-
-  // for each file get the length, allocate memory and then get the name
-  wxChar **aszFiles = new wxChar *[nFiles];
-  UINT len, n;
-  for ( n = 0; n < nFiles; n++ ) {
-    // +1 for terminating NUL
-    len = ::DragQueryFile(hdrop, n, NULL, 0) + 1;
-
-    aszFiles[n] = new wxChar[len];
-
-    UINT len2 = ::DragQueryFile(hdrop, n, aszFiles[n], len);
-    if ( len2 != len - 1 ) {
-      wxLogDebug(wxT("In wxFileDropTarget::OnDrop DragQueryFile returned %d "
-                    "characters, %d expected."), len2, len - 1);
-    }
-  }
-
-  bool bResult = OnDropFiles(x, y, nFiles, (const wxChar**) aszFiles);
+}
 
-  // free memory
-  for ( n = 0; n < nFiles; n++ ) {
-    delete [] aszFiles[n];
-  }
-  delete [] aszFiles;
+bool wxTextDropTarget::OnData(wxCoord x, wxCoord y)
+{
+    if ( !GetData() )
+        return FALSE;
 
-  return bResult;
+    return OnDropText(x, y, ((wxTextDataObject *)m_dataObject)->GetText());
 }
 
-size_t wxFileDropTarget::GetFormatCount() const
+// ----------------------------------------------------------------------------
+// wxFileDropTarget
+// ----------------------------------------------------------------------------
+
+wxFileDropTarget::wxFileDropTarget()
+                : wxDropTarget(new wxFileDataObject)
 {
-  return 1;
 }
 
-wxDataFormat wxFileDropTarget::GetFormat(size_t WXUNUSED(n)) const
+bool wxFileDropTarget::OnData(wxCoord x, wxCoord y)
 {
-#ifdef __WIN32__
-  return wxDF_FILENAME;
-#else
-  // TODO: how to implement this in WIN16?
-  return wxDF_TEXT;
-#endif
+    if ( !GetData() )
+        return FALSE;
+
+    return OnDropFiles(x, y,
+                       ((wxFileDataObject *)m_dataObject)->GetFilenames());
 }
 
 #endif
index c5134276101243c00b248836378e1a18ec86c903..a5f6e4cef24b59c389c88e399deff419ac0652a7 100644 (file)
@@ -54,9 +54,8 @@
     #include "wx/ownerdrw.h"
 #endif
 
-#if     wxUSE_DRAG_AND_DROP
-    #include "wx/dataobj.h"
-    #include "wx/msw/ole/droptgt.h"
+#if wxUSE_DRAG_AND_DROP
+    #include "wx/dnd.h"
 #endif
 
 #include "wx/menuitem.h"
@@ -1215,7 +1214,7 @@ void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags)
     wxSize size(-1, -1);
     if ( width == -1 )
     {
-        if ( sizeFlags && wxSIZE_AUTO_WIDTH )
+        if ( sizeFlags & wxSIZE_AUTO_WIDTH )
         {
             size = DoGetBestSize();
             width = size.x;
@@ -1229,7 +1228,7 @@ void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 
     if ( height == -1 )
     {
-        if ( sizeFlags && wxSIZE_AUTO_HEIGHT )
+        if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
         {
             if ( size.x == -1 )
             {