]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/dnd.cpp
   1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/os2/dnd.cpp 
   3 // Purpose:     wxDropTarget, wxDropSource, wxDataObject implementation 
   4 // Author:      David Webster 
   8 // Copyright:   (c) 1998 AUTHOR 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  15 #if wxUSE_DRAG_AND_DROP 
  21     #include "wx/window.h" 
  22     #include "wx/gdicmn.h" 
  29 // ---------------------------------------------------------------------------- 
  31 // ---------------------------------------------------------------------------- 
  33 ///////////////////////////////////////////////////////////////////////////// 
  35 ///////////////////////////////////////////////////////////////////////////// 
  38 static wxDragResult 
ConvertDragEffectToResult ( 
  57 } // end of ConvertDragEffectToResult 
  59 static DWORD 
ConvertDragResultToEffect ( 
  78 } // end of ConvertDragResultToEffect 
  84     CIDropTarget(wxDropTarget
* pTarget
) 
  89     virtual ~CIDropTarget() { } 
  92     // Accessors for CDropTarget 
  94     void      Free(void) { ::DrgFreeDraginfo(m_pDragInfo
); } 
  95     PDRAGINFO 
GetDataSource(void) { return m_pDragInfo
; } 
  96     void      SetDataSource(PDRAGINFO pDragInfo
) { m_pDragInfo 
= pDragInfo
; } 
  97     void      SetHWND(HWND hWnd
) { m_hWnd 
= hWnd
; } 
 100     // CIDropTarget methods 
 102            bool    DragLeave(void); 
 103            MRESULT 
DragOver(void); 
 108     PDRAGINFO                       m_pDragInfo
; 
 109     PDRAGITEM                       m_pDragItem
; // !NULL between DragEnter and DragLeave/Drop 
 110     wxDropTarget
*                   m_pTarget
;   // the real target (we're just a proxy) 
 111     HWND                            m_hWnd
;      // window we're associated with 
 112 }; // end of CLASS CIDropTarget 
 114 bool CIDropTarget::DragLeave() 
 117     // Remove the UI feedback 
 119     m_pTarget
->OnLeave(); 
 122     // Release the held object 
 126 } // end of CIDropTarget::DragLeave 
 128 MRESULT 
CIDropTarget::DragOver () 
 137     ::DrgAccessDraginfo(m_pDragInfo
); 
 138     switch(m_pDragInfo
->usOperation
) 
 142             return (MRFROM2SHORT(DOR_NODROPOP
, 0)); 
 145             m_pDragItem 
= ::DrgQueryDragitemPtr(m_pDragInfo
, 0); 
 146             ulBytes     
= ::DrgQueryStrName( m_pDragItem
->hstrContainerName
 
 151                 return (MRFROM2SHORT(DOR_NODROPOP
, 0)); 
 158             uOp 
= m_pDragInfo
->usOperation
; 
 161     uIndicator 
= DOR_DROP
; 
 162     ulItems 
= (ULONG
)::DrgQueryDragitemCount(m_pDragInfo
); 
 163     for (i 
= 0; i 
< ulItems
; i
++) 
 165         m_pDragItem 
= ::DrgQueryDragitemPtr(m_pDragInfo
, i
); 
 166         if (((m_pDragItem
->fsSupportedOps 
& DO_COPYABLE
) && 
 167              (uOp 
== (USHORT
)DO_COPY
))                   || 
 168             ((m_pDragItem
->fsSupportedOps 
& DO_MOVEABLE
) && 
 169              (uOp 
== (USHORT
)DO_COPY
))) 
 171             if (::DrgVerifyRMF(m_pDragItem
, "DRM_OS2FILE", "DRF_UNKNOWN")) 
 172                 uIndicator 
= (USHORT
)DOR_DROP
; 
 174                 uIndicator 
= (USHORT
)DOR_NEVERDROP
; 
 178     return (MRFROM2SHORT(uIndicator
, uOp
)); 
 179 } // end of CIDropTarget::DragOver 
 181 // #pragma page   "CIDropTarget::Drop" 
 182 ///////////////////////////////////////////////////////////////////////////// 
 184 // CIDropTarget::Drop 
 186 //   Instructs the drop target to paste data that was just now dropped on it. 
 189 //   pIDataSource -- the data to paste 
 190 //   dwKeyState   -- kbd & mouse state 
 191 //   pt           -- mouse coordinates 
 192 //   pdwEffect    -- effect flag 
 197 ///////////////////////////////////////////////////////////////////////////// 
 198 MRESULT 
CIDropTarget::Drop () 
 207     ::DrgAccessDraginfo(m_pDragInfo
); 
 208     switch(m_pDragInfo
->usOperation
) 
 212             return (MRFROM2SHORT(DOR_NODROPOP
, 0)); 
 215             m_pDragItem 
= ::DrgQueryDragitemPtr(m_pDragInfo
, 0); 
 216             ulBytes     
= ::DrgQueryStrName( m_pDragItem
->hstrContainerName
 
 221                 return (MRFROM2SHORT(DOR_NODROPOP
, 0)); 
 228             uOp 
= m_pDragInfo
->usOperation
; 
 231     uIndicator 
= DOR_DROP
; 
 232     ulItems 
= (ULONG
)::DrgQueryDragitemCount(m_pDragInfo
); 
 233     for (i 
= 0; i 
< ulItems
; i
++) 
 235         m_pDragItem 
= ::DrgQueryDragitemPtr(m_pDragInfo
, i
); 
 236         if (((m_pDragItem
->fsSupportedOps 
& DO_COPYABLE
) && 
 237              (uOp 
== (USHORT
)DO_COPY
))                   || 
 238             ((m_pDragItem
->fsSupportedOps 
& DO_MOVEABLE
) && 
 239              (uOp 
== (USHORT
)DO_COPY
))) 
 241             if (::DrgVerifyRMF(m_pDragItem
, "DRM_OS2FILE", "DRF_UNKNOWN")) 
 242                 uIndicator 
= (USHORT
)DOR_DROP
; 
 244                 uIndicator 
= (USHORT
)DOR_NEVERDROP
; 
 249     // First ask the drop target if it wants data 
 251     if (m_pTarget
->OnDrop( m_pDragInfo
->xDrop
 
 255         wxDragResult                 eRc 
= wxDragNone
; 
 258         // And now it has the data 
 260         eRc 
= m_pTarget
->OnData( m_pDragInfo
->xDrop
 
 265     //else: OnDrop() returned false, no need to copy data 
 268     // Release the held object 
 271     return (MRFROM2SHORT(uIndicator
, uOp
)); 
 272 } // end of CIDropTarget::Drop 
 274 // ---------------------------------------------------------------------------- 
 276 // ---------------------------------------------------------------------------- 
 278 wxDropTarget::wxDropTarget ( 
 279   wxDataObject
*                     pDataObject
 
 282     m_dataObject  
= pDataObject
; 
 283     m_pDropTarget 
= new CIDropTarget(this); 
 284 } // end of wxDropTarget::wxDropTarget 
 286 wxDropTarget::~wxDropTarget() 
 289 } // end of wxDropTarget::~wxDropTarget 
 291 bool wxDropTarget::GetData () 
 293     wxDataFormat                    vFormat 
= GetSupportedFormat(m_pDropTarget
->GetDataSource()); 
 295     if (vFormat 
== wxDF_INVALID
) 
 300     // Under OS/2 we already have the data via the attached DRAGITEM's 
 303 } // end of wxDropTarget::GetData 
 305 wxDataFormat 
wxDropTarget::GetSupportedFormat ( 
 306   PDRAGINFO                         pDataSource
 
 310     wxDataFormat                    vFormat
; 
 311     wxDataFormat
*                   pFormats
; 
 312     ULONG                           ulFormats 
= m_dataObject
->GetFormatCount(wxDataObject::Set
); 
 313     ULONG                           ulItems 
= (ULONG
)::DrgQueryDragitemCount(pDataSource
); 
 320     pFormats 
= ulFormats 
== 1 ? &vFormat 
:  new wxDataFormat
[ulFormats
]; 
 321     m_dataObject
->GetAllFormats( pFormats
 
 325     for (n 
= 0; n 
< ulFormats
; n
++) 
 327         switch(pFormats
[n
].GetType()) 
 332                 sMechanism 
= wxT("DRM_OS2FILE"); 
 333                 sFormat    
= wxT("DRF_TEXT"); 
 337                 sMechanism 
= wxT("DRM_OS2FILE"); 
 338                 sFormat    
= wxT("DRF_OEMTEXT"); 
 342                 sMechanism 
= wxT("DRM_OS2FILE"); 
 343                 sFormat    
= wxT("DRF_BITMAP"); 
 347             case wxDF_ENHMETAFILE
: 
 348                 sMechanism 
= wxT("DRM_OS2FILE"); 
 349                 sFormat    
= wxT("DRF_METAFILE"); 
 353                 sMechanism 
= wxT("DRM_OS2FILE"); 
 354                 sFormat    
= wxT("DRF_TIFF"); 
 358                 sMechanism 
= wxT("DRM_OS2FILE"); 
 359                 sFormat    
= wxT("DRF_SYLK"); 
 363                 sMechanism 
= wxT("DRM_OS2FILE"); 
 364                 sFormat    
= wxT("DRF_DIF"); 
 368                 sMechanism 
= wxT("DRM_OS2FILE"); 
 369                 sFormat    
= wxT("DRF_DIB"); 
 376             case wxDF_UNICODETEXT
: 
 378                 sMechanism 
= wxT("DRM_OS2FILE"); 
 379                 sFormat    
= wxT("DRF_UNKNOWN"); 
 383                 sMechanism 
= wxT("DRM_OBJECT"); 
 384                 sFormat    
= wxT("DRF_UNKNOWN"); 
 387         for (i 
= 0; i 
< ulItems
; i
++) 
 389             pDragItem 
= ::DrgQueryDragitemPtr(pDataSource
, i
); 
 390             if (::DrgVerifyRMF(pDragItem
, sMechanism
.c_str(), sFormat
.c_str())) 
 398             vFormat 
= pFormats
[n
]; 
 402     if (pFormats 
!= &vFormat
) 
 405         // Free memory if we allocated it 
 409     return (n 
< ulFormats 
? vFormat 
: wxFormatInvalid
); 
 410 } // end of wxDropTarget::GetSupportedFormat 
 412 bool wxDropTarget::IsAcceptedData ( 
 413   PDRAGINFO                         pDataSource
 
 416     return (GetSupportedFormat(pDataSource
) != wxDF_INVALID
); 
 417 } // end of wxDropTarget::IsAcceptedData 
 419 void wxDropTarget::Release () 
 421     m_pDropTarget
->Free(); 
 422 } // end of wxDropTarget::Release 
 425 wxDragResult 
wxDropTarget::OnData ( 
 427 , wxCoord                           
WXUNUSED(y
) 
 428 , wxDragResult                      
WXUNUSED(vResult
) 
 431     return (wxDragResult
)0; 
 432 } // end of wxDropTarget::OnData 
 434 bool wxDropTarget::OnDrop ( 
 436 , wxCoord                           
WXUNUSED(y
) 
 440 } // end of wxDropTarget::OnDrop 
 442 //------------------------------------------------------------------------- 
 444 //------------------------------------------------------------------------- 
 446 wxDropSource::wxDropSource ( wxWindow
* WXUNUSED(pWin
) ) 
 449 } // end of wxDropSource::wxDropSource 
 451 wxDropSource::wxDropSource ( wxDataObject
& rData
, wxWindow
* WXUNUSED(pWin
) ) 
 455 } // end of wxDropSource::wxDropSource 
 457 wxDropSource::~wxDropSource () 
 459     ::DrgFreeDraginfo(m_pDragInfo
); 
 460 } // end of wxDropSource::~wxDropSource 
 462 wxDragResult 
wxDropSource::DoDragDrop ( 
 467     // Need to specify drag items in derived classes that know their data types 
 468     // before calling DoDragDrop 
 470     if (::DrgDrag( m_pWindow
->GetHWND() 
 478         switch(m_pDragInfo
->usOperation
) 
 494 } // end of wxDropSource::DoDragDrop 
 496 bool wxDropSource::GiveFeedback ( 
 500     const wxCursor
&                 rCursor 
= GetCursor(eEffect
); 
 504         ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)rCursor
.GetHCURSOR()); 
 505         m_vDragImage
.hImage 
= (LHANDLE
)rCursor
.GetHCURSOR(); 
 509                 m_pDragInfo
->usOperation 
= DO_COPY
; 
 513                 m_pDragInfo
->usOperation 
= DO_MOVE
; 
 517                 m_pDragInfo
->usOperation 
= DO_LINK
; 
 531 } // end of GuiAdvDnd_CDropSource::GiveFeedback 
 533 void wxDropSource::Init () 
 535     m_pDragInfo 
= ::DrgAllocDraginfo(m_ulItems
); 
 538     // Set a default drag image struct with what we know so far 
 540     m_vDragImage
.cb             
= sizeof(DRAGIMAGE
); 
 541     m_vDragImage
.cptl           
= 0;  // non-zero if fl is DRG_POLYGON 
 542     m_vDragImage
.hImage         
= 0;  // Set in GiveFeedback 
 543     m_vDragImage
.sizlStretch
.cx 
= 20L; 
 544     m_vDragImage
.sizlStretch
.cy 
= 20L; 
 545     m_vDragImage
.fl             
= DRG_ICON 
| DRG_STRETCH
; 
 546     m_vDragImage
.cxOffset       
= 0; 
 547     m_vDragImage
.cyOffset       
= 0; 
 549     HSTR    hStrType 
= ::DrgAddStrHandle(DRT_UNKNOWN
); 
 552     wxChar  zFormats
[128]; 
 553     wxChar  zContainer
[128]; 
 554     USHORT  uSize 
= (USHORT
)(GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()) + 1); 
 555     wxChar
* pzBuffer 
= new wxChar
[uSize
]; 
 557     memset(pzBuffer
, '\0', GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat())); 
 558     pzBuffer
[GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat())] = '\0'; 
 559     GetDataObject()->GetDataHere( GetDataObject()->GetPreferredFormat() 
 563     wxStrcpy(zFormats
, wxT("<DRM_OS2FILE, DRF_UNKNOWN>")); 
 564     wxStrcpy(zContainer
, GetDataObject()->GetPreferredFormat().GetId()); 
 566     hStrRMF       
= ::DrgAddStrHandle((PSZ
)zFormats
); 
 567     hStrContainer 
= ::DrgAddStrHandle((PSZ
)zContainer
); 
 569     m_pDragItem 
= new DRAGITEM
[m_ulItems
]; 
 570     for (ULONG i 
= 0; i 
< m_ulItems
; i
++) 
 572         m_pDragItem
[i
].hwndItem          
= m_pWindow
->GetHWND(); 
 573         m_pDragItem
[i
].hstrType          
= hStrType
; 
 574         m_pDragItem
[i
].hstrRMF           
= hStrRMF
; 
 575         m_pDragItem
[i
].hstrContainerName 
= hStrContainer
; 
 576         m_pDragItem
[i
].fsControl         
= 0; 
 577         m_pDragItem
[i
].fsSupportedOps    
= DO_COPYABLE 
| DO_MOVEABLE 
| DO_LINKABLE
; 
 578         m_pDragItem
[i
].hstrSourceName    
= ::DrgAddStrHandle((PSZ
)pzBuffer
); 
 579         m_pDragItem
[i
].hstrTargetName    
= m_pDragItem
[i
].hstrSourceName
; 
 580         m_pDragItem
[i
].ulItemID          
= i
; 
 581         ::DrgSetDragitem( m_pDragInfo
 
 588     delete [] m_pDragItem
; 
 589 } // end of wxDropSource::Init 
 591 #endif //wxUSE_DRAG_AND_DROP