]>
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"
24 #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 ( wxWindow
* WXUNUSED(pWin
) )
450 } // end of wxDropSource::wxDropSource
452 wxDropSource::wxDropSource ( wxDataObject
& rData
, wxWindow
* WXUNUSED(pWin
) )
456 } // end of wxDropSource::wxDropSource
458 wxDropSource::~wxDropSource ()
460 ::DrgFreeDraginfo(m_pDragInfo
);
461 } // end of wxDropSource::~wxDropSource
463 wxDragResult
wxDropSource::DoDragDrop (
468 // Need to specify drag items in derived classes that know their data types
469 // before calling DoDragDrop
471 if (::DrgDrag( m_pWindow
->GetHWND()
479 switch(m_pDragInfo
->usOperation
)
495 } // end of wxDropSource::DoDragDrop
497 bool wxDropSource::GiveFeedback (
501 const wxCursor
& rCursor
= GetCursor(eEffect
);
505 ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)rCursor
.GetHCURSOR());
506 m_vDragImage
.hImage
= (LHANDLE
)rCursor
.GetHCURSOR();
510 m_pDragInfo
->usOperation
= DO_COPY
;
514 m_pDragInfo
->usOperation
= DO_MOVE
;
518 m_pDragInfo
->usOperation
= DO_LINK
;
532 } // end of GuiAdvDnd_CDropSource::GiveFeedback
534 void wxDropSource::Init ()
536 m_pDragInfo
= ::DrgAllocDraginfo(m_ulItems
);
539 // Set a default drag image struct with what we know so far
541 m_vDragImage
.cb
= sizeof(DRAGIMAGE
);
542 m_vDragImage
.cptl
= 0; // non-zero if fl is DRG_POLYGON
543 m_vDragImage
.hImage
= 0; // Set in GiveFeedback
544 m_vDragImage
.sizlStretch
.cx
= 20L;
545 m_vDragImage
.sizlStretch
.cy
= 20L;
546 m_vDragImage
.fl
= DRG_ICON
| DRG_STRETCH
;
547 m_vDragImage
.cxOffset
= 0;
548 m_vDragImage
.cyOffset
= 0;
550 HSTR hStrType
= ::DrgAddStrHandle(DRT_UNKNOWN
);
553 wxChar zFormats
[128];
554 wxChar zContainer
[128];
555 USHORT uSize
= (USHORT
)(GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()) + 1);
556 wxChar
* pzBuffer
= new wxChar
[uSize
];
558 memset(pzBuffer
, '\0', GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()));
559 pzBuffer
[GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat())] = '\0';
560 GetDataObject()->GetDataHere( GetDataObject()->GetPreferredFormat()
564 wxStrcpy(zFormats
, _T("<DRM_OS2FILE, DRF_UNKNOWN>"));
565 wxStrcpy(zContainer
, GetDataObject()->GetPreferredFormat().GetId());
567 hStrRMF
= ::DrgAddStrHandle((PSZ
)zFormats
);
568 hStrContainer
= ::DrgAddStrHandle((PSZ
)zContainer
);
570 m_pDragItem
= new DRAGITEM
[m_ulItems
];
571 for (ULONG i
= 0; i
< m_ulItems
; i
++)
573 m_pDragItem
[i
].hwndItem
= m_pWindow
->GetHWND();
574 m_pDragItem
[i
].hstrType
= hStrType
;
575 m_pDragItem
[i
].hstrRMF
= hStrRMF
;
576 m_pDragItem
[i
].hstrContainerName
= hStrContainer
;
577 m_pDragItem
[i
].fsControl
= 0;
578 m_pDragItem
[i
].fsSupportedOps
= DO_COPYABLE
| DO_MOVEABLE
| DO_LINKABLE
;
579 m_pDragItem
[i
].hstrSourceName
= ::DrgAddStrHandle((PSZ
)pzBuffer
);
580 m_pDragItem
[i
].hstrTargetName
= m_pDragItem
[i
].hstrSourceName
;
581 m_pDragItem
[i
].ulItemID
= i
;
582 ::DrgSetDragitem( m_pDragInfo
589 delete [] m_pDragItem
;
590 } // end of wxDropSource::Init
592 #endif //wxUSE_DRAG_AND_DROP