<wx/gdicmn.h>
+\membersection{::wxEnableTopLevelWindows}\label{wxenabletoplevelwindows}
+
+\func{void}{wxEnableTopLevelWindow}{\param{bool}{ enable = TRUE}}
+
+This function enables or disables all top level windows. It is used by
+\helpref{::wxSafeYield}{wxsafeyield}.
+
+\wxheading{Include files}
+
+<wx/utils.h>
+
\membersection{::wxEntry}\label{wxentry}
This initializes wxWindows in a platform-dependent way. Use this if you
<wx/app.h>
-\membersection{::wxError}\label{wxerror}
+\membersection{::wxEndBusyCursor}\label{wxendbusycursor}
-\func{void}{wxError}{\param{const wxString\& }{msg}, \param{const wxString\& }{title = "wxWindows Internal Error"}}
+\func{void}{wxEndBusyCursor}{\void}
-Displays {\it msg} and continues. This writes to standard error under
-Unix, and pops up a message box under Windows. Used for internal
-wxWindows errors. See also \helpref{wxFatalError}{wxfatalerror}.
+Changes the cursor back to the original cursor, for all windows in the application.
+Use with \helpref{wxBeginBusyCursor}{wxbeginbusycursor}.
+
+See also \helpref{wxIsBusy}{wxisbusy}, \helpref{wxBusyCursor}{wxbusycursor}.
\wxheading{Include files}
<wx/utils.h>
-\membersection{::wxEndBusyCursor}\label{wxendbusycursor}
-
-\func{void}{wxEndBusyCursor}{\void}
+\membersection{::wxError}\label{wxerror}
-Changes the cursor back to the original cursor, for all windows in the application.
-Use with \helpref{wxBeginBusyCursor}{wxbeginbusycursor}.
+\func{void}{wxError}{\param{const wxString\& }{msg}, \param{const wxString\& }{title = "wxWindows Internal Error"}}
-See also \helpref{wxIsBusy}{wxisbusy}, \helpref{wxBusyCursor}{wxbusycursor}.
+Displays {\it msg} and continues. This writes to standard error under
+Unix, and pops up a message box under Windows. Used for internal
+wxWindows errors. See also \helpref{wxFatalError}{wxfatalerror}.
\wxheading{Include files}
<wx/utils.h>
+\membersection{::wxPostEvent}\label{wxpostevent}
+
+\func{void}{wxPostEvent}{\param{wxEvtHandler *}{dest}, \param{wxEvent\& }{event}}
+
+This function posts the event to the specified {\it dest} object. The
+difference between sending an event and posting it is that in the first case
+the event is processed before the function returns (in wxWindows, event sending
+is done with \helpref{ProcessEvent}{wxevthandlerprocessevent} function), but in
+the second, the function returns immediately and the event will be processed
+sometime later - usually during the next even loop iteration.
+
+Note that a copy of the {\it event} is made by the function, so the original
+copy can be deleted as soon as function returns. This function can also be used
+to send events between different threads safely.
+
+\wxheading{Include files}
+
+<wx/app.h>
+
\membersection{::wxSafeYield}\label{wxsafeyield}
\func{bool}{wxSafeYield}{\param{wxWindow*}{ win = NULL}}
<wx/utils.h>
-\membersection{::wxEnableTopLevelWindows}\label{wxenabletoplevelwindows}
-
-\func{void}{wxEnableTopLevelWindow}{\param{bool}{ enable = TRUE}}
-
-This function enables or disables all top level windows. It is used by
-\helpref{::wxSafeYield}{wxsafeyield}.
-
-\wxheading{Include files}
-
-<wx/utils.h>
-
-
\membersection{::wxSetDisplayName}\label{wxsetdisplayname}
\func{void}{wxSetDisplayName}{\param{const wxString\& }{displayName}}
\wxheading{Include files}
-<wx/utils.h>
+<wx/app.h> or <wx/utils.h>
\section{Macros}\label{macros}
[OPTIONS]
-BMROOT=d:\wx2\wxWind~1\docs/latex/wx ; Assume that bitmaps are where the source is
+BMROOT=. ; Assume that bitmaps are where the source is
TITLE=wxWindows Manual
CONTENTS=Contents
COMPRESS=HIGH
[FILES]
-wx.rtf
+Wx.rtf
[CONFIG]
-CreateButton("Up", "&Up", "JumpId(`wx.hlp', `Contents')")
+CreateButton("Up", "&Up", "JumpId(`Wx.hlp', `Contents')")
BrowseButtons()
[MAP]
// Yield to other apps/messages
extern bool WXDLLEXPORT wxYield();
+// Post a message to the given eventhandler which will be processed during the
+// next event loop iteration
+inline void WXDLLEXPORT wxPostEvent(wxEvtHandler *dest, wxEvent& event)
+{
+ wxCHECK_RET( dest, wxT("need an object to post event to in wxPostEvent") );
+
+ dest->AddPendingEvent(event);
+}
+
#endif // wxUSE_GUI
// console applications may avoid using DECLARE_APP and IMPLEMENT_APP macros
wxEVT_COMPARE_ITEM
*/
+// ============================================================================
+// event handler and related classes
+// ============================================================================
+
typedef void (wxObject::*wxObjectEventFunction)(wxEvent&);
struct WXDLLEXPORT wxEventTableEntry
void SetNextHandler(wxEvtHandler *handler) { m_nextHandler = handler; }
void SetPreviousHandler(wxEvtHandler *handler) { m_previousHandler = handler; }
- void SetEvtHandlerEnabled(bool en) { m_enabled = en; }
+ void SetEvtHandlerEnabled(bool enabled) { m_enabled = enabled; }
bool GetEvtHandlerEnabled() const { return m_enabled; }
-#if WXWIN_COMPATIBILITY_2
- virtual void OnCommand(wxWindow& WXUNUSED(win),
- wxCommandEvent& WXUNUSED(event))
- {
- wxFAIL_MSG(wxT("shouldn't be called any more"));
- }
+ // process an event right now
+ virtual bool ProcessEvent(wxEvent& event);
- // Called if child control has no callback function
- virtual long Default()
- { return GetNextHandler() ? GetNextHandler()->Default() : 0; };
-#endif // WXWIN_COMPATIBILITY_2
+ // add an event to be processed later
+ void AddPendingEvent(wxEvent& event);
-#if WXWIN_COMPATIBILITY
- virtual bool OnClose();
-#endif
+ // process all pending events
+ void ProcessPendingEvents();
+ // add a
#if wxUSE_THREADS
bool ProcessThreadEvent(wxEvent& event);
- void ProcessPendingEvents();
#endif
- virtual bool ProcessEvent(wxEvent& event);
- virtual bool SearchEventTable(wxEventTable& table, wxEvent& event);
// Dynamic association of a member function handler with the event handler,
// id and event type
wxObject *userData = (wxObject *) NULL )
{ Connect(id, -1, eventType, func, userData); }
+ // implementation from now on
+ virtual bool SearchEventTable(wxEventTable& table, wxEvent& event);
bool SearchDynamicEventTable( wxEvent& event );
#if wxUSE_THREADS
void ClearEventLocker() { delete m_eventsLocker; m_eventsLocker = NULL; };
#endif
+ // old stuff
+
+#if WXWIN_COMPATIBILITY_2
+ virtual void OnCommand(wxWindow& WXUNUSED(win),
+ wxCommandEvent& WXUNUSED(event))
+ {
+ wxFAIL_MSG(wxT("shouldn't be called any more"));
+ }
+
+ // Called if child control has no callback function
+ virtual long Default()
+ { return GetNextHandler() ? GetNextHandler()->Default() : 0; };
+#endif // WXWIN_COMPATIBILITY_2
+
+#if WXWIN_COMPATIBILITY
+ virtual bool OnClose();
+#endif
+
private:
- static const wxEventTableEntry sm_eventTableEntries[];
+ static const wxEventTableEntry sm_eventTableEntries[];
protected:
static const wxEventTable sm_eventTable;
protected:
wxEvtHandler* m_nextHandler;
wxEvtHandler* m_previousHandler;
- bool m_enabled; // Is event handler enabled?
wxList* m_dynamicEvents;
wxList* m_pendingEvents;
#if wxUSE_THREADS
// optimization: instead of using costly IsKindOf() to decide whether we're
// a window (which is true in 99% of cases), use this flag
bool m_isWindow;
+
+ // Is event handler enabled?
+ bool m_enabled;
};
typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&);
#define EVT_UPDATE_UI(id, func) \
{ wxEVT_UPDATE_UI, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxUpdateUIEventFunction) & func, (wxObject *) NULL },\
+// ----------------------------------------------------------------------------
+// Global data
+// ----------------------------------------------------------------------------
+
+// for pending event processing - notice that there is intentionally no
+// WXDLLEXPORT here
+extern wxList *wxPendingEvents;
+#if wxUSE_THREADS
+ extern wxCriticalSection *wxPendingEventsLocker;
+#endif
+
// ----------------------------------------------------------------------------
// Helper functions
// ----------------------------------------------------------------------------
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
+
+ /* 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
+ and then call RequestData() to indicate the format
you request. */
virtual bool OnDrop( long x, long 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 );
/* called to query what formats are available */
bool IsSupported( wxDataFormat format );
-
+
/* fill data with data from the dragging source */
bool GetData( wxDataObject *data );
// implementation
-
+
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; }
virtual bool OnMove( long x, long y );
virtual bool OnDrop( long x, long y );
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;
-
+
};
//-------------------------------------------------------------------------
wxPrivateDropTarget();
/* see SetId() below for explanation */
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 );
-
+
/* you have to override OnDropData to get at the data */
virtual bool OnDropData( long x, long y, void *data, size_t size ) = 0;
-
+
/* the string ID identifies the format of clipboard or DnD data. a word
processor would e.g. add a wxTextDataObject and a wxPrivateDataObject
to the clipboard - the latter with the Id "application/wxword" or
"image/png". */
void SetId( const wxString& id ) { m_id = id; }
wxString GetId() { return m_id; }
-
+
private:
wxString m_id;
class wxFileDropTarget: public wxDropTarget
{
public:
-
+
wxFileDropTarget() {}
-
+
virtual bool OnMove( long x, long y );
virtual bool OnDrop( long x, long y );
virtual bool OnData( long x, long y );
-
+
/* you have to override OnDropFiles to get at the file names */
virtual bool OnDropFiles( long x, long y, size_t nFiles, const wxChar * const aszFiles[] ) = 0;
/* constructor. set data later with SetData() */
wxDropSource( wxWindow *win, const wxIcon &go = wxNullIcon, const wxIcon &stop = wxNullIcon );
-
+
/* constructor for setting one data object */
- wxDropSource( wxDataObject *data, wxWindow *win, const wxIcon &go = wxNullIcon, const wxIcon &stop = wxNullIcon );
-
+ wxDropSource( wxDataObject& data, wxWindow *win, const wxIcon &go = wxNullIcon, const wxIcon &stop = wxNullIcon );
+
/* constructor for setting several data objects via wxDataBroker */
wxDropSource( wxDataBroker *data, wxWindow *win );
~wxDropSource();
-
+
/* set several dataobjects via wxDataBroker */
void SetData( wxDataBroker *data );
/* set one dataobject */
+ void SetData( wxDataObject& data );
+
+ // this one isn't portable to wxMSW -- deprecated
void SetData( wxDataObject *data );
/* start drag action */
wxDragResult DoDragDrop( bool bAllowMove = FALSE );
-
+
/* override to give feedback */
virtual bool GiveFeedback( wxDragResult WXUNUSED(effect), bool WXUNUSED(bScrolling) ) { return TRUE; }
-
+
/* GTK implementation */
-
+
void RegisterWindow();
void UnregisterWindow();
-
+
GtkWidget *m_widget;
wxWindow *m_window;
wxDragResult m_retValue;
wxDataBroker *m_data;
-
+
wxCursor m_defaultCursor;
wxCursor m_goaheadCursor;
-
+
wxIcon m_goIcon;
wxIcon m_stopIcon;
-
+
bool m_waiting;
};
// wxUSE_DRAG_AND_DROP
-#endif
+#endif
//__GTKDNDH__
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
+
+ /* 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
+ and then call RequestData() to indicate the format
you request. */
virtual bool OnDrop( long x, long 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 );
/* called to query what formats are available */
bool IsSupported( wxDataFormat format );
-
+
/* fill data with data from the dragging source */
bool GetData( wxDataObject *data );
// implementation
-
+
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; }
virtual bool OnMove( long x, long y );
virtual bool OnDrop( long x, long y );
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;
-
+
};
//-------------------------------------------------------------------------
wxPrivateDropTarget();
/* see SetId() below for explanation */
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 );
-
+
/* you have to override OnDropData to get at the data */
virtual bool OnDropData( long x, long y, void *data, size_t size ) = 0;
-
+
/* the string ID identifies the format of clipboard or DnD data. a word
processor would e.g. add a wxTextDataObject and a wxPrivateDataObject
to the clipboard - the latter with the Id "application/wxword" or
"image/png". */
void SetId( const wxString& id ) { m_id = id; }
wxString GetId() { return m_id; }
-
+
private:
wxString m_id;
class wxFileDropTarget: public wxDropTarget
{
public:
-
+
wxFileDropTarget() {}
-
+
virtual bool OnMove( long x, long y );
virtual bool OnDrop( long x, long y );
virtual bool OnData( long x, long y );
-
+
/* you have to override OnDropFiles to get at the file names */
virtual bool OnDropFiles( long x, long y, size_t nFiles, const wxChar * const aszFiles[] ) = 0;
/* constructor. set data later with SetData() */
wxDropSource( wxWindow *win, const wxIcon &go = wxNullIcon, const wxIcon &stop = wxNullIcon );
-
+
/* constructor for setting one data object */
- wxDropSource( wxDataObject *data, wxWindow *win, const wxIcon &go = wxNullIcon, const wxIcon &stop = wxNullIcon );
-
+ wxDropSource( wxDataObject& data, wxWindow *win, const wxIcon &go = wxNullIcon, const wxIcon &stop = wxNullIcon );
+
/* constructor for setting several data objects via wxDataBroker */
wxDropSource( wxDataBroker *data, wxWindow *win );
~wxDropSource();
-
+
/* set several dataobjects via wxDataBroker */
void SetData( wxDataBroker *data );
/* set one dataobject */
+ void SetData( wxDataObject& data );
+
+ // this one isn't portable to wxMSW -- deprecated
void SetData( wxDataObject *data );
/* start drag action */
wxDragResult DoDragDrop( bool bAllowMove = FALSE );
-
+
/* override to give feedback */
virtual bool GiveFeedback( wxDragResult WXUNUSED(effect), bool WXUNUSED(bScrolling) ) { return TRUE; }
-
+
/* GTK implementation */
-
+
void RegisterWindow();
void UnregisterWindow();
-
+
GtkWidget *m_widget;
wxWindow *m_window;
wxDragResult m_retValue;
wxDataBroker *m_data;
-
+
wxCursor m_defaultCursor;
wxCursor m_goaheadCursor;
-
+
wxIcon m_goIcon;
wxIcon m_stopIcon;
-
+
bool m_waiting;
};
// wxUSE_DRAG_AND_DROP
-#endif
+#endif
//__GTKDNDH__
virtual bool ProcessMessage(WXMSG* pMsg);
void DeletePendingObjects();
bool ProcessIdle();
-#if wxUSE_THREADS
void ProcessPendingEvents();
-#endif
int GetComCtl32Version() const;
public:
#ifndef _WX_OLEDATAOBJ_H
#define _WX_OLEDATAOBJ_H
-#include "wx/bitmap.h"
// ----------------------------------------------------------------------------
// wxDataFormat identifies the single format of data
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// wxDataObject is a "smart" and polymorphic piece of data.
//
-// TODO it's currently "read-only" from COM point of view, i.e. we don't support
-// SetData. We don't support all advise functions neither (but it's easy to
-// do if we really want them)
+// TODO it's currently "read-only" from COM point of view, i.e. we don't
+// support SetData. We don't support all advise functions neither (but
+// it's easy to do if we really want them)
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxDataObject
{
public:
- // function to return symbolic name of clipboard format (debug messages)
- static const char *GetFormatName(wxDataFormat format);
-
- // ctor & dtor
- wxDataObject();
- virtual ~wxDataObject();
-
- // pure virtuals to override
- // get the best suited format for our data
- virtual wxDataFormat GetPreferredFormat() const = 0;
- // decide if we support this format (should be one of values of
- // wxDataFormatId enumerations or a user-defined format)
- virtual bool IsSupportedFormat(wxDataFormat format) const = 0;
- // get the (total) size of data
- virtual size_t GetDataSize() const = 0;
- // copy raw data to provided pointer
- virtual void GetDataHere(void *pBuf) const = 0;
-
- // accessors
- // retrieve IDataObject interface (for other OLE related classes)
- IDataObject *GetInterface() const { return m_pIDataObject; }
-
- ////// wxGTK compatibility: hopefully to become the preferred API.
- virtual wxDataFormat GetFormat() const { return GetPreferredFormat(); }
+ // ctor & dtor
+ wxDataObject();
+ virtual ~wxDataObject();
+
+ // pure virtuals to override
+ // get the best suited format for our data
+ virtual wxDataFormat GetPreferredFormat() const = 0;
+ // get the number of formats we support
+ virtual size_t GetFormatCount() const
+ { return 1; }
+ // return all formats in the provided array (of size GetFormatCount())
+ virtual void GetAllFormats(wxDataFormat *formats) 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 void GetDataHere(const wxDataFormat& format, void *pBuf) const = 0;
+
+ // accessors
+ // 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;
+
+#ifdef __WXDEBUG__
+ // function to return symbolic name of clipboard format (for debug messages)
+ static const char *GetFormatName(wxDataFormat format);
+#endif // Debug
private:
- IDataObject *m_pIDataObject; // pointer to the COM interface
+ 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(wxDataFormat format) const
- { return format == wxDF_TEXT || format == wxDF_LOCALE; }
- virtual size_t GetDataSize() const
- { return m_strText.Len() + 1; } // +1 for trailing '\0'of course
- virtual void GetDataHere(void *pBuf) const
- { memcpy(pBuf, m_strText.c_str(), GetDataSize()); }
-
- ////// wxGTK compatibility: hopefully to become the preferred API.
- void SetText(const wxString& strText) { m_strText = strText; }
- wxString GetText() const { return m_strText; }
- virtual wxDataFormat GetFormat() const { return wxDF_TEXT; }
+ // 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 void GetDataHere(const wxDataFormat& format, void *pBuf) const
+ { memcpy(pBuf, m_strText.c_str(), GetDataSize(format)); }
+
+ // additional helpers
+ void SetText(const wxString& strText) { m_strText = strText; }
+ wxString GetText() const { return m_strText; }
private:
- wxString m_strText;
+ wxString m_strText;
};
// ----------------------------------------------------------------------------
-// @@@ TODO: wx{Bitmap|Metafile|...}DataObject
+// TODO: wx{Bitmap|Metafile|...}DataObject
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// TODO: implement OLE side of things. At present, it's just for clipboard
// use.
+#include "wx/bitmap.h"
+
class WXDLLEXPORT wxBitmapDataObject : public wxDataObject
{
public:
- // ctors
- wxBitmapDataObject() {}
- wxBitmapDataObject(const wxBitmap& bitmap): m_bitmap(bitmap) {}
- void SetBitmap(const wxBitmap& bitmap) { m_bitmap = bitmap; }
- wxBitmap GetBitmap() const { return m_bitmap; }
-
- virtual wxDataFormat GetFormat() const { return wxDF_BITMAP; }
-
- // implement base class pure virtuals
- virtual wxDataFormat GetPreferredFormat() const
- { return wxDF_BITMAP; }
- virtual bool IsSupportedFormat(wxDataFormat format) const
- { return format == wxDF_BITMAP; }
- virtual size_t GetDataSize() const
- { wxASSERT(FALSE); return 0; } // BEMIMP
- virtual void GetDataHere(void *pBuf) const
- { wxASSERT(FALSE); } // BEMIMP
+ // 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 bool IsSupportedFormat(const wxDataFormat& format) const
+ { return format == wxDF_BITMAP; }
+ virtual size_t GetDataSize(const wxDataFormat& format) const;
+ virtual void GetDataHere(const wxDataFormat& format, void *pBuf) const;
private:
- wxBitmap m_bitmap;
+ wxBitmap m_bitmap;
};
// ----------------------------------------------------------------------------
#define _WX_OLEDROPSRC_H
#ifdef __GNUG__
-#pragma interface
+ #pragma interface
#endif
-#include "wx/window.h"
+
#if !wxUSE_DRAG_AND_DROP
#error "You should #define wxUSE_DRAG_AND_DROP to 1 to compile this file!"
#endif //WX_DRAG_DROP
// ----------------------------------------------------------------------------
// forward declarations
// ----------------------------------------------------------------------------
+
class wxIDropSource;
-class wxDataObject;
+class WXDLLEXPORT wxDataObject;
+class WXDLLEXPORT wxWindow;
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
enum wxDragResult
- {
+{
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
wxDragCancel // the operation was cancelled by user (not an error)
- };
+};
// ----------------------------------------------------------------------------
// wxDropSource is used to start the drag-&-drop operation on associated
// wxDataObject object. It's responsible for giving UI feedback while dragging.
// ----------------------------------------------------------------------------
+
class WXDLLEXPORT wxDropSource
{
public:
// ctors: if you use default ctor you must call SetData() later!
// NB: the "wxWindow *win" parameter is unused and is here only for wxGTK
- // compatibility
- wxDropSource(wxWindow *win = NULL);
- wxDropSource(wxDataObject& data, wxWindow *win = NULL);
+ // compatibility, as well as both icon parameters
+ wxDropSource(wxWindow *win = NULL,
+ const wxIcon &go = wxNullIcon,
+ const wxIcon &stop = wxNullIcon );
+ wxDropSource(wxDataObject& data,
+ wxWindow *win = NULL,
+ const wxIcon &go = wxNullIcon,
+ const wxIcon &stop = wxNullIcon );
void SetData(wxDataObject& data);
#include "wx/wx.h"
#endif
-#ifdef __WXMOTIF__
- #error Sorry, drag and drop is not yet implemented on wxMotif.
+#if !wxUSE_DRAG_AND_DROP
+ #error This sample requires drag and drop support in the library
#endif
#include "wx/intl.h"
#include "wx/filedlg.h"
#include "wx/image.h"
#include "wx/clipbrd.h"
+#include "wx/colordlg.h"
+#include "wx/resource.h"
#if defined(__WXGTK__) || defined(__WXMOTIF__)
#include "mondrian.xpm"
class DnDApp : public wxApp
{
public:
- bool OnInit();
+ virtual bool OnInit();
};
IMPLEMENT_APP(DnDApp);
// ----------------------------------------------------------------------------
-// Define a new frame type
+// Define a new frame type for the main frame
// ----------------------------------------------------------------------------
+
class DnDFrame : public wxFrame
{
public:
void OnQuit (wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnDrag (wxCommandEvent& event);
+ void OnNewFrame(wxCommandEvent& event);
void OnHelp (wxCommandEvent& event);
void OnLogClear(wxCommandEvent& event);
void OnCopy(wxCommandEvent& event);
wxBitmap m_bitmap;
};
+// ----------------------------------------------------------------------------
+// A shape is an example of application-specific data which may be transported
+// via drag-and-drop or clipboard: in our case, we have different geometric
+// shapes, each one with its own colour and position
+// ----------------------------------------------------------------------------
+
+class DnDShape
+{
+public:
+ enum Kind
+ {
+ None,
+ Triangle,
+ Rectangle,
+ Ellipse
+ };
+
+ DnDShape(const wxPoint& pos,
+ const wxSize& size,
+ const wxColour& col)
+ : m_pos(pos), m_size(size), m_col(col)
+ {
+ }
+
+ // the functions used for drag-and-drop: they dump and restore a shape into
+ // some bitwise-copiable data
+ //
+ // NB: here we profit from the fact that wxPoint, wxSize and wxColour are
+ // POD (plain old data) and so can be copied directly - but it wouldn't
+ // work for other types!
+ // ------------------------------------------------------------------------
+
+ // restore from buffer
+ static DnDShape *New(const void *buf);
+
+ virtual size_t GetDataSize() const
+ {
+ return sizeof(ShapeDump);
+ }
+
+ virtual void GetDataHere(void *buf) const
+ {
+ ShapeDump& dump = *(ShapeDump *)buf;
+ dump.x = m_pos.x;
+ dump.y = m_pos.y;
+ dump.w = m_size.x;
+ dump.h = m_size.y;
+ dump.r = m_col.Red();
+ dump.g = m_col.Green();
+ dump.b = m_col.Blue();
+ dump.k = GetKind();
+ }
+
+ // accessors
+ const wxPoint& GetPosition() const { return m_pos; }
+ const wxColour& GetColour() const { return m_col; }
+ const wxSize& GetSize() const { return m_size; }
+
+ // to implement in derived classes
+ virtual Kind GetKind() const = 0;
+
+ virtual void Draw(wxDC& dc) = 0
+ {
+ dc.SetPen(wxPen(m_col, 1, wxSOLID));
+ }
+
+protected:
+ wxPoint GetCentre() const
+ { return wxPoint(m_pos.x + m_size.x / 2, m_pos.y + m_size.y / 2); }
+
+ struct ShapeDump
+ {
+ int x, y, // position
+ w, h, // size
+ r, g, b, // colour
+ k; // kind
+ };
+
+ wxPoint m_pos;
+ wxSize m_size;
+ wxColour m_col;
+};
+
+class DnDTriangularShape : public DnDShape
+{
+public:
+ DnDTriangularShape(const wxPoint& pos,
+ const wxSize& size,
+ const wxColour& col)
+ : DnDShape(pos, size, col)
+ {
+ }
+
+ virtual Kind GetKind() const { return Triangle; }
+ virtual void Draw(wxDC& dc)
+ {
+ DnDShape::Draw(dc);
+
+ // well, it's a bit difficult to describe a triangle by position and
+ // size, but we're not doing geometry here, do we? ;-)
+ wxPoint p1(m_pos);
+ wxPoint p2(m_pos.x + m_size.x, m_pos.y);
+ wxPoint p3(m_pos.x, m_pos.y + m_size.y);
+
+ dc.DrawLine(p1, p2);
+ dc.DrawLine(p2, p3);
+ dc.DrawLine(p3, p1);
+
+ dc.FloodFill(GetCentre(), m_col, wxFLOOD_BORDER);
+ }
+};
+
+class DnDRectangularShape : public DnDShape
+{
+public:
+ DnDRectangularShape(const wxPoint& pos,
+ const wxSize& size,
+ const wxColour& col)
+ : DnDShape(pos, size, col)
+ {
+ }
+
+ virtual Kind GetKind() const { return Rectangle; }
+ virtual void Draw(wxDC& dc)
+ {
+ DnDShape::Draw(dc);
+
+ wxPoint p1(m_pos);
+ wxPoint p2(p1.x + m_size.x, p1.y);
+ wxPoint p3(p2.x, p2.y + m_size.y);
+ wxPoint p4(p1.x, p3.y);
+
+ dc.DrawLine(p1, p2);
+ dc.DrawLine(p2, p3);
+ dc.DrawLine(p3, p4);
+ dc.DrawLine(p4, p1);
+
+ dc.FloodFill(GetCentre(), m_col, wxFLOOD_BORDER);
+ }
+};
+
+class DnDEllipticShape : public DnDShape
+{
+public:
+ DnDEllipticShape(const wxPoint& pos,
+ const wxSize& size,
+ const wxColour& col)
+ : DnDShape(pos, size, col)
+ {
+ }
+
+ virtual Kind GetKind() const { return Ellipse; }
+ virtual void Draw(wxDC& dc)
+ {
+ DnDShape::Draw(dc);
+
+ dc.DrawEllipse(m_pos, m_size);
+
+ dc.FloodFill(GetCentre(), m_col, wxFLOOD_BORDER);
+ }
+};
+
+// ----------------------------------------------------------------------------
+// A wxDataObject specialisation for the application-specific data
+// ----------------------------------------------------------------------------
+
+static const char *shapeFormatId = "wxShape";
+
+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)
+ {
+ m_shape = shape;
+
+ // this string should uniquely identify our format, but is otherwise
+ // arbitrary
+ m_formatShape.SetId(shapeFormatId);
+
+ // we don't draw the shape to a bitmap until it's really needed (i.e.
+ // we're asked to do so)
+ m_hasBitmap = FALSE;
+ }
+
+ // implement base class pure virtuals
+ // ----------------------------------
+
+ virtual wxDataFormat GetPreferredFormat() const
+ {
+ return m_formatShape;
+ }
+
+ virtual size_t GetFormatCount() const
+ {
+ // +1 for our custom format
+ return m_dataobj.GetFormatCount() + 1;
+ }
+
+ virtual void GetAllFormats(wxDataFormat *formats) const
+ {
+ formats[0] = m_formatShape;
+ m_dataobj.GetAllFormats(&formats[1]);
+ }
+
+ virtual size_t GetDataSize(const wxDataFormat& format) const
+ {
+ if ( format == m_formatShape )
+ {
+ return m_shape->GetDataSize();
+ }
+ else
+ {
+ wxASSERT_MSG( format == wxDF_BITMAP, "unsupported format" );
+
+ if ( !m_hasBitmap )
+ CreateBitmap();
+
+ return m_dataobj.GetDataSize(format);
+ }
+ }
+
+ virtual void GetDataHere(const wxDataFormat& format, void *pBuf) const
+ {
+ if ( format == m_formatShape )
+ {
+ m_shape->GetDataHere(pBuf);
+ }
+ else
+ {
+ wxASSERT_MSG( format == wxDF_BITMAP, "unsupported format" );
+
+ if ( !m_hasBitmap )
+ CreateBitmap();
+
+ m_dataobj.GetDataHere(format, pBuf);
+ }
+ }
+
+private:
+ // creates a bitmap and assigns it to m_dataobj (also sets m_hasBitmap)
+ void CreateBitmap() const;
+
+ wxDataFormat m_formatShape; // our custom format
+
+ wxBitmapDataObject m_dataobj; // it handles bitmaps
+ bool m_hasBitmap; // true if m_dataobj has valid bitmap
+
+ DnDShape *m_shape; // our data
+};
+
+// ----------------------------------------------------------------------------
+// A dialog to edit shape properties
+// ----------------------------------------------------------------------------
+
+class DnDShapeDialog : public wxDialog
+{
+public:
+ DnDShapeDialog(wxFrame *parent, DnDShape *shape);
+
+ DnDShape *GetShape() const;
+
+ virtual bool TransferDataToWindow();
+ virtual bool TransferDataFromWindow();
+
+ void OnColour(wxCommandEvent& event);
+
+private:
+ // input
+ DnDShape *m_shape;
+
+ // output
+ DnDShape::Kind m_shapeKind;
+ wxPoint m_pos;
+ wxSize m_size;
+ wxColour m_col;
+
+ // controls
+ wxRadioBox *m_radio;
+ wxTextCtrl *m_textX,
+ *m_textY,
+ *m_textW,
+ *m_textH;
+
+ DECLARE_EVENT_TABLE()
+};
+
+// ----------------------------------------------------------------------------
+// A frame for the shapes which can be drag-and-dropped between frames
+// ----------------------------------------------------------------------------
+
+class DnDShapeFrame : public wxFrame
+{
+public:
+ DnDShapeFrame(wxFrame *parent);
+ ~DnDShapeFrame();
+
+ void SetShape(DnDShape *shape);
+
+ // callbacks
+ void OnDrag(wxMouseEvent& event);
+ void OnEdit(wxMouseEvent& event);
+ void OnPaint(wxPaintEvent& event);
+ void OnDrop(long x, long y, DnDShape *shape);
+
+private:
+ DnDShape *m_shape;
+
+ DECLARE_EVENT_TABLE()
+};
+
+// ----------------------------------------------------------------------------
+// wxDropTarget derivation for DnDShapes
+// ----------------------------------------------------------------------------
+
+class DnDShapeDropTarget : public wxDropTarget
+{
+public:
+ DnDShapeDropTarget(DnDShapeFrame *frame)
+ {
+ m_frame = frame;
+
+ // the same as used by DnDShapeDataObject
+ m_formatShape.SetId(shapeFormatId);
+ }
+
+ // override base class (pure) virtuals
+ virtual void OnEnter()
+ { 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)
+ {
+ m_frame->OnDrop(x, y, DnDShape::New(pData));
+
+ 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;
+};
+
// ----------------------------------------------------------------------------
// IDs for the menu commands
// ----------------------------------------------------------------------------
{
Menu_Quit = 1,
Menu_Drag,
+ Menu_NewFrame,
Menu_About = 101,
Menu_Help,
Menu_Clear,
Menu_HasText,
Menu_HasBitmap,
Menu_ToBeGreyed, /* for testing */
- Menu_ToBeDeleted /* for testing */
+ Menu_ToBeDeleted, /* for testing */
+ Button_Colour = 1001
};
BEGIN_EVENT_TABLE(DnDFrame, wxFrame)
EVT_MENU(Menu_Quit, DnDFrame::OnQuit)
EVT_MENU(Menu_About, DnDFrame::OnAbout)
EVT_MENU(Menu_Drag, DnDFrame::OnDrag)
+ EVT_MENU(Menu_NewFrame, DnDFrame::OnNewFrame)
EVT_MENU(Menu_Help, DnDFrame::OnHelp)
EVT_MENU(Menu_Clear, DnDFrame::OnLogClear)
EVT_MENU(Menu_Copy, DnDFrame::OnCopy)
EVT_PAINT( DnDFrame::OnPaint)
END_EVENT_TABLE()
- // `Main program' equivalent, creating windows and returning main app frame
+BEGIN_EVENT_TABLE(DnDShapeFrame, wxFrame)
+ EVT_RIGHT_DOWN(DnDShapeFrame::OnDrag)
+ EVT_LEFT_DCLICK(DnDShapeFrame::OnEdit)
+ EVT_PAINT(DnDShapeFrame::OnPaint)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(DnDShapeDialog, wxDialog)
+ EVT_BUTTON(Button_Colour, OnColour)
+END_EVENT_TABLE()
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// `Main program' equivalent, creating windows and returning main app frame
bool DnDApp::OnInit()
{
#if wxUSE_LIBPNG
SetTopWindow(frame);
+ wxDefaultResourceTable->ParseResourceFile("dnd.wxr");
+
return TRUE;
}
CreateStatusBar();
- // construct sub menu for testing
- wxMenu *sub_menu = new wxMenu;
- sub_menu->Append(Menu_Quit, "E&xit");
- sub_menu->Append(Menu_Quit, "E&xit");
- sub_menu->Append(Menu_Quit, "E&xit");
-
// construct menu
wxMenu *file_menu = new wxMenu;
file_menu->Append(Menu_Drag, "&Test drag...");
file_menu->AppendSeparator();
- file_menu->Append(Menu_Quit, "E&xit");
+ file_menu->Append(Menu_NewFrame, "&New frame\tCtrl-N");
file_menu->AppendSeparator();
- file_menu->Append( 0, "More exit menus", sub_menu);
+ file_menu->Append(Menu_Quit, "E&xit");
wxMenu *log_menu = new wxMenu;
log_menu->Append(Menu_Clear, "Clear");
clip_menu->AppendSeparator();
clip_menu->Append(Menu_HasText, "Clipboard has &text\tCtrl+T");
clip_menu->Append(Menu_HasBitmap, "Clipboard has a &bitmap\tCtrl+B");
-
+
wxMenuBar *menu_bar = new wxMenuBar;
menu_bar->Append(file_menu, "&File");
menu_bar->Append(log_menu, "&Log");
m_ctrlLog = new wxTextCtrl(this, -1, "", pos, size,
wxTE_MULTILINE | wxTE_READONLY |
wxSUNKEN_BORDER );
- // redirect log messages to the text window (don't forget to delete it!)
+
+ // redirect log messages to the text window and switch on OLE messages
+ // logging
+ wxLog::AddTraceMask(wxTRACE_OleCalls);
m_pLog = new wxLogTextCtrl(m_ctrlLog);
m_pLogPrev = wxLog::SetActiveTarget(m_pLog);
wxPaintDC dc(this);
dc.SetFont( wxFont( 24, wxDECORATIVE, wxNORMAL, wxNORMAL, FALSE, "charter" ) );
dc.DrawText( "Drag text from here!", 20, h-50 );
-
+
if (m_bitmap.Ok())
dc.DrawBitmap( m_bitmap, 280, h-120, TRUE );
}
wxTheClipboard->Close();
}
+void DnDFrame::OnNewFrame(wxCommandEvent& WXUNUSED(event))
+{
+ (new DnDShapeFrame(this))->Show(TRUE);
+
+ wxLogStatus(this, "Double click the new frame to select a shape for it");
+}
+
void DnDFrame::OnDrag(wxCommandEvent& WXUNUSED(event))
{
wxString strText = wxGetTextFromUser
void DnDFrame::OnLeftDown(wxMouseEvent &WXUNUSED(event) )
{
- if ( !m_strText.IsEmpty() )
+ if ( !m_strText.IsEmpty() )
{
// start drag operation
-#ifdef __WXMSW__
wxTextDataObject textData(m_strText);
- wxDropSource dragSource( textData, this );
-#else
- wxDropSource dragSource( new wxTextDataObject (m_strText), this, wxIcon(mondrian_xpm) );
-#endif
+ wxDropSource source(textData, this, wxICON(mondrian));
+
const char *pc;
- switch ( dragSource.DoDragDrop(TRUE) )
+ switch ( source.DoDragDrop(TRUE) )
{
case wxDragError: pc = "Error!"; break;
case wxDragNone: pc = "Nothing"; break;
menu->Append(Menu_Quit, "E&xit");
menu->Append(Menu_ToBeDeleted, "To be deleted");
menu->Append(Menu_ToBeGreyed, "To be greyed");
-
+
menu->Delete( Menu_ToBeDeleted );
menu->Enable( Menu_ToBeGreyed, FALSE );
#endif
if (dialog.ShowModal() != wxID_OK)
- {
+ {
wxLogMessage( _T("Aborted file open") );
return;
}
-
+
if (dialog.GetPath().IsEmpty())
- {
+ {
wxLogMessage( _T("Returned empty string.") );
return;
}
-
+
if (!wxFileExists(dialog.GetPath()))
{
wxLogMessage( _T("File doesn't exist.") );
return;
}
-
+
wxImage image;
- image.LoadFile( dialog.GetPath(),
+ image.LoadFile( dialog.GetPath(),
#ifdef __WXMSW__
wxBITMAP_TYPE_BMP
#else
);
if (!image.Ok())
{
- wxLogMessage( _T("Invalid image file...") );
+ wxLogError( _T("Invalid image file...") );
return;
}
-
- wxLogMessage( _T("Decoding image file...") );
+
+ wxLogStatus( _T("Decoding image file...") );
wxYield();
-
+
wxBitmap bitmap( image.ConvertToBitmap() );
if ( !wxTheClipboard->Open() )
wxLogMessage( _T("Creating wxBitmapDataObject...") );
wxYield();
-
+
if ( !wxTheClipboard->AddData(new wxBitmapDataObject(bitmap)) )
{
wxLogError(_T("Can't copy image to the clipboard."));
else
{
wxLogMessage(_T("Bitmap pasted from the clipboard") );
- m_bitmap = data.GetBitmap();
- Refresh();
+ m_bitmap = data.GetBitmap();
+ Refresh();
}
wxTheClipboard->Close();
return TRUE;
}
+
+// ----------------------------------------------------------------------------
+// DnDShapeDialog
+// ----------------------------------------------------------------------------
+
+DnDShapeDialog::DnDShapeDialog(wxFrame *parent, DnDShape *shape)
+{
+ m_shape = shape;
+
+ LoadFromResource(parent, "dialogShape");
+
+ m_textX = (wxTextCtrl *)wxFindWindowByName("textX", this);
+ m_textY = (wxTextCtrl *)wxFindWindowByName("textY", this);
+ m_textW = (wxTextCtrl *)wxFindWindowByName("textW", this);
+ m_textH = (wxTextCtrl *)wxFindWindowByName("textH", this);
+
+ m_radio = (wxRadioBox *)wxFindWindowByName("radio", this);
+}
+
+DnDShape *DnDShapeDialog::GetShape() const
+{
+ switch ( m_shapeKind )
+ {
+ default:
+ case DnDShape::None: return NULL;
+ case DnDShape::Triangle: return new DnDTriangularShape(m_pos, m_size, m_col);
+ case DnDShape::Rectangle: return new DnDRectangularShape(m_pos, m_size, m_col);
+ case DnDShape::Ellipse: return new DnDEllipticShape(m_pos, m_size, m_col);
+ }
+}
+
+bool DnDShapeDialog::TransferDataToWindow()
+{
+ if ( m_shape )
+ {
+ m_radio->SetSelection(m_shape->GetKind());
+ m_pos = m_shape->GetPosition();
+ m_size = m_shape->GetSize();
+ m_col = m_shape->GetColour();
+ }
+ else
+ {
+ m_radio->SetSelection(DnDShape::None);
+ m_pos = wxPoint(1, 1);
+ m_size = wxSize(100, 100);
+ }
+
+ m_textX->SetValue(wxString() << m_pos.x);
+ m_textY->SetValue(wxString() << m_pos.y);
+ m_textW->SetValue(wxString() << m_size.x);
+ m_textH->SetValue(wxString() << m_size.y);
+
+ return TRUE;
+}
+
+bool DnDShapeDialog::TransferDataFromWindow()
+{
+ m_shapeKind = (DnDShape::Kind)m_radio->GetSelection();
+
+ m_pos.x = atoi(m_textX->GetValue());
+ m_pos.y = atoi(m_textY->GetValue());
+ m_size.x = atoi(m_textW->GetValue());
+ m_size.y = atoi(m_textH->GetValue());
+
+ if ( !m_pos.x || !m_pos.y || !m_size.x || !m_size.y )
+ {
+ wxMessageBox("All sizes and positions should be non null!",
+ "Invalid shape", wxICON_HAND | wxOK, this);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void DnDShapeDialog::OnColour(wxCommandEvent& WXUNUSED(event))
+{
+ wxColourData data;
+ data.SetChooseFull(TRUE);
+ for (int i = 0; i < 16; i++)
+ {
+ wxColour colour(i*16, i*16, i*16);
+ data.SetCustomColour(i, colour);
+ }
+
+ wxColourDialog dialog(this, &data);
+ if ( dialog.ShowModal() == wxID_OK )
+ {
+ m_col = dialog.GetColourData().GetColour();
+ }
+}
+
+// ----------------------------------------------------------------------------
+// DnDShapeFrame
+// ----------------------------------------------------------------------------
+
+DnDShapeFrame::DnDShapeFrame(wxFrame *parent)
+ : wxFrame(parent, -1, "Shape Frame",
+ wxDefaultPosition, wxSize(250, 150))
+{
+ SetBackgroundColour(*wxWHITE);
+
+ CreateStatusBar();
+
+ SetStatusText("Double click the frame to create a shape");
+
+ SetDropTarget(new DnDShapeDropTarget(this));
+
+ m_shape = NULL;
+}
+
+DnDShapeFrame::~DnDShapeFrame()
+{
+ delete m_shape;
+}
+
+void DnDShapeFrame::SetShape(DnDShape *shape)
+{
+ delete m_shape;
+ m_shape = shape;
+ Refresh();
+}
+
+// callbacks
+void DnDShapeFrame::OnDrag(wxMouseEvent& event)
+{
+ if ( !m_shape )
+ {
+ event.Skip();
+
+ return;
+ }
+
+ // start drag operation
+ DnDShapeDataObject shapeData(m_shape);
+ wxDropSource source(shapeData, this, wxICON(mondrian));
+
+ const char *pc = NULL;
+ switch ( source.DoDragDrop(TRUE) )
+ {
+ default:
+ case wxDragError:
+ wxLogError("An error occured during drag and drop operation");
+ break;
+
+ case wxDragNone:
+ SetStatusText("Nothing happened");
+ break;
+
+ case wxDragCopy:
+ pc = "copied";
+ break;
+
+ case wxDragMove:
+ pc = "moved";
+ SetShape(NULL);
+ break;
+
+ case wxDragCancel:
+ SetStatusText("Drag and drop operation cancelled");
+ break;
+ }
+
+ if ( pc )
+ {
+ SetStatusText(wxString("Shape successfully ") + pc);
+ }
+ //else: status text already set
+}
+
+void DnDShapeFrame::OnEdit(wxMouseEvent& event)
+{
+ DnDShapeDialog dlg(this, m_shape);
+ if ( dlg.ShowModal() == wxID_OK )
+ {
+ SetShape(dlg.GetShape());
+
+ if ( m_shape )
+ {
+ SetStatusText("Right click now drag the shape to another frame");
+ }
+ }
+}
+
+void DnDShapeFrame::OnPaint(wxPaintEvent& event)
+{
+ if ( m_shape )
+ m_shape->Draw(wxPaintDC(this));
+ else
+ event.Skip();
+}
+
+void DnDShapeFrame::OnDrop(long x, long y, DnDShape *shape)
+{
+ wxString s;
+ s.Printf("Drop occured at (%ld, %ld)", x, y);
+ SetStatusText(s);
+
+ SetShape(shape);
+}
+
+// ----------------------------------------------------------------------------
+// DnDShape
+// ----------------------------------------------------------------------------
+
+DnDShape *DnDShape::New(const void *buf)
+{
+ const ShapeDump& dump = *(const ShapeDump *)buf;
+ switch ( dump.k )
+ {
+ case Triangle:
+ return new DnDTriangularShape(wxPoint(dump.x, dump.y),
+ wxSize(dump.w, dump.h),
+ wxColour(dump.r, dump.g, dump.b));
+
+ case Rectangle:
+ return new DnDRectangularShape(wxPoint(dump.x, dump.y),
+ wxSize(dump.w, dump.h),
+ wxColour(dump.r, dump.g, dump.b));
+
+ case Ellipse:
+ return new DnDEllipticShape(wxPoint(dump.x, dump.y),
+ wxSize(dump.w, dump.h),
+ wxColour(dump.r, dump.g, dump.b));
+
+ default:
+ wxFAIL_MSG("invalid shape!");
+ return NULL;
+ }
+}
+
+// ----------------------------------------------------------------------------
+// DnDShapeDataObject
+// ----------------------------------------------------------------------------
+
+void DnDShapeDataObject::CreateBitmap() const
+{
+ wxBitmap bitmap;
+ wxMemoryDC dc;
+ dc.SelectObject(bitmap);
+ m_shape->Draw(dc);
+ dc.SelectObject(wxNullBitmap);
+
+ DnDShapeDataObject *self = (DnDShapeDataObject *)this; // const_cast
+ self->m_dataobj.SetBitmap(bitmap);
+ self->m_hasBitmap = TRUE;
+}
+
+++ /dev/null
-# Microsoft Developer Studio Project File - Name="test" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 5.00
-# ** NICHT BEARBEITEN **
-
-# TARGTYPE "Win32 (x86) Application" 0x0101
-
-CFG=test - Win32 Release
-!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit\
- NMAKE
-!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den\
- Befehl
-!MESSAGE
-!MESSAGE NMAKE /f "test.mak".
-!MESSAGE
-!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
-!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
-!MESSAGE
-!MESSAGE NMAKE /f "test.mak" CFG="test - Win32 Release"
-!MESSAGE
-!MESSAGE Für die Konfiguration stehen zur Auswahl:
-!MESSAGE
-!MESSAGE "test - Win32 Release" (basierend auf "Win32 (x86) Application")
-!MESSAGE "test - Win32 Debug" (basierend auf "Win32 (x86) Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "test - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir ".\Release"
-# PROP BASE Intermediate_Dir ".\Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir ".\Release"
-# PROP Intermediate_Dir ".\Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
-# ADD CPP /nologo /w /W0 /GX /O2 /I "..\..\include" /D "__WXDEBUG__" /D "__WIN32__" /D "__WXMSW__" /D "__WIN95__" /D "STRICT" /D "__WINDOWS__" /YX /FD /D /c
-# ADD BASE MTL /nologo /D "NDEBUG" /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x407 /d "NDEBUG"
-# ADD RSC /l 0x407 /i "..\..\include" /d "WXDEBUG" /d "__WXMSW__"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib oldnames.lib comctl32.lib ctl3d32.lib odbc32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ..\..\debug\wxwin.lib ctl3d32.lib /nologo /subsystem:windows /incremental:yes /pdb:".\Debug/santis.pdb" /debug /machine:I386 /out:".\Debug/santis.exe"
-# SUBTRACT LINK32 /pdb:none
-
-!ELSEIF "$(CFG)" == "test - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir ".\Debug"
-# PROP BASE Intermediate_Dir ".\Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir ".\Debug"
-# PROP Intermediate_Dir ".\Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
-# ADD CPP /nologo /w /W0 /GX /Z7 /Od /I "..\..\include" /D "__WXDEBUG__" /D "__WIN32__" /D "__WXMSW__" /D "__WIN95__" /D "STRICT" /D "__WINDOWS__" /YX /FD /D /c
-# ADD BASE MTL /nologo /D "_DEBUG" /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x407 /d "_DEBUG"
-# ADD RSC /l 0x407 /i "..\..\include" /d "WXDEBUG" /d "__WXMSW__"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib oldnames.lib comctl32.lib ctl3d32.lib odbc32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib ..\..\debug\wxwin.lib ctl3d32.lib /nologo /subsystem:windows /debug /machine:I386
-# SUBTRACT LINK32 /pdb:none
-
-!ENDIF
-
-# Begin Target
-
-# Name "test - Win32 Release"
-# Name "test - Win32 Debug"
-# Begin Group "Quellcodedateien"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
-# Begin Source File
-
-SOURCE=.\dnd.cpp
-# End Source File
-# End Group
-# Begin Group "Header-Dateien"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
-# End Group
-# Begin Group "Ressourcendateien"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
-# Begin Source File
-
-SOURCE=.\dnd.rc
-
-!IF "$(CFG)" == "test - Win32 Release"
-
-!ELSEIF "$(CFG)" == "test - Win32 Debug"
-
-!ENDIF
-
-# End Source File
-# End Group
-# End Target
-# End Project
+++ /dev/null
-Microsoft Developer Studio Workspace File, Format Version 5.00
-# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!
-
-###############################################################################
-
-Project: "test"=.\test.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
#ifdef __GNUG__
#pragma implementation "event.h"
#endif
#include "wx/validate.h"
#endif // wxUSE_GUI
+// ----------------------------------------------------------------------------
+// wxWin macros
+// ----------------------------------------------------------------------------
+
#if !USE_SHARED_LIBRARY
IMPLEMENT_DYNAMIC_CLASS(wxEvtHandler, wxObject)
IMPLEMENT_ABSTRACT_CLASS(wxEvent, wxObject)
#endif // !USE_SHARED_LIBRARY
+// ----------------------------------------------------------------------------
+// global variables
+// ----------------------------------------------------------------------------
+
+// To put pending event handlers
+wxList *wxPendingEvents = (wxList *)NULL;
+
#if wxUSE_THREADS
-/* To put pending event handlers */
-extern wxList *wxPendingEvents;
-extern wxCriticalSection *wxPendingEventsLocker;
+ // protects wxPendingEvents list
+ wxCriticalSection *wxPendingEventsLocker = (wxCriticalSection *)NULL;
#endif
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxEvent
+// ----------------------------------------------------------------------------
+
/*
* General wxWindows events, covering
* all interesting things that might happen (button clicking, resizing,
m_enabled = TRUE;
m_dynamicEvents = (wxList *) NULL;
m_isWindow = FALSE;
+ m_pendingEvents = (wxList *) NULL;
#if wxUSE_THREADS
- m_eventsLocker = new wxCriticalSection();
+ m_eventsLocker = new wxCriticalSection;
#endif
- m_pendingEvents = (wxList *) NULL;
}
wxEvtHandler::~wxEvtHandler()
delete m_dynamicEvents;
};
-#if wxUSE_THREADS
- if (m_pendingEvents)
- delete m_pendingEvents;
+ delete m_pendingEvents;
+#if wxUSE_THREADS
delete m_eventsLocker;
#endif
}
#if wxUSE_THREADS
-#ifdef __WXGTK__
-extern bool g_isIdle;
-extern void wxapp_install_idle_handler();
-#endif
-
bool wxEvtHandler::ProcessThreadEvent(wxEvent& event)
{
- wxEvent *event_main;
wxCriticalSectionLocker locker(*m_eventsLocker);
// check that we are really in a child thread
- wxASSERT( !wxThread::IsMain() );
+ wxASSERT_MSG( !wxThread::IsMain(),
+ wxT("use ProcessEvent() in main thread") );
+
+ AddPendingEvent(event);
- if (m_pendingEvents == NULL)
- m_pendingEvents = new wxList();
+ return TRUE;
+}
+
+#endif // wxUSE_THREADS
+
+void wxEvtHandler::AddPendingEvent(wxEvent& event)
+{
+ if ( !m_pendingEvents )
+ m_pendingEvents = new wxList;
- event_main = (wxEvent *)event.Clone();
+ wxEvent *event2 = (wxEvent *)event.Clone();
- m_pendingEvents->Append(event_main);
+ m_pendingEvents->Append(event2);
wxPendingEventsLocker->Enter();
+ if ( !wxPendingEvents )
+ wxPendingEvents = new wxList;
wxPendingEvents->Append(this);
wxPendingEventsLocker->Leave();
// TODO: Wake up idle handler for the other platforms.
#ifdef __WXGTK__
- if (g_isIdle)
+ extern bool g_isIdle;
+ extern void wxapp_install_idle_handler();
+ if ( g_isIdle )
wxapp_install_idle_handler();
-#endif
-
- return TRUE;
+#else // this works for wxMSW, but may be for others too?
+ // might also send a dummy message to the top level window, this would
+ // probably be cleaner?
+ wxIdleEvent eventIdle;
+ wxTheApp->OnIdle(eventIdle);
+#endif // platform
}
void wxEvtHandler::ProcessPendingEvents()
{
+#if wxUSE_THREADS
wxCriticalSectionLocker locker(*m_eventsLocker);
+#endif
+
wxNode *node = m_pendingEvents->First();
wxEvent *event;
- while (node != NULL) {
- event = (wxEvent *)node->Data();
- ProcessEvent(*event);
- delete node;
- node = m_pendingEvents->First();
+ while ( node )
+ {
+ event = (wxEvent *)node->Data();
+ ProcessEvent(*event);
+ delete node;
+ node = m_pendingEvents->First();
}
}
-#endif
/*
* Event table stuff
bool wxEvtHandler::ProcessEvent(wxEvent& event)
{
#if wxUSE_GUI
- /* check that our flag corresponds to reality */
+ // check that our flag corresponds to reality
wxASSERT( m_isWindow == IsKindOf(CLASSINFO(wxWindow)) );
#endif // wxUSE_GUI
- /* An event handler can be enabled or disabled */
+ // An event handler can be enabled or disabled
if ( GetEvtHandlerEnabled() )
{
#if wxUSE_THREADS
- /* Check whether we are in a child thread. */
- if (!wxThread::IsMain())
+ // Check whether we are in a child thread.
+ if ( !wxThread::IsMain() )
return ProcessThreadEvent(event);
-#endif
- /* Handle per-instance dynamic event tables first */
+#endif // wxUSE_THREADS
+ // Handle per-instance dynamic event tables first
if ( m_dynamicEvents && SearchDynamicEventTable(event) )
return TRUE;
- /* Then static per-class event tables */
-
+ // Then static per-class event tables
const wxEventTable *table = GetEventTable();
#if wxUSE_GUI && wxUSE_VALIDATORS
wxApp *wxTheApp = (wxApp *) NULL;
wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
-#if wxUSE_THREADS
-extern wxList *wxPendingEvents;
-extern wxCriticalSection *wxPendingEventsLocker;
-#endif
extern wxResourceCache *wxTheResourceCache;
extern bool g_isIdle;
// local functions
//-----------------------------------------------------------------------------
-extern void wxFlushResources(void);
+extern void wxFlushResources();
//-----------------------------------------------------------------------------
// global functions
return TRUE;
}
+
#endif // wxUSE_THREADS
//-----------------------------------------------------------------------------
s_inOnIdle = TRUE;
-#if wxUSE_THREADS
/* Resend in the main thread events which have been prepared in other
threads */
ProcessPendingEvents();
-#endif
/* 'Garbage' collection of windows deleted with Close(). */
DeletePendingObjects();
gtk_main_iteration();
}
-#if wxUSE_THREADS
void wxApp::ProcessPendingEvents()
{
- wxNode *node = wxPendingEvents->First();
+#if wxUSE_THREADS
wxCriticalSectionLocker locker(*wxPendingEventsLocker);
+#endif // wxUSE_THREADS
+
+ if ( !wxPendingEvents )
+ return;
+ wxNode *node = wxPendingEvents->First();
while (node)
{
wxEvtHandler *handler = (wxEvtHandler *)node->Data();
node = wxPendingEvents->First();
}
}
-#endif // wxUSE_THREADS
void wxApp::DeletePendingObjects()
{
/* List of windows pending deletion */
wxList wxPendingDelete;
-#if wxUSE_THREADS
-/* List of events pending processing */
-wxList *wxPendingEvents = NULL;
-wxCriticalSection *wxPendingEventsLocker = NULL;
-#endif
-
/* Current cursor, in order to hang on to
* cursor handle when setting the cursor globally */
wxCursor g_globalCursor;
/* disable GUI threads */
wxapp_uninstall_thread_wakeup();
#endif
-
+
gtk_selection_data_set( selection_data,
selection_data->target,
8, // 8-bit
if (wxNullIcon == stop) m_stopIcon = wxIcon( gv_xpm );
}
-wxDropSource::wxDropSource( wxDataObject *data, wxWindow *win, const wxIcon &go, const wxIcon &stop )
+wxDropSource::wxDropSource( wxDataObject& data, wxWindow *win,
+ const wxIcon &go, const wxIcon &stop )
{
m_waiting = TRUE;
if (win->m_wxwindow) m_widget = win->m_wxwindow;
m_retValue = wxDragCancel;
- if (data)
- {
- m_data = new wxDataBroker();
- m_data->Add( data );
- }
- else
- {
- m_data = (wxDataBroker*) NULL;
- }
+ m_data = new wxDataBroker;
+ m_data->Add(&data);
m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY );
m_goaheadCursor = wxCursor( wxCURSOR_HAND );
m_goaheadCursor = wxCursor( wxCURSOR_HAND );
}
+void wxDropSource::SetData( wxDataObject& data )
+{
+ if ( m_data )
+ delete m_data;
+
+ m_data = new wxDataBroker;
+ m_data->Add(&data);
+}
+
void wxDropSource::SetData( wxDataObject *data )
{
if (m_data) delete m_data;
m_data = data;
}
-wxDropSource::~wxDropSource(void)
+wxDropSource::~wxDropSource()
{
if (m_data) delete m_data;
/* disable GUI threads */
wxapp_uninstall_thread_wakeup();
#endif
-
+
/* don't start dragging if no button is down */
if (button_number)
{
/* re-enable GUI threads */
wxapp_install_thread_wakeup();
#endif
-
+
g_blockEventsOnDrag = FALSE;
UnregisterWindow();
wxApp *wxTheApp = (wxApp *) NULL;
wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
-#if wxUSE_THREADS
-extern wxList *wxPendingEvents;
-extern wxCriticalSection *wxPendingEventsLocker;
-#endif
extern wxResourceCache *wxTheResourceCache;
extern bool g_isIdle;
// local functions
//-----------------------------------------------------------------------------
-extern void wxFlushResources(void);
+extern void wxFlushResources();
//-----------------------------------------------------------------------------
// global functions
return TRUE;
}
+
#endif // wxUSE_THREADS
//-----------------------------------------------------------------------------
s_inOnIdle = TRUE;
-#if wxUSE_THREADS
/* Resend in the main thread events which have been prepared in other
threads */
ProcessPendingEvents();
-#endif
/* 'Garbage' collection of windows deleted with Close(). */
DeletePendingObjects();
gtk_main_iteration();
}
-#if wxUSE_THREADS
void wxApp::ProcessPendingEvents()
{
- wxNode *node = wxPendingEvents->First();
+#if wxUSE_THREADS
wxCriticalSectionLocker locker(*wxPendingEventsLocker);
+#endif // wxUSE_THREADS
+
+ if ( !wxPendingEvents )
+ return;
+ wxNode *node = wxPendingEvents->First();
while (node)
{
wxEvtHandler *handler = (wxEvtHandler *)node->Data();
node = wxPendingEvents->First();
}
}
-#endif // wxUSE_THREADS
void wxApp::DeletePendingObjects()
{
/* List of windows pending deletion */
wxList wxPendingDelete;
-#if wxUSE_THREADS
-/* List of events pending processing */
-wxList *wxPendingEvents = NULL;
-wxCriticalSection *wxPendingEventsLocker = NULL;
-#endif
-
/* Current cursor, in order to hang on to
* cursor handle when setting the cursor globally */
wxCursor g_globalCursor;
/* disable GUI threads */
wxapp_uninstall_thread_wakeup();
#endif
-
+
gtk_selection_data_set( selection_data,
selection_data->target,
8, // 8-bit
if (wxNullIcon == stop) m_stopIcon = wxIcon( gv_xpm );
}
-wxDropSource::wxDropSource( wxDataObject *data, wxWindow *win, const wxIcon &go, const wxIcon &stop )
+wxDropSource::wxDropSource( wxDataObject& data, wxWindow *win,
+ const wxIcon &go, const wxIcon &stop )
{
m_waiting = TRUE;
if (win->m_wxwindow) m_widget = win->m_wxwindow;
m_retValue = wxDragCancel;
- if (data)
- {
- m_data = new wxDataBroker();
- m_data->Add( data );
- }
- else
- {
- m_data = (wxDataBroker*) NULL;
- }
+ m_data = new wxDataBroker;
+ m_data->Add(&data);
m_defaultCursor = wxCursor( wxCURSOR_NO_ENTRY );
m_goaheadCursor = wxCursor( wxCURSOR_HAND );
m_goaheadCursor = wxCursor( wxCURSOR_HAND );
}
+void wxDropSource::SetData( wxDataObject& data )
+{
+ if ( m_data )
+ delete m_data;
+
+ m_data = new wxDataBroker;
+ m_data->Add(&data);
+}
+
void wxDropSource::SetData( wxDataObject *data )
{
if (m_data) delete m_data;
m_data = data;
}
-wxDropSource::~wxDropSource(void)
+wxDropSource::~wxDropSource()
{
if (m_data) delete m_data;
/* disable GUI threads */
wxapp_uninstall_thread_wakeup();
#endif
-
+
/* don't start dragging if no button is down */
if (button_number)
{
/* re-enable GUI threads */
wxapp_install_thread_wakeup();
#endif
-
+
g_blockEventsOnDrag = FALSE;
UnregisterWindow();
extern wxChar *wxOsVersion;
extern wxList *wxWinHandleList;
extern wxList WXDLLEXPORT wxPendingDelete;
-#if wxUSE_THREADS
-extern wxList *wxPendingEvents;
-extern wxCriticalSection *wxPendingEventsLocker;
-#endif
extern void wxSetKeyboardHook(bool doIt);
extern wxCursor *g_globalCursor;
wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion);
#endif
- // I'm annoyed ... I don't know where to put this and I don't want to
- // create a module for that as it's part of the core.
#if wxUSE_THREADS
- wxPendingEvents = new wxList();
- wxPendingEventsLocker = new wxCriticalSection();
+ wxPendingEventsLocker = new wxCriticalSection;
#endif
wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
// GL: I'm annoyed ... I don't know where to put this and I don't want to
// create a module for that as it's part of the core.
-#if wxUSE_THREADS
delete wxPendingEvents;
+#if wxUSE_THREADS
delete wxPendingEventsLocker;
// If we don't do the following, we get an apparent memory leak.
((wxEvtHandler&) wxDefaultValidator).ClearEventLocker();
return event.MoreRequested();
}
-#if wxUSE_THREADS
void wxApp::ProcessPendingEvents()
{
- wxNode *node = wxPendingEvents->First();
+#if wxUSE_THREADS
+ // ensure that we're the only thread to modify the pending events list
wxCriticalSectionLocker locker(*wxPendingEventsLocker);
+#endif
+ if ( !wxPendingEvents )
+ return;
+
+ wxNode *node = wxPendingEvents->First();
while (node)
{
wxEvtHandler *handler = (wxEvtHandler *)node->Data();
node = wxPendingEvents->First();
}
}
-#endif
-
void wxApp::ExitMainLoop()
{
event.RequestMore(TRUE);
}
- // If they are pending events, we must process them.
-#if wxUSE_THREADS
+ // If they are pending events, we must process them: pending events are
+ // either events to the threads other than main or events posted with
+ // wxPostEvent() functions
ProcessPendingEvents();
-#endif
+
s_inOnIdle = FALSE;
}
// Yield to incoming messages
bool wxYield()
{
+ // we don't want to process WM_QUIT from here - it should be processed in
+ // the main event loop in order to stop it
+
MSG msg;
- // We want to go back to the main message loop
- // if we see a WM_QUIT. (?)
-#ifdef __WXWINE__
- while (PeekMessage(&msg, (HWND)NULL, 0, 0, PM_NOREMOVE) && msg.message != WM_QUIT)
-#else
- while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) && msg.message != WM_QUIT)
-#endif
+ while ( PeekMessage(&msg, (HWND)0, 0, 0, PM_NOREMOVE) &&
+ msg.message != WM_QUIT )
{
if ( !wxTheApp->DoMessage() )
break;
}
+
// If they are pending events, we must process them.
-#if wxUSE_THREADS
wxTheApp->ProcessPendingEvents();
-#endif
return TRUE;
}
#if wxUSE_DRAG_AND_DROP
static bool wxSetClipboardData(wxDataObject *data)
{
- size_t size = data->GetDataSize();
+ wxDataFormat format = data->GetPreferredFormat();
+ size_t size = data->GetDataSize(format);
HANDLE hGlobal = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size);
if ( !hGlobal )
{
LPVOID lpGlobalMemory = ::GlobalLock(hGlobal);
- data->GetDataHere(lpGlobalMemory);
+ data->GetDataHere(format, lpGlobalMemory);
GlobalUnlock(hGlobal);
- wxDataFormat format = data->GetPreferredFormat();
if ( !::SetClipboardData(format, hGlobal) )
{
wxLogSysError(_("Failed to set clipboard data in format %s"),
// List of windows pending deletion
wxList WXDLLEXPORT wxPendingDelete;
-// List of events pending processing
-#if wxUSE_THREADS
-wxList *wxPendingEvents = NULL;
-wxCriticalSection *wxPendingEventsLocker = NULL;
-#endif
-
// Current cursor, in order to hang on to
// cursor handle when setting the cursor globally
wxCursor *g_globalCursor = NULL;
// functions
// ----------------------------------------------------------------------------
-static const char *GetTymedName(DWORD tymed);
+#ifdef __WXDEBUG__
+ static const char *GetTymedName(DWORD tymed);
+#endif // Debug
// ----------------------------------------------------------------------------
// wxIEnumFORMATETC interface implementation
// ----------------------------------------------------------------------------
+
class wxIEnumFORMATETC : public IEnumFORMATETC
{
public:
- wxIEnumFORMATETC(CLIPFORMAT cf);
+ wxIEnumFORMATETC(const wxDataFormat* formats, ULONG nCount);
+ ~wxIEnumFORMATETC() { delete [] m_formats; }
- DECLARE_IUNKNOWN_METHODS;
+ DECLARE_IUNKNOWN_METHODS;
- // IEnumFORMATETC
- STDMETHODIMP Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched);
- STDMETHODIMP Skip(ULONG celt);
- STDMETHODIMP Reset();
- STDMETHODIMP Clone(IEnumFORMATETC **ppenum);
+ // IEnumFORMATETC
+ STDMETHODIMP Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFetched);
+ STDMETHODIMP Skip(ULONG celt);
+ STDMETHODIMP Reset();
+ STDMETHODIMP Clone(IEnumFORMATETC **ppenum);
private:
- FORMATETC m_format; // (unique @@@) format we can provide data in
- ULONG m_nCurrent; // current enum position (currently either 0 or 1)
+ CLIPFORMAT *m_formats; // formats we can provide data in
+ ULONG m_nCount, // number of formats we support
+ m_nCurrent; // current enum position
};
// ----------------------------------------------------------------------------
// wxIDataObject implementation of IDataObject interface
// ----------------------------------------------------------------------------
+
class wxIDataObject : public IDataObject
{
public:
- wxIDataObject(wxDataObject *pDataObject);
+ wxIDataObject(wxDataObject *pDataObject);
- DECLARE_IUNKNOWN_METHODS;
+ DECLARE_IUNKNOWN_METHODS;
- // IDataObject
- STDMETHODIMP GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium);
- STDMETHODIMP GetDataHere(FORMATETC *pformatetc, STGMEDIUM *pmedium);
- STDMETHODIMP QueryGetData(FORMATETC *pformatetc);
- STDMETHODIMP GetCanonicalFormatEtc(FORMATETC *In, FORMATETC *pOut);
- STDMETHODIMP SetData(FORMATETC *pfetc, STGMEDIUM *pmedium, BOOL fRelease);
- STDMETHODIMP EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFEtc);
- STDMETHODIMP DAdvise(FORMATETC *pfetc, DWORD ad, IAdviseSink *p, DWORD *pdw);
- STDMETHODIMP DUnadvise(DWORD dwConnection);
- STDMETHODIMP EnumDAdvise(IEnumSTATDATA **ppenumAdvise);
+ // IDataObject
+ STDMETHODIMP GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium);
+ STDMETHODIMP GetDataHere(FORMATETC *pformatetc, STGMEDIUM *pmedium);
+ STDMETHODIMP QueryGetData(FORMATETC *pformatetc);
+ STDMETHODIMP GetCanonicalFormatEtc(FORMATETC *In, FORMATETC *pOut);
+ STDMETHODIMP SetData(FORMATETC *pfetc, STGMEDIUM *pmedium, BOOL fRelease);
+ STDMETHODIMP EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC **ppenumFEtc);
+ STDMETHODIMP DAdvise(FORMATETC *pfetc, DWORD ad, IAdviseSink *p, DWORD *pdw);
+ STDMETHODIMP DUnadvise(DWORD dwConnection);
+ STDMETHODIMP EnumDAdvise(IEnumSTATDATA **ppenumAdvise);
private:
- wxDataObject *m_pDataObject; // pointer to C++ class we belong to
+ wxDataObject *m_pDataObject; // pointer to C++ class we belong to
};
// ============================================================================
// ----------------------------------------------------------------------------
BEGIN_IID_TABLE(wxIEnumFORMATETC)
- ADD_IID(Unknown)
- ADD_IID(EnumFORMATETC)
+ ADD_IID(Unknown)
+ ADD_IID(EnumFORMATETC)
END_IID_TABLE;
IMPLEMENT_IUNKNOWN_METHODS(wxIEnumFORMATETC)
-wxIEnumFORMATETC::wxIEnumFORMATETC(CLIPFORMAT cf)
+wxIEnumFORMATETC::wxIEnumFORMATETC(const wxDataFormat *formats, ULONG nCount)
{
- m_format.cfFormat = cf;
- m_format.ptd = NULL;
- m_format.dwAspect = DVASPECT_CONTENT;
- m_format.lindex = -1;
- m_format.tymed = TYMED_HGLOBAL;
- m_cRef = 0;
- m_nCurrent = 0;
+ m_cRef = 0;
+ m_nCurrent = 0;
+ m_nCount = nCount;
+ m_formats = new CLIPFORMAT[nCount];
+ for ( ULONG n = 0; n < nCount; n++ ) {
+ m_formats[n] = formats[n].GetFormatId();
+ }
}
STDMETHODIMP wxIEnumFORMATETC::Next(ULONG celt,
FORMATETC *rgelt,
ULONG *pceltFetched)
{
- wxLogTrace(wxT("wxIEnumFORMATETC::Next"));
+ wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumFORMATETC::Next"));
- if ( celt > 1 )
- return S_FALSE;
+ if ( celt > 1 ) {
+ // we only return 1 element at a time - mainly because I'm too lazy to
+ // implement something which you're never asked for anyhow
+ return S_FALSE;
+ }
- if ( m_nCurrent == 0 ) {
- *rgelt = m_format;
- m_nCurrent++;
+ if ( m_nCurrent < m_nCount ) {
+ FORMATETC format;
+ format.cfFormat = m_formats[m_nCurrent++];
+ format.ptd = NULL;
+ format.dwAspect = DVASPECT_CONTENT;
+ format.lindex = -1;
+ format.tymed = TYMED_HGLOBAL;
+ *rgelt = format;
- return S_OK;
- }
- else
- return S_FALSE;
+ return S_OK;
+ }
+ else {
+ // bad index
+ return S_FALSE;
+ }
}
STDMETHODIMP wxIEnumFORMATETC::Skip(ULONG celt)
{
- wxLogTrace(wxT("wxIEnumFORMATETC::Skip"));
+ wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumFORMATETC::Skip"));
+
+ m_nCurrent += celt;
+ if ( m_nCurrent < m_nCount )
+ return S_OK;
- if ( m_nCurrent == 0 )
- m_nCurrent++;
+ // no, can't skip this many elements
+ m_nCurrent -= celt;
- return S_FALSE;
+ return S_FALSE;
}
STDMETHODIMP wxIEnumFORMATETC::Reset()
{
- wxLogTrace(wxT("wxIEnumFORMATETC::Reset"));
+ wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumFORMATETC::Reset"));
- m_nCurrent = 0;
+ m_nCurrent = 0;
- return S_OK;
+ return S_OK;
}
STDMETHODIMP wxIEnumFORMATETC::Clone(IEnumFORMATETC **ppenum)
{
- wxLogTrace(wxT("wxIEnumFORMATETC::Clone"));
-
- wxIEnumFORMATETC *pNew = new wxIEnumFORMATETC(m_format.cfFormat);
- pNew->AddRef();
- *ppenum = pNew;
+ wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumFORMATETC::Clone"));
+
+ // unfortunately, we can't reuse the code in ctor - types are different
+ wxIEnumFORMATETC *pNew = new wxIEnumFORMATETC(NULL, 0);
+ pNew->m_nCount = m_nCount;
+ pNew->m_formats = new CLIPFORMAT[m_nCount];
+ for ( ULONG n = 0; n < m_nCount; n++ ) {
+ pNew->m_formats[n] = m_formats[n];
+ }
+ pNew->AddRef();
+ *ppenum = pNew;
- return S_OK;
+ return S_OK;
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
BEGIN_IID_TABLE(wxIDataObject)
- ADD_IID(Unknown)
- ADD_IID(DataObject)
+ ADD_IID(Unknown)
+ ADD_IID(DataObject)
END_IID_TABLE;
IMPLEMENT_IUNKNOWN_METHODS(wxIDataObject)
wxIDataObject::wxIDataObject(wxDataObject *pDataObject)
{
- m_cRef = 0;
- m_pDataObject = pDataObject;
+ m_cRef = 0;
+ m_pDataObject = pDataObject;
}
// get data functions
STDMETHODIMP wxIDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
{
- wxLogTrace(wxT("wxIDataObject::GetData"));
+ wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::GetData"));
- // is data is in our format?
- HRESULT hr = QueryGetData(pformatetcIn);
- if ( FAILED(hr) )
- return hr;
+ // is data is in our format?
+ HRESULT hr = QueryGetData(pformatetcIn);
+ if ( FAILED(hr) )
+ return hr;
- // alloc memory
- HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
- m_pDataObject->GetDataSize());
- if ( hGlobal == NULL ) {
- wxLogLastError("GlobalAlloc");
- return E_OUTOFMEMORY;
- }
+ // for the bitmaps and metafiles we use the handles instead of global memory
+ // to pass the data
+ wxDataFormat format = (wxDataFormatId)pformatetcIn->cfFormat;
- // copy data
- pmedium->tymed = TYMED_HGLOBAL;
- pmedium->hGlobal = hGlobal;
- pmedium->pUnkForRelease = NULL;
+ switch ( format )
+ {
+ case wxDF_BITMAP:
+ pmedium->tymed = TYMED_GDI;
+ break;
+
+ case wxDF_METAFILE:
+ pmedium->tymed = TYMED_MFPICT;
+ break;
+
+ default:
+ // alloc memory
+ size_t size = m_pDataObject->GetDataSize(format);
+ if ( !size ) {
+ // it probably means that the method is just not implemented
+ wxLogDebug(wxT("Invalid data size - can't be 0"));
+
+ return DV_E_FORMATETC;
+ }
+
+ HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, size);
+ if ( hGlobal == NULL ) {
+ wxLogLastError("GlobalAlloc");
+ return E_OUTOFMEMORY;
+ }
+
+ // copy data
+ pmedium->tymed = TYMED_HGLOBAL;
+ pmedium->hGlobal = hGlobal;
+ }
- hr = GetDataHere(pformatetcIn, pmedium);
- if ( FAILED(hr) ) {
- GlobalFree(hGlobal);
- return hr;
- }
+ pmedium->pUnkForRelease = NULL;
+
+ // do copy the data
+ hr = GetDataHere(pformatetcIn, pmedium);
+ if ( FAILED(hr) ) {
+ // free resources we allocated
+ if ( pmedium->tymed == TYMED_HGLOBAL ) {
+ GlobalFree(pmedium->hGlobal);
+ }
+
+ return hr;
+ }
- return S_OK;
+ return S_OK;
}
STDMETHODIMP wxIDataObject::GetDataHere(FORMATETC *pformatetc,
STGMEDIUM *pmedium)
{
- wxLogTrace(wxT("wxIDataObject::GetDataHere"));
-
- // put data in caller provided medium
- if ( pmedium->tymed != TYMED_HGLOBAL )
- return DV_E_TYMED;
-
- // copy data
- void *pBuf = GlobalLock(pmedium->hGlobal);
- if ( pBuf == NULL ) {
- wxLogLastError(wxT("GlobalLock"));
- return E_OUTOFMEMORY;
- }
+ wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::GetDataHere"));
- m_pDataObject->GetDataHere(pBuf);
-
- GlobalUnlock(pmedium->hGlobal);
+ // put data in caller provided medium
+ switch ( pmedium->tymed )
+ {
+ case TYMED_GDI:
+ m_pDataObject->GetDataHere(wxDF_BITMAP, &pmedium->hBitmap);
+ break;
+
+ case TYMED_MFPICT:
+ // this should be copied on bitmaps - but I don't have time for
+ // this now
+ wxFAIL_MSG(wxT("TODO - no support for metafiles in wxDataObject"));
+ break;
+
+ case TYMED_HGLOBAL:
+ {
+ // copy data
+ void *pBuf = GlobalLock(pmedium->hGlobal);
+ if ( pBuf == NULL ) {
+ wxLogLastError(wxT("GlobalLock"));
+ return E_OUTOFMEMORY;
+ }
+
+ wxDataFormat format = (wxDataFormatId)pformatetc->cfFormat;
+ m_pDataObject->GetDataHere(format, pBuf);
+
+ GlobalUnlock(pmedium->hGlobal);
+ }
+ break;
+
+ default:
+ return DV_E_TYMED;
+ }
- return S_OK;
+ return S_OK;
}
// set data functions (not implemented)
STGMEDIUM *pmedium,
BOOL fRelease)
{
- wxLogTrace(wxT("wxIDataObject::SetData"));
+ wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::SetData"));
+
return E_NOTIMPL;
}
{
// do we accept data in this format?
if ( pformatetc == NULL ) {
- wxLogTrace(wxT("wxIDataObject::QueryGetData: invalid ptr."));
+ wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: invalid ptr."));
+
return E_INVALIDARG;
}
// the only one allowed by current COM implementation
if ( pformatetc->lindex != -1 ) {
- wxLogTrace(wxT("wxIDataObject::QueryGetData: bad lindex %d"),
+ wxLogTrace(wxTRACE_OleCalls,
+ wxT("wxIDataObject::QueryGetData: bad lindex %d"),
pformatetc->lindex);
return DV_E_LINDEX;
}
// we don't support anything other (THUMBNAIL, ICON, DOCPRINT...)
if ( pformatetc->dwAspect != DVASPECT_CONTENT ) {
- wxLogTrace(wxT("wxIDataObject::QueryGetData: bad dwAspect %d"),
+ wxLogTrace(wxTRACE_OleCalls,
+ wxT("wxIDataObject::QueryGetData: bad dwAspect %d"),
pformatetc->dwAspect);
return DV_E_DVASPECT;
}
- // @@ we only transfer data by global memory (bad for large amounts of it!)
- if ( !(pformatetc->tymed & TYMED_HGLOBAL) ) {
- wxLogTrace(wxT("wxIDataObject::QueryGetData: %s != TYMED_HGLOBAL."),
- GetTymedName(pformatetc->tymed));
+ // we only transfer data by global memory, except for some particular cases
+ wxDataFormat format = (wxDataFormatId)pformatetc->cfFormat;
+ DWORD tymed = pformatetc->tymed;
+ if ( (format == wxDF_BITMAP && !(tymed & TYMED_GDI)) ||
+ !(tymed & TYMED_HGLOBAL) ) {
+ // it's not what we're waiting for
+#ifdef __WXDEBUG__
+ wxLogTrace(wxTRACE_OleCalls,
+ wxT("wxIDataObject::QueryGetData: %s & %s == 0."),
+ GetTymedName(tymed),
+ GetTymedName(format == wxDF_BITMAP ? TYMED_GDI : TYMED_HGLOBAL));
+#endif // Debug
return DV_E_TYMED;
}
// and now check the type of data requested
- if ( m_pDataObject->IsSupportedFormat((wxDataFormatId)pformatetc->cfFormat) ) {
- wxLogTrace(wxT("wxIDataObject::QueryGetData: %s ok"),
- wxDataObject::GetFormatName((wxDataFormatId)pformatetc->cfFormat));
+ if ( m_pDataObject->IsSupportedFormat(format) ) {
+#ifdef __WXDEBUG__
+ wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: %s ok"),
+ wxDataObject::GetFormatName(format));
+#endif // Debug
return S_OK;
}
else {
- wxLogTrace(wxT("wxIDataObject::QueryGetData: %s unsupported"),
+ wxLogTrace(wxTRACE_OleCalls,
+ wxT("wxIDataObject::QueryGetData: %s unsupported"),
wxDataObject::GetFormatName((wxDataFormatId)pformatetc->cfFormat));
return DV_E_FORMATETC;
}
STDMETHODIMP wxIDataObject::GetCanonicalFormatEtc(FORMATETC *pFormatetcIn,
FORMATETC *pFormatetcOut)
{
- wxLogTrace(wxT("wxIDataObject::GetCanonicalFormatEtc"));
+ wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::GetCanonicalFormatEtc"));
+
+ // TODO we might want something better than this trivial implementation here
+ if ( pFormatetcOut != NULL )
+ pFormatetcOut->ptd = NULL;
- // @@ implementation is trivial, we might want something better here
- if ( pFormatetcOut != NULL )
- pFormatetcOut->ptd = NULL;
- return DATA_S_SAMEFORMATETC;
+ return DATA_S_SAMEFORMATETC;
}
STDMETHODIMP wxIDataObject::EnumFormatEtc(DWORD dwDirection,
IEnumFORMATETC **ppenumFormatEtc)
{
- wxLogTrace(wxT("wxIDataObject::EnumFormatEtc"));
+ wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::EnumFormatEtc"));
- if ( dwDirection == DATADIR_SET ) {
- // we don't allow setting of data anyhow
- return E_NOTIMPL;
- }
+ if ( dwDirection == DATADIR_SET ) {
+ // we don't allow setting of data anyhow
+ return E_NOTIMPL;
+ }
- wxIEnumFORMATETC *pEnum =
- new wxIEnumFORMATETC(m_pDataObject->GetPreferredFormat());
- pEnum->AddRef();
- *ppenumFormatEtc = pEnum;
+ size_t nFormatCount = m_pDataObject->GetFormatCount();
+ 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);
+ }
+
+ wxIEnumFORMATETC *pEnum = new wxIEnumFORMATETC(formats, nFormatCount);
+ pEnum->AddRef();
+ *ppenumFormatEtc = pEnum;
+
+ if ( formats != &format ) {
+ delete [] formats;
+ }
- return S_OK;
+ return S_OK;
}
// advise sink functions (not implemented)
m_pIDataObject->Release();
}
-const char *wxDataObject::GetFormatName(wxDataFormat format)
+bool wxDataObject::IsSupportedFormat(const wxDataFormat& format) const
{
+ size_t nFormatCount = GetFormatCount();
+ if ( nFormatCount == 1 ) {
+ return format == GetPreferredFormat();
+ }
+ else {
+ wxDataFormat *formats = new wxDataFormat[nFormatCount];
+ GetAllFormats(formats);
+
+ size_t n;
+ for ( n = 0; n < nFormatCount; n++ ) {
+ if ( formats[n] == format )
+ break;
+ }
+
+ delete [] formats;
+
+ // found?
+ return n < nFormatCount;
+ }
+}
+
#ifdef __WXDEBUG__
+const char *wxDataObject::GetFormatName(wxDataFormat format)
+{
// case 'xxx' is not a valid value for switch of enum 'wxDataFormat'
#ifdef __VISUALC__
#pragma warning(disable:4063)
#ifdef __VISUALC__
#pragma warning(default:4063)
#endif // VC++
-
-#else // !Debug
- return "";
-#endif // Debug
}
+#endif // Debug
// ----------------------------------------------------------------------------
// wxPrivateDataObject
memcpy( dest, data, GetSize() );
}
+// ----------------------------------------------------------------------------
+// wxBitmapDataObject
+// ----------------------------------------------------------------------------
+
+// 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.
+
+size_t wxBitmapDataObject::GetDataSize(const wxDataFormat& format) const
+{
+ // no data to copy anyhow
+ return 0;
+}
+
+void wxBitmapDataObject::GetDataHere(const wxDataFormat& format,
+ void *pBuf) const
+{
+ // we put a bitmap handle into pBuf
+ *(WXHBITMAP *)pBuf = m_bitmap.GetHBITMAP();
+}
+
// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------
+
+#ifdef __WXDEBUG__
+
static const char *GetTymedName(DWORD tymed)
{
static char s_szBuf[128];
}
}
-// TODO: OLE parts of wxBitmap/File/MetafileDataObject
+#endif // Debug
#endif
m_pIDropSource->AddRef();
}
-wxDropSource::wxDropSource(wxWindow* WXUNUSED(win))
+wxDropSource::wxDropSource(wxWindow* WXUNUSED(win),
+ const wxIcon & WXUNUSED(go),
+ const wxIcon & WXUNUSED(stop))
{
Init();
m_pData = NULL;
}
-wxDropSource::wxDropSource(wxDataObject& data, wxWindow* WXUNUSED(win))
+wxDropSource::wxDropSource(wxDataObject& data,
+ wxWindow* WXUNUSED(win),
+ const wxIcon & WXUNUSED(go),
+ const wxIcon & WXUNUSED(stop))
{
Init();
SetData(data);