]>
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 #include "wx/window.h" 
  18 #include "wx/gdicmn.h" 
  25 #if wxUSE_DRAG_AND_DROP 
  27 // ---------------------------------------------------------------------------- 
  29 // ---------------------------------------------------------------------------- 
  31 ///////////////////////////////////////////////////////////////////////////// 
  33 ///////////////////////////////////////////////////////////////////////////// 
  36 static wxDragResult 
ConvertDragEffectToResult ( 
  55 } // end of ConvertDragEffectToResult 
  57 static DWORD 
ConvertDragResultToEffect ( 
  76 } // end of ConvertDragResultToEffect 
  82     CIDropTarget(wxDropTarget
* pTarget
) 
  87     virtual ~CIDropTarget() { } 
  90     // Accessors for CDropTarget 
  92     void      Free(void) { ::DrgFreeDraginfo(m_pDragInfo
); } 
  93     PDRAGINFO 
GetDataSource(void) { return m_pDragInfo
; } 
  94     void      SetDataSource(PDRAGINFO pDragInfo
) { m_pDragInfo 
= pDragInfo
; } 
  95     void      SetHWND(HWND hWnd
) { m_hWnd 
= hWnd
; } 
  98     // CIDropTarget methods 
 100            bool    DragLeave(void); 
 101            MRESULT 
DragOver(void); 
 106     PDRAGINFO                       m_pDragInfo
; 
 107     PDRAGITEM                       m_pDragItem
; // !NULL between DragEnter and DragLeave/Drop 
 108     wxDropTarget
*                   m_pTarget
;   // the real target (we're just a proxy) 
 109     HWND                            m_hWnd
;      // window we're associated with 
 110 }; // end of CLASS CIDropTarget 
 112 bool CIDropTarget::DragLeave() 
 115     // Remove the UI feedback 
 117     m_pTarget
->OnLeave(); 
 120     // Release the held object 
 124 } // end of CIDropTarget::DragLeave 
 126 MRESULT 
CIDropTarget::DragOver () 
 135     ::DrgAccessDraginfo(m_pDragInfo
); 
 136     switch(m_pDragInfo
->usOperation
) 
 140             return (MRFROM2SHORT(DOR_NODROPOP
, 0)); 
 143             m_pDragItem 
= ::DrgQueryDragitemPtr(m_pDragInfo
, 0); 
 144             ulBytes     
= ::DrgQueryStrName( m_pDragItem
->hstrContainerName
 
 149                 return (MRFROM2SHORT(DOR_NODROPOP
, 0)); 
 156             uOp 
= m_pDragInfo
->usOperation
; 
 159     uIndicator 
= DOR_DROP
; 
 160     ulItems 
= (ULONG
)::DrgQueryDragitemCount(m_pDragInfo
); 
 161     for (i 
= 0; i 
< ulItems
; i
++) 
 163         m_pDragItem 
= ::DrgQueryDragitemPtr(m_pDragInfo
, i
); 
 164         if (((m_pDragItem
->fsSupportedOps 
& DO_COPYABLE
) && 
 165              (uOp 
== (USHORT
)DO_COPY
))                   || 
 166             ((m_pDragItem
->fsSupportedOps 
& DO_MOVEABLE
) && 
 167              (uOp 
== (USHORT
)DO_COPY
))) 
 169             if (::DrgVerifyRMF(m_pDragItem
, "DRM_OS2FILE", "DRF_UNKNOWN")) 
 170                 uIndicator 
= (USHORT
)DOR_DROP
; 
 172                 uIndicator 
= (USHORT
)DOR_NEVERDROP
; 
 176     return (MRFROM2SHORT(uIndicator
, uOp
)); 
 177 } // end of CIDropTarget::DragOver 
 179 // #pragma page   "CIDropTarget::Drop" 
 180 ///////////////////////////////////////////////////////////////////////////// 
 182 // CIDropTarget::Drop 
 184 //   Instructs the drop target to paste data that was just now dropped on it. 
 187 //   pIDataSource -- the data to paste 
 188 //   dwKeyState   -- kbd & mouse state 
 189 //   pt           -- mouse coordinates 
 190 //   pdwEffect    -- effect flag 
 195 ///////////////////////////////////////////////////////////////////////////// 
 196 MRESULT 
CIDropTarget::Drop () 
 205     ::DrgAccessDraginfo(m_pDragInfo
); 
 206     switch(m_pDragInfo
->usOperation
) 
 210             return (MRFROM2SHORT(DOR_NODROPOP
, 0)); 
 213             m_pDragItem 
= ::DrgQueryDragitemPtr(m_pDragInfo
, 0); 
 214             ulBytes     
= ::DrgQueryStrName( m_pDragItem
->hstrContainerName
 
 219                 return (MRFROM2SHORT(DOR_NODROPOP
, 0)); 
 226             uOp 
= m_pDragInfo
->usOperation
; 
 229     uIndicator 
= DOR_DROP
; 
 230     ulItems 
= (ULONG
)::DrgQueryDragitemCount(m_pDragInfo
); 
 231     for (i 
= 0; i 
< ulItems
; i
++) 
 233         m_pDragItem 
= ::DrgQueryDragitemPtr(m_pDragInfo
, i
); 
 234         if (((m_pDragItem
->fsSupportedOps 
& DO_COPYABLE
) && 
 235              (uOp 
== (USHORT
)DO_COPY
))                   || 
 236             ((m_pDragItem
->fsSupportedOps 
& DO_MOVEABLE
) && 
 237              (uOp 
== (USHORT
)DO_COPY
))) 
 239             if (::DrgVerifyRMF(m_pDragItem
, "DRM_OS2FILE", "DRF_UNKNOWN")) 
 240                 uIndicator 
= (USHORT
)DOR_DROP
; 
 242                 uIndicator 
= (USHORT
)DOR_NEVERDROP
; 
 247     // First ask the drop target if it wants data 
 249     if (m_pTarget
->OnDrop( m_pDragInfo
->xDrop
 
 256         // And now it has the data 
 258         eRc 
= m_pTarget
->OnData( m_pDragInfo
->xDrop
 
 263     //else: OnDrop() returned FALSE, no need to copy data 
 266     // Release the held object 
 269     return (MRFROM2SHORT(uIndicator
, uOp
)); 
 270 } // end of CIDropTarget::Drop 
 272 // ---------------------------------------------------------------------------- 
 274 // ---------------------------------------------------------------------------- 
 276 wxDropTarget::wxDropTarget ( 
 277   wxDataObject
*                     pDataObject
 
 280     m_dataObject  
= pDataObject
; 
 281     m_pDropTarget 
= new CIDropTarget(this); 
 282 } // end of wxDropTarget::wxDropTarget 
 284 wxDropTarget::~wxDropTarget() 
 287 } // end of wxDropTarget::~wxDropTarget 
 289 bool wxDropTarget::GetData () 
 291     wxDataFormat                    vFormat 
= GetSupportedFormat(m_pDropTarget
->GetDataSource()); 
 293     if (vFormat 
== wxDF_INVALID
) 
 298     // Under OS/2 we already have the data via the attached DRAGITEM's 
 301 } // end of wxDropTarget::GetData 
 303 wxDataFormat 
wxDropTarget::GetSupportedFormat ( 
 304   PDRAGINFO                         pDataSource
 
 308     wxDataFormat                    vFormat
; 
 309     wxDataFormat
*                   pFormats
; 
 310     ULONG                           ulFormats 
= m_dataObject
->GetFormatCount(wxDataObject::Set
); 
 311     ULONG                           ulItems 
= (ULONG
)::DrgQueryDragitemCount(pDataSource
); 
 318     pFormats 
= ulFormats 
== 1 ? &vFormat 
:  new wxDataFormat
[ulFormats
]; 
 319     m_dataObject
->GetAllFormats( pFormats
 
 323     for (n 
= 0; n 
< ulFormats
; n
++) 
 325         switch(pFormats
[n
].GetType()) 
 330                 sMechanism 
= "DRM_OS2FILE"; 
 331                 sFormat    
= "DRF_TEXT"; 
 335                 sMechanism 
= "DRM_OS2FILE"; 
 336                 sFormat    
= "DRF_OEMTEXT"; 
 340                 sMechanism 
= "DRM_OS2FILE"; 
 341                 sFormat    
= "DRF_BITMAP"; 
 345             case wxDF_ENHMETAFILE
: 
 346                 sMechanism 
= "DRM_OS2FILE"; 
 347                 sFormat    
= "DRF_METAFILE"; 
 351                 sMechanism 
= "DRM_OS2FILE"; 
 352                 sFormat    
= "DRF_TIFF"; 
 356                 sMechanism 
= "DRM_OS2FILE"; 
 357                 sFormat    
= "DRF_SYLK"; 
 361                 sMechanism 
= "DRM_OS2FILE"; 
 366                 sMechanism 
= "DRM_OS2FILE"; 
 374             case wxDF_UNICODETEXT
: 
 376                 sMechanism 
= "DRM_OS2FILE"; 
 377                 sFormat    
= "DRF_UNKNOWN"; 
 381                 sMechanism 
= "DRM_OBJECT"; 
 382                 sFormat    
= "DRF_UNKNOWN"; 
 385         for (i 
= 0; i 
< ulItems
; i
++) 
 387             pDragItem 
= ::DrgQueryDragitemPtr(pDataSource
, i
); 
 388             if (::DrgVerifyRMF(pDragItem
, sMechanism
.c_str(), sFormat
.c_str())) 
 396             vFormat 
= pFormats
[n
]; 
 400     if (pFormats 
!= &vFormat
) 
 403         // Free memory if we allocated it 
 407     return (n 
< ulFormats 
? vFormat 
: wxFormatInvalid
); 
 408 } // end of wxDropTarget::GetSupportedFormat 
 410 bool wxDropTarget::IsAcceptedData ( 
 411   PDRAGINFO                         pDataSource
 
 414     return (GetSupportedFormat(pDataSource
) != wxDF_INVALID
); 
 415 } // end of wxDropTarget::IsAcceptedData 
 417 void wxDropTarget::Release () 
 419     m_pDropTarget
->Free(); 
 420 } // end of wxDropTarget::Release 
 423 wxDragResult 
wxDropTarget::OnData ( 
 425 , wxCoord                           
WXUNUSED(y
) 
 426 , wxDragResult                      
WXUNUSED(vResult
) 
 429     return (wxDragResult
)0; 
 430 } // end of wxDropTarget::OnData 
 432 bool wxDropTarget::OnDrop ( 
 434 , wxCoord                           
WXUNUSED(y
) 
 438 } // end of wxDropTarget::OnDrop 
 440 //------------------------------------------------------------------------- 
 442 //------------------------------------------------------------------------- 
 444 wxDropSource::wxDropSource ( 
 449 } // end of wxDropSource::wxDropSource 
 451 wxDropSource::wxDropSource ( 
 458 } // end of wxDropSource::wxDropSource 
 460 wxDropSource::~wxDropSource () 
 462     ::DrgFreeDraginfo(m_pDragInfo
); 
 463 } // end of wxDropSource::~wxDropSource 
 465 wxDragResult 
wxDropSource::DoDragDrop ( 
 470     // Need to specify drag items in derived classes that know their data types 
 471     // before calling DoDragDrop 
 473     if (::DrgDrag( m_pWindow
->GetHWND() 
 481         switch(m_pDragInfo
->usOperation
) 
 497 } // end of wxDropSource::DoDragDrop 
 499 bool wxDropSource::GiveFeedback ( 
 503     const wxCursor
&                 rCursor 
= GetCursor(eEffect
); 
 507         ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)rCursor
.GetHCURSOR()); 
 508         m_vDragImage
.hImage 
= (LHANDLE
)rCursor
.GetHCURSOR(); 
 512                 m_pDragInfo
->usOperation 
= DO_COPY
; 
 516                 m_pDragInfo
->usOperation 
= DO_MOVE
; 
 520                 m_pDragInfo
->usOperation 
= DO_LINK
; 
 534 } // end of GuiAdvDnd_CDropSource::GiveFeedback 
 536 void wxDropSource::Init () 
 538     m_pDragInfo 
= ::DrgAllocDraginfo(m_ulItems
); 
 541     // Set a default drag image struct with what we know so far 
 543     m_vDragImage
.cb             
= sizeof(DRAGIMAGE
); 
 544     m_vDragImage
.cptl           
= 0;  // non-zero if fl is DRG_POLYGON 
 545     m_vDragImage
.hImage         
= 0;  // Set in GiveFeedback 
 546     m_vDragImage
.sizlStretch
.cx 
= 20L; 
 547     m_vDragImage
.sizlStretch
.cy 
= 20L; 
 548     m_vDragImage
.fl             
= DRG_ICON 
| DRG_STRETCH
; 
 549     m_vDragImage
.cxOffset       
= 0; 
 550     m_vDragImage
.cyOffset       
= 0; 
 552     HSTR                            hStrType 
= ::DrgAddStrHandle(DRT_UNKNOWN
); 
 556     char                            zContainer
[128]; 
 557     USHORT                          uSize 
= GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()) + 1; 
 558     char*                           pzBuffer 
= new char[uSize
]; 
 560     memset(pzBuffer
, '\0', GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat())); 
 561     pzBuffer
[GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat())] = '\0'; 
 562     GetDataObject()->GetDataHere( GetDataObject()->GetPreferredFormat() 
 566     strcpy(zFormats
, "<DRM_OS2FILE, DRF_UNKNOWN>"); 
 567     strcpy(zContainer
, GetDataObject()->GetPreferredFormat().GetId().c_str()); 
 569     hStrRMF       
= ::DrgAddStrHandle(zFormats
); 
 570     hStrContainer 
= ::DrgAddStrHandle(zContainer
); 
 572     m_pDragItem 
= new DRAGITEM
[m_ulItems
]; 
 573     for (ULONG i 
= 0; i 
< m_ulItems
; i
++) 
 575         m_pDragItem
[i
].hwndItem          
= m_pWindow
->GetHWND(); 
 576         m_pDragItem
[i
].hstrType          
= hStrType
; 
 577         m_pDragItem
[i
].hstrRMF           
= hStrRMF
; 
 578         m_pDragItem
[i
].hstrContainerName 
= hStrContainer
; 
 579         m_pDragItem
[i
].fsControl         
= 0; 
 580         m_pDragItem
[i
].fsSupportedOps    
= DO_COPYABLE 
| DO_MOVEABLE 
| DO_LINKABLE
; 
 581         m_pDragItem
[i
].hstrSourceName    
= ::DrgAddStrHandle(pzBuffer
); 
 582         m_pDragItem
[i
].hstrTargetName    
= m_pDragItem
[i
].hstrSourceName
; 
 583         m_pDragItem
[i
].ulItemID          
= i
; 
 584         ::DrgSetDragitem( m_pDragInfo
 
 591     delete [] m_pDragItem
; 
 592 } // end of wxDropSource::Init 
 594 #endif //wxUSE_DRAG_AND_DROP