]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/ole/droptgt.cpp
added new project file having the new files
[wxWidgets.git] / src / msw / ole / droptgt.cpp
index 897e2279dd5012ee593cef2f7265177a7e2b7ca0..094ca925e4e4744bef9af5dede2422db4f76eb0b 100644 (file)
 
 #include "wx/setup.h"
 
-#if wxUSE_DRAG_AND_DROP
+#if wxUSE_OLE && wxUSE_DRAG_AND_DROP
 
 #include "wx/log.h"
 
 #ifdef __WIN32__
-    #ifndef __GNUWIN32__
+    #if !defined(__GNUWIN32__) || wxUSE_NORLANDER_HEADERS
+        #if wxCHECK_W32API_VERSION( 1, 0 )
+            #include <windows.h>
+        #endif
         #include <shlobj.h>            // for DROPFILES structure
     #endif
 #else
 class wxIDropTarget : public IDropTarget
 {
 public:
-  wxIDropTarget(wxDropTarget *p);
- ~wxIDropTarget();
+    wxIDropTarget(wxDropTarget *p);
   virtual ~wxIDropTarget();
 
-  // IDropTarget methods
-  STDMETHODIMP DragEnter(LPDATAOBJECT, DWORD, POINTL, LPDWORD);
-  STDMETHODIMP DragOver(DWORD, POINTL, LPDWORD);
-  STDMETHODIMP DragLeave(void);
-  STDMETHODIMP Drop(LPDATAOBJECT, DWORD, POINTL, LPDWORD);
+    // accessors for wxDropTarget
+    void SetHwnd(HWND hwnd) { m_hwnd = hwnd; }
 
-  DECLARE_IUNKNOWN_METHODS;
+    // IDropTarget methods
+    STDMETHODIMP DragEnter(LPDATAOBJECT, DWORD, POINTL, LPDWORD);
+    STDMETHODIMP DragOver(DWORD, POINTL, LPDWORD);
+    STDMETHODIMP DragLeave();
+    STDMETHODIMP Drop(LPDATAOBJECT, DWORD, POINTL, LPDWORD);
+
+    DECLARE_IUNKNOWN_METHODS;
 
 protected:
-  IDataObject   *m_pIDataObject;  // !NULL between DragEnter and DragLeave/Drop
-  wxDropTarget  *m_pTarget;       // the real target (we're just a proxy)
+    IDataObject  *m_pIDataObject; // !NULL between DragEnter and DragLeave/Drop
+    wxDropTarget *m_pTarget;      // the real target (we're just a proxy)
+
+    HWND          m_hwnd;         // window we're associated with
 
-private:
-  static inline DWORD GetDropEffect(DWORD flags);
+    // get default drop effect for given keyboard flags
+    static inline DWORD GetDropEffect(DWORD flags);
 };
 
 // ----------------------------------------------------------------------------
@@ -90,7 +98,7 @@ static DWORD ConvertDragResultToEffect(wxDragResult result);
 // wxIDropTarget implementation
 // ============================================================================
 
-// Name    : static wxDropTarget::GetDropEffect
+// Name    : static wxIDropTarget::GetDropEffect
 // Purpose : determine the drop operation from keyboard/mouse state.
 // Returns : DWORD combined from DROPEFFECT_xxx constants
 // Params  : [in] DWORD flags       kbd & mouse flags as passed to
@@ -134,31 +142,35 @@ STDMETHODIMP wxIDropTarget::DragEnter(IDataObject *pIDataSource,
                                       POINTL       pt,
                                       DWORD       *pdwEffect)
 {
-  wxLogDebug(wxT("IDropTarget::DragEnter"));
+    wxLogDebug(wxT("IDropTarget::DragEnter"));
 
-  wxASSERT( m_pIDataObject == NULL );
+    wxASSERT( m_pIDataObject == NULL );
 
-  if ( !m_pTarget->IsAcceptedData(pIDataSource) ) {
-    // we don't accept this kind of data
-    *pdwEffect = DROPEFFECT_NONE;
+    if ( !m_pTarget->IsAcceptedData(pIDataSource) ) {
+        // we don't accept this kind of data
+        *pdwEffect = DROPEFFECT_NONE;
 
-    return S_OK;
-  }
+        return S_OK;
+    }
 
-  // get hold of the data object
-  m_pIDataObject = pIDataSource;
-  m_pIDataObject->AddRef();
+    // get hold of the data object
+    m_pIDataObject = pIDataSource;
+    m_pIDataObject->AddRef();
 
-  // give some visual feedback
-  *pdwEffect = ConvertDragResultToEffect(
-                 m_pTarget->OnEnter(pt.x, pt.y,
-                   ConvertDragEffectToResult(
-                     GetDropEffect(grfKeyState)
-                   )
-                 )
-               );
+    // we need client coordinates to pass to wxWin functions
+    if ( !ScreenToClient(m_hwnd, (POINT *)&pt) )
+    {
+        wxLogLastError(wxT("ScreenToClient"));
+    }
 
-  return S_OK;
+    // give some visual feedback
+    *pdwEffect = ConvertDragResultToEffect(
+                    m_pTarget->OnEnter(pt.x, pt.y,
+                        ConvertDragEffectToResult(GetDropEffect(grfKeyState))
+                    )
+                 );
+
+    return S_OK;
 }
 
 // Name    : wxIDropTarget::DragOver
@@ -174,22 +186,28 @@ STDMETHODIMP wxIDropTarget::DragOver(DWORD   grfKeyState,
                                      POINTL  pt,
                                      LPDWORD pdwEffect)
 {
-  // there are too many of them... wxLogDebug("IDropTarget::DragOver");
+    // there are too many of them... wxLogDebug("IDropTarget::DragOver");
 
-  wxDragResult result;
-  if ( m_pIDataObject ) {
-      result = ConvertDragEffectToResult(GetDropEffect(grfKeyState));
-  }
-  else {
-      // can't accept data anyhow normally
-      result = wxDragNone;
-  }
+    wxDragResult result;
+    if ( m_pIDataObject ) {
+        result = ConvertDragEffectToResult(GetDropEffect(grfKeyState));
+    }
+    else {
+        // can't accept data anyhow normally
+        result = wxDragNone;
+    }
 
-  *pdwEffect = ConvertDragResultToEffect(
-                 m_pTarget->OnDragOver(pt.x, pt.y, result)
-               );
+    // we need client coordinates to pass to wxWin functions
+    if ( !ScreenToClient(m_hwnd, (POINT *)&pt) )
+    {
+        wxLogLastError(wxT("ScreenToClient"));
+    }
 
-  return S_OK;
+    *pdwEffect = ConvertDragResultToEffect(
+                    m_pTarget->OnDragOver(pt.x, pt.y, result)
+                 );
+
+    return S_OK;
 }
 
 // Name    : wxIDropTarget::DragLeave
@@ -232,15 +250,23 @@ STDMETHODIMP wxIDropTarget::Drop(IDataObject *pIDataSource,
     // by default, nothing happens
     *pdwEffect = DROPEFFECT_NONE;
 
+    // we need client coordinates to pass to wxWin functions
+    if ( !ScreenToClient(m_hwnd, (POINT *)&pt) )
+    {
+        wxLogLastError(wxT("ScreenToClient"));
+    }
+
     // 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) ) {
+        wxDragResult rc = ConvertDragEffectToResult(GetDropEffect(grfKeyState));
+        rc = m_pTarget->OnData(pt.x, pt.y, rc);
+        if ( wxIsDragResultOk(rc) ) {
             // operation succeeded
-            *pdwEffect = GetDropEffect(grfKeyState);
+            *pdwEffect = ConvertDragResultToEffect(rc);
         }
         //else: *pdwEffect is already DROPEFFECT_NONE
     }
@@ -282,7 +308,7 @@ bool wxDropTarget::Register(WXHWND hwnd)
 {
     HRESULT hr = ::CoLockObjectExternal(m_pIDropTarget, TRUE, FALSE);
     if ( FAILED(hr) ) {
-        wxLogApiError("CoLockObjectExternal", hr);
+        wxLogApiError(wxT("CoLockObjectExternal"), hr);
         return FALSE;
     }
 
@@ -290,10 +316,13 @@ bool wxDropTarget::Register(WXHWND hwnd)
     if ( FAILED(hr) ) {
         ::CoLockObjectExternal(m_pIDropTarget, FALSE, FALSE);
 
-        wxLogApiError("RegisterDragDrop", hr);
+        wxLogApiError(wxT("RegisterDragDrop"), hr);
         return FALSE;
     }
 
+    // we will need the window handle for coords transformation later
+    m_pIDropTarget->SetHwnd((HWND)hwnd);
+
     return TRUE;
 }
 
@@ -302,10 +331,12 @@ void wxDropTarget::Revoke(WXHWND hwnd)
     HRESULT hr = ::RevokeDragDrop((HWND) hwnd);
 
     if ( FAILED(hr) ) {
-        wxLogApiError("RevokeDragDrop", hr);
+        wxLogApiError(wxT("RevokeDragDrop"), hr);
     }
 
     ::CoLockObjectExternal(m_pIDropTarget, FALSE, TRUE);
+
+    m_pIDropTarget->SetHwnd(0);
 }
 
 // ----------------------------------------------------------------------------
@@ -349,11 +380,11 @@ bool wxDropTarget::GetData()
             rc = TRUE;
         }
         else {
-            wxLogLastError("IDataObject::SetData()");
+            wxLogLastError(wxT("IDataObject::SetData()"));
         }
     }
     else {
-        wxLogLastError("IDataObject::GetData()");
+        wxLogLastError(wxT("IDataObject::GetData()"));
     }
 
     return rc;
@@ -393,7 +424,8 @@ wxDataFormat wxDropTarget::GetSupportedFormat(IDataObject *pIDataSource) const
 
     // get the list of supported formats
     size_t nFormats = m_dataObject->GetFormatCount(wxDataObject::Set);
-    wxDataFormat format, *formats;
+    wxDataFormat format;
+       wxDataFormat *formats;
     formats = nFormats == 1 ? &format :  new wxDataFormat[nFormats];
 
     m_dataObject->GetAllFormats(formats, wxDataObject::Set);
@@ -417,42 +449,7 @@ wxDataFormat wxDropTarget::GetSupportedFormat(IDataObject *pIDataSource) const
         delete [] formats;
     }
 
-    return (n < nFormats) ? (wxDataFormat) format : (wxDataFormat) wxDF_INVALID;
-}
-
-// ----------------------------------------------------------------------------
-// wxTextDropTarget
-// ----------------------------------------------------------------------------
-
-wxTextDropTarget::wxTextDropTarget()
-                : wxDropTarget(new wxTextDataObject)
-{
-}
-
-bool wxTextDropTarget::OnData(wxCoord x, wxCoord y)
-{
-    if ( !GetData() )
-        return FALSE;
-
-    return OnDropText(x, y, ((wxTextDataObject *)m_dataObject)->GetText());
-}
-
-// ----------------------------------------------------------------------------
-// wxFileDropTarget
-// ----------------------------------------------------------------------------
-
-wxFileDropTarget::wxFileDropTarget()
-                : wxDropTarget(new wxFileDataObject)
-{
-}
-
-bool wxFileDropTarget::OnData(wxCoord x, wxCoord y)
-{
-    if ( !GetData() )
-        return FALSE;
-
-    return OnDropFiles(x, y,
-                       ((wxFileDataObject *)m_dataObject)->GetFilenames());
+    return n < nFormats ? format : wxFormatInvalid;
 }
 
 // ----------------------------------------------------------------------------