]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/dnd.cpp
   1 /////////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxDropTarget, wxDropSource, wxDataObject implementation 
   4 // Author:      David Webster 
   8 // Copyright:   (c) 1998 AUTHOR 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "dnd.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  19 #if wxUSE_DRAG_AND_DROP 
  21 #include "wx/window.h" 
  23 #include "wx/gdicmn.h" 
  30 // ---------------------------------------------------------------------------- 
  32 // ---------------------------------------------------------------------------- 
  34 ///////////////////////////////////////////////////////////////////////////// 
  36 ///////////////////////////////////////////////////////////////////////////// 
  39 static wxDragResult 
ConvertDragEffectToResult ( 
  58 } // end of ConvertDragEffectToResult 
  60 static DWORD 
ConvertDragResultToEffect ( 
  79 } // end of ConvertDragResultToEffect 
  85     CIDropTarget(wxDropTarget
* pTarget
) 
  90     virtual ~CIDropTarget() { } 
  93     // Accessors for CDropTarget 
  95     void      Free(void) { ::DrgFreeDraginfo(m_pDragInfo
); } 
  96     PDRAGINFO 
GetDataSource(void) { return m_pDragInfo
; } 
  97     void      SetDataSource(PDRAGINFO pDragInfo
) { m_pDragInfo 
= pDragInfo
; } 
  98     void      SetHWND(HWND hWnd
) { m_hWnd 
= hWnd
; } 
 101     // CIDropTarget methods 
 103            bool    DragLeave(void); 
 104            MRESULT 
DragOver(void); 
 109     PDRAGINFO                       m_pDragInfo
; 
 110     PDRAGITEM                       m_pDragItem
; // !NULL between DragEnter and DragLeave/Drop 
 111     wxDropTarget
*                   m_pTarget
;   // the real target (we're just a proxy) 
 112     HWND                            m_hWnd
;      // window we're associated with 
 113 }; // end of CLASS CIDropTarget 
 115 bool CIDropTarget::DragLeave() 
 118     // Remove the UI feedback 
 120     m_pTarget
->OnLeave(); 
 123     // Release the held object 
 127 } // end of CIDropTarget::DragLeave 
 129 MRESULT 
CIDropTarget::DragOver () 
 138     ::DrgAccessDraginfo(m_pDragInfo
); 
 139     switch(m_pDragInfo
->usOperation
) 
 143             return (MRFROM2SHORT(DOR_NODROPOP
, 0)); 
 146             m_pDragItem 
= ::DrgQueryDragitemPtr(m_pDragInfo
, 0); 
 147             ulBytes     
= ::DrgQueryStrName( m_pDragItem
->hstrContainerName
 
 152                 return (MRFROM2SHORT(DOR_NODROPOP
, 0)); 
 159             uOp 
= m_pDragInfo
->usOperation
; 
 162     uIndicator 
= DOR_DROP
; 
 163     ulItems 
= (ULONG
)::DrgQueryDragitemCount(m_pDragInfo
); 
 164     for (i 
= 0; i 
< ulItems
; i
++) 
 166         m_pDragItem 
= ::DrgQueryDragitemPtr(m_pDragInfo
, i
); 
 167         if (((m_pDragItem
->fsSupportedOps 
& DO_COPYABLE
) && 
 168              (uOp 
== (USHORT
)DO_COPY
))                   || 
 169             ((m_pDragItem
->fsSupportedOps 
& DO_MOVEABLE
) && 
 170              (uOp 
== (USHORT
)DO_COPY
))) 
 172             if (::DrgVerifyRMF(m_pDragItem
, "DRM_OS2FILE", "DRF_UNKNOWN")) 
 173                 uIndicator 
= (USHORT
)DOR_DROP
; 
 175                 uIndicator 
= (USHORT
)DOR_NEVERDROP
; 
 179     return (MRFROM2SHORT(uIndicator
, uOp
)); 
 180 } // end of CIDropTarget::DragOver 
 182 // #pragma page   "CIDropTarget::Drop" 
 183 ///////////////////////////////////////////////////////////////////////////// 
 185 // CIDropTarget::Drop 
 187 //   Instructs the drop target to paste data that was just now dropped on it. 
 190 //   pIDataSource -- the data to paste 
 191 //   dwKeyState   -- kbd & mouse state 
 192 //   pt           -- mouse coordinates 
 193 //   pdwEffect    -- effect flag 
 198 ///////////////////////////////////////////////////////////////////////////// 
 199 MRESULT 
CIDropTarget::Drop () 
 208     ::DrgAccessDraginfo(m_pDragInfo
); 
 209     switch(m_pDragInfo
->usOperation
) 
 213             return (MRFROM2SHORT(DOR_NODROPOP
, 0)); 
 216             m_pDragItem 
= ::DrgQueryDragitemPtr(m_pDragInfo
, 0); 
 217             ulBytes     
= ::DrgQueryStrName( m_pDragItem
->hstrContainerName
 
 222                 return (MRFROM2SHORT(DOR_NODROPOP
, 0)); 
 229             uOp 
= m_pDragInfo
->usOperation
; 
 232     uIndicator 
= DOR_DROP
; 
 233     ulItems 
= (ULONG
)::DrgQueryDragitemCount(m_pDragInfo
); 
 234     for (i 
= 0; i 
< ulItems
; i
++) 
 236         m_pDragItem 
= ::DrgQueryDragitemPtr(m_pDragInfo
, i
); 
 237         if (((m_pDragItem
->fsSupportedOps 
& DO_COPYABLE
) && 
 238              (uOp 
== (USHORT
)DO_COPY
))                   || 
 239             ((m_pDragItem
->fsSupportedOps 
& DO_MOVEABLE
) && 
 240              (uOp 
== (USHORT
)DO_COPY
))) 
 242             if (::DrgVerifyRMF(m_pDragItem
, "DRM_OS2FILE", "DRF_UNKNOWN")) 
 243                 uIndicator 
= (USHORT
)DOR_DROP
; 
 245                 uIndicator 
= (USHORT
)DOR_NEVERDROP
; 
 250     // First ask the drop target if it wants data 
 252     if (m_pTarget
->OnDrop( m_pDragInfo
->xDrop
 
 256         wxDragResult                 eRc 
= wxDragNone
; 
 259         // And now it has the data 
 261         eRc 
= m_pTarget
->OnData( m_pDragInfo
->xDrop
 
 266     //else: OnDrop() returned false, no need to copy data 
 269     // Release the held object 
 272     return (MRFROM2SHORT(uIndicator
, uOp
)); 
 273 } // end of CIDropTarget::Drop 
 275 // ---------------------------------------------------------------------------- 
 277 // ---------------------------------------------------------------------------- 
 279 wxDropTarget::wxDropTarget ( 
 280   wxDataObject
*                     pDataObject
 
 283     m_dataObject  
= pDataObject
; 
 284     m_pDropTarget 
= new CIDropTarget(this); 
 285 } // end of wxDropTarget::wxDropTarget 
 287 wxDropTarget::~wxDropTarget() 
 290 } // end of wxDropTarget::~wxDropTarget 
 292 bool wxDropTarget::GetData () 
 294     wxDataFormat                    vFormat 
= GetSupportedFormat(m_pDropTarget
->GetDataSource()); 
 296     if (vFormat 
== wxDF_INVALID
) 
 301     // Under OS/2 we already have the data via the attached DRAGITEM's 
 304 } // end of wxDropTarget::GetData 
 306 wxDataFormat 
wxDropTarget::GetSupportedFormat ( 
 307   PDRAGINFO                         pDataSource
 
 311     wxDataFormat                    vFormat
; 
 312     wxDataFormat
*                   pFormats
; 
 313     ULONG                           ulFormats 
= m_dataObject
->GetFormatCount(wxDataObject::Set
); 
 314     ULONG                           ulItems 
= (ULONG
)::DrgQueryDragitemCount(pDataSource
); 
 321     pFormats 
= ulFormats 
== 1 ? &vFormat 
:  new wxDataFormat
[ulFormats
]; 
 322     m_dataObject
->GetAllFormats( pFormats
 
 326     for (n 
= 0; n 
< ulFormats
; n
++) 
 328         switch(pFormats
[n
].GetType()) 
 333                 sMechanism 
= _T("DRM_OS2FILE"); 
 334                 sFormat    
= _T("DRF_TEXT"); 
 338                 sMechanism 
= _T("DRM_OS2FILE"); 
 339                 sFormat    
= _T("DRF_OEMTEXT"); 
 343                 sMechanism 
= _T("DRM_OS2FILE"); 
 344                 sFormat    
= _T("DRF_BITMAP"); 
 348             case wxDF_ENHMETAFILE
: 
 349                 sMechanism 
= _T("DRM_OS2FILE"); 
 350                 sFormat    
= _T("DRF_METAFILE"); 
 354                 sMechanism 
= _T("DRM_OS2FILE"); 
 355                 sFormat    
= _T("DRF_TIFF"); 
 359                 sMechanism 
= _T("DRM_OS2FILE"); 
 360                 sFormat    
= _T("DRF_SYLK"); 
 364                 sMechanism 
= _T("DRM_OS2FILE"); 
 365                 sFormat    
= _T("DRF_DIF"); 
 369                 sMechanism 
= _T("DRM_OS2FILE"); 
 370                 sFormat    
= _T("DRF_DIB"); 
 377             case wxDF_UNICODETEXT
: 
 379                 sMechanism 
= _T("DRM_OS2FILE"); 
 380                 sFormat    
= _T("DRF_UNKNOWN"); 
 384                 sMechanism 
= _T("DRM_OBJECT"); 
 385                 sFormat    
= _T("DRF_UNKNOWN"); 
 388         for (i 
= 0; i 
< ulItems
; i
++) 
 390             pDragItem 
= ::DrgQueryDragitemPtr(pDataSource
, i
); 
 391             if (::DrgVerifyRMF(pDragItem
, (PSZ
)sMechanism
.c_str(), (PSZ
)sFormat
.c_str())) 
 399             vFormat 
= pFormats
[n
]; 
 403     if (pFormats 
!= &vFormat
) 
 406         // Free memory if we allocated it 
 410     return (n 
< ulFormats 
? vFormat 
: wxFormatInvalid
); 
 411 } // end of wxDropTarget::GetSupportedFormat 
 413 bool wxDropTarget::IsAcceptedData ( 
 414   PDRAGINFO                         pDataSource
 
 417     return (GetSupportedFormat(pDataSource
) != wxDF_INVALID
); 
 418 } // end of wxDropTarget::IsAcceptedData 
 420 void wxDropTarget::Release () 
 422     m_pDropTarget
->Free(); 
 423 } // end of wxDropTarget::Release 
 426 wxDragResult 
wxDropTarget::OnData ( 
 428 , wxCoord                           
WXUNUSED(y
) 
 429 , wxDragResult                      
WXUNUSED(vResult
) 
 432     return (wxDragResult
)0; 
 433 } // end of wxDropTarget::OnData 
 435 bool wxDropTarget::OnDrop ( 
 437 , wxCoord                           
WXUNUSED(y
) 
 441 } // end of wxDropTarget::OnDrop 
 443 //------------------------------------------------------------------------- 
 445 //------------------------------------------------------------------------- 
 447 wxDropSource::wxDropSource ( 
 452 } // end of wxDropSource::wxDropSource 
 454 wxDropSource::wxDropSource ( 
 461 } // end of wxDropSource::wxDropSource 
 463 wxDropSource::~wxDropSource () 
 465     ::DrgFreeDraginfo(m_pDragInfo
); 
 466 } // end of wxDropSource::~wxDropSource 
 468 wxDragResult 
wxDropSource::DoDragDrop ( 
 473     // Need to specify drag items in derived classes that know their data types 
 474     // before calling DoDragDrop 
 476     if (::DrgDrag( m_pWindow
->GetHWND() 
 484         switch(m_pDragInfo
->usOperation
) 
 500 } // end of wxDropSource::DoDragDrop 
 502 bool wxDropSource::GiveFeedback ( 
 506     const wxCursor
&                 rCursor 
= GetCursor(eEffect
); 
 510         ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)rCursor
.GetHCURSOR()); 
 511         m_vDragImage
.hImage 
= (LHANDLE
)rCursor
.GetHCURSOR(); 
 515                 m_pDragInfo
->usOperation 
= DO_COPY
; 
 519                 m_pDragInfo
->usOperation 
= DO_MOVE
; 
 523                 m_pDragInfo
->usOperation 
= DO_LINK
; 
 537 } // end of GuiAdvDnd_CDropSource::GiveFeedback 
 539 void wxDropSource::Init () 
 541     m_pDragInfo 
= ::DrgAllocDraginfo(m_ulItems
); 
 544     // Set a default drag image struct with what we know so far 
 546     m_vDragImage
.cb             
= sizeof(DRAGIMAGE
); 
 547     m_vDragImage
.cptl           
= 0;  // non-zero if fl is DRG_POLYGON 
 548     m_vDragImage
.hImage         
= 0;  // Set in GiveFeedback 
 549     m_vDragImage
.sizlStretch
.cx 
= 20L; 
 550     m_vDragImage
.sizlStretch
.cy 
= 20L; 
 551     m_vDragImage
.fl             
= DRG_ICON 
| DRG_STRETCH
; 
 552     m_vDragImage
.cxOffset       
= 0; 
 553     m_vDragImage
.cyOffset       
= 0; 
 555     HSTR                            hStrType 
= ::DrgAddStrHandle(DRT_UNKNOWN
); 
 558     wxChar                          zFormats
[128]; 
 559     wxChar                          zContainer
[128]; 
 560     USHORT                          uSize 
= GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()) + 1; 
 561     wxChar
*                         pzBuffer 
= new wxChar
[uSize
]; 
 563     memset(pzBuffer
, '\0', GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat())); 
 564     pzBuffer
[GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat())] = '\0'; 
 565     GetDataObject()->GetDataHere( GetDataObject()->GetPreferredFormat() 
 569     wxStrcpy(zFormats
, _T("<DRM_OS2FILE, DRF_UNKNOWN>")); 
 570     wxStrcpy(zContainer
, GetDataObject()->GetPreferredFormat().GetId()); 
 572     hStrRMF       
= ::DrgAddStrHandle((PSZ
)zFormats
); 
 573     hStrContainer 
= ::DrgAddStrHandle((PSZ
)zContainer
); 
 575     m_pDragItem 
= new DRAGITEM
[m_ulItems
]; 
 576     for (ULONG i 
= 0; i 
< m_ulItems
; i
++) 
 578         m_pDragItem
[i
].hwndItem          
= m_pWindow
->GetHWND(); 
 579         m_pDragItem
[i
].hstrType          
= hStrType
; 
 580         m_pDragItem
[i
].hstrRMF           
= hStrRMF
; 
 581         m_pDragItem
[i
].hstrContainerName 
= hStrContainer
; 
 582         m_pDragItem
[i
].fsControl         
= 0; 
 583         m_pDragItem
[i
].fsSupportedOps    
= DO_COPYABLE 
| DO_MOVEABLE 
| DO_LINKABLE
; 
 584         m_pDragItem
[i
].hstrSourceName    
= ::DrgAddStrHandle((PSZ
)pzBuffer
); 
 585         m_pDragItem
[i
].hstrTargetName    
= m_pDragItem
[i
].hstrSourceName
; 
 586         m_pDragItem
[i
].ulItemID          
= i
; 
 587         ::DrgSetDragitem( m_pDragInfo
 
 594     delete [] m_pDragItem
; 
 595 } // end of wxDropSource::Init 
 597 #endif //wxUSE_DRAG_AND_DROP