From 9e2896e5c8944c5f5227fa080e1b781c4a6f2600 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 21 Oct 1999 01:58:57 +0000 Subject: [PATCH] wxDataObject changes - ok for MSW, still not for GTK/Motif/... git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4090 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/clipbrd.h | 2 +- include/wx/dataobj.h | 31 ++-- include/wx/defs.h | 42 ++--- include/wx/dnd.h | 18 +- include/wx/gtk/dnd.h | 174 +++++++++++++------ include/wx/gtk1/dnd.h | 174 +++++++++++++------ include/wx/msw/ole/dataobj.h | 110 +----------- include/wx/msw/ole/dropsrc.h | 2 +- include/wx/msw/ole/droptgt.h | 72 ++++---- samples/dnd/dnd.cpp | 126 +++++++++----- src/common/appcmn.cpp | 1 + src/common/dobjcmn.cpp | 10 +- src/msw/clipbrd.cpp | 4 +- src/msw/ole/dataobj.cpp | 294 +++++++++++++++++++++++++------- src/msw/ole/dropsrc.cpp | 15 +- src/msw/ole/droptgt.cpp | 315 +++++++++++++++++++---------------- src/msw/window.cpp | 9 +- 17 files changed, 831 insertions(+), 568 deletions(-) diff --git a/include/wx/clipbrd.h b/include/wx/clipbrd.h index 6ce90e1982..ad50734933 100644 --- a/include/wx/clipbrd.h +++ b/include/wx/clipbrd.h @@ -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; } diff --git a/include/wx/dataobj.h b/include/wx/dataobj.h index 9ef5f2bc7f..572b4f12d2 100644 --- a/include/wx/dataobj.h +++ b/include/wx/dataobj.h @@ -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; }; diff --git a/include/wx/defs.h b/include/wx/defs.h index 0eb6c98144..9669936041 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -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 */ diff --git a/include/wx/dnd.h b/include/wx/dnd.h index c201cf9992..36d3e506cd 100644 --- a/include/wx/dnd.h +++ b/include/wx/dnd.h @@ -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__) diff --git a/include/wx/gtk/dnd.h b/include/wx/gtk/dnd.h index c43eeca35b..c67cb053e8 100644 --- a/include/wx/gtk/dnd.h +++ b/include/wx/gtk/dnd.h @@ -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; diff --git a/include/wx/gtk1/dnd.h b/include/wx/gtk1/dnd.h index c43eeca35b..c67cb053e8 100644 --- a/include/wx/gtk1/dnd.h +++ b/include/wx/gtk1/dnd.h @@ -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; diff --git a/include/wx/msw/ole/dataobj.h b/include/wx/msw/ole/dataobj.h index 09dff76e96..fe47ce3bf3 100644 --- a/include/wx/msw/ole/dataobj.h +++ b/include/wx/msw/ole/dataobj.h @@ -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 - diff --git a/include/wx/msw/ole/dropsrc.h b/include/wx/msw/ole/dropsrc.h index aa9283f65c..36badcc6a1 100644 --- a/include/wx/msw/ole/dropsrc.h +++ b/include/wx/msw/ole/dropsrc.h @@ -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! diff --git a/include/wx/msw/ole/droptgt.h b/include/wx/msw/ole/droptgt.h index 1a7716f2a5..2e4a4f4f98 100644 --- a/include/wx/msw/ole/droptgt.h +++ b/include/wx/msw/ole/droptgt.h @@ -9,9 +9,6 @@ // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// -// ============================================================================ -// prolog -// ============================================================================ #ifndef _WX_OLEDROPTGT_H #define _WX_OLEDROPTGT_H @@ -20,12 +17,13 @@ #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 diff --git a/samples/dnd/dnd.cpp b/samples/dnd/dnd.cpp index 9ce9518b12..ebadcfcd0c 100644 --- a/samples/dnd/dnd.cpp +++ b/samples/dnd/dnd.cpp @@ -43,15 +43,12 @@ // 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 // ---------------------------------------------------------------------------- diff --git a/src/common/appcmn.cpp b/src/common/appcmn.cpp index 33d0cc1956..8cb28408e7 100644 --- a/src/common/appcmn.cpp +++ b/src/common/appcmn.cpp @@ -33,6 +33,7 @@ #endif #include "wx/thread.h" +#include "wx/clipbrd.h" // =========================================================================== // implementation diff --git a/src/common/dobjcmn.cpp b/src/common/dobjcmn.cpp index f806dcdec6..9c5e5ddc39 100644 --- a/src/common/dobjcmn.cpp +++ b/src/common/dobjcmn.cpp @@ -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; } diff --git a/src/msw/clipbrd.cpp b/src/msw/clipbrd.cpp index a24d4c3c58..f8287de98a 100644 --- a/src/msw/clipbrd.cpp +++ b/src/msw/clipbrd.cpp @@ -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; diff --git a/src/msw/ole/dataobj.cpp b/src/msw/ole/dataobj.cpp index 14ae6ed6a8..46cfd66c4b 100644 --- a/src/msw/ole/dataobj.cpp +++ b/src/msw/ole/dataobj.cpp @@ -58,6 +58,10 @@ 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) diff --git a/src/msw/ole/dropsrc.cpp b/src/msw/ole/dropsrc.cpp index bd296c8abb..3ddecc92ea 100644 --- a/src/msw/ole/dropsrc.cpp +++ b/src/msw/ole/dropsrc.cpp @@ -36,17 +36,17 @@ #if wxUSE_DRAG_AND_DROP #include "wx/log.h" -#include "wx/dataobj.h" -#include "wx/msw/ole/dropsrc.h" +#include "wx/dnd.h" #include + #ifdef wxUSE_NORLANDER_HEADERS -#include + #include #endif #ifndef __WIN32__ - #include - #include + #include + #include #endif #include @@ -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, diff --git a/src/msw/ole/droptgt.cpp b/src/msw/ole/droptgt.cpp index 003a29891a..c9f5feb506 100644 --- a/src/msw/ole/droptgt.cpp +++ b/src/msw/ole/droptgt.cpp @@ -42,8 +42,7 @@ #include #endif -#include "wx/dataobj.h" -#include "wx/msw/ole/droptgt.h" +#include "wx/dnd.h" #ifndef __WIN32__ #include @@ -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 diff --git a/src/msw/window.cpp b/src/msw/window.cpp index c513427610..a5f6e4cef2 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -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 ) { -- 2.45.2