]>
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 /////////////////////////////////////////////////////////////////////////////
35 static wxDragResult
ConvertDragEffectToResult (
54 } // end of ConvertDragEffectToResult
56 static DWORD
ConvertDragResultToEffect (
75 } // end of ConvertDragResultToEffect
80 CIDropTarget(wxDropTarget
* pTarget
)
85 virtual ~CIDropTarget() { }
88 // Accessors for CDropTarget
90 void Free(void) { ::DrgFreeDraginfo(m_pDragInfo
); }
91 PDRAGINFO
GetDataSource(void) { return m_pDragInfo
; }
92 void SetDataSource(PDRAGINFO pDragInfo
) { m_pDragInfo
= pDragInfo
; }
93 void SetHWND(HWND hWnd
) { m_hWnd
= hWnd
; }
96 // CIDropTarget methods
99 MRESULT
DragOver(void);
104 PDRAGINFO m_pDragInfo
;
105 PDRAGITEM m_pDragItem
; // !NULL between DragEnter and DragLeave/Drop
106 wxDropTarget
* m_pTarget
; // the real target (we're just a proxy)
107 HWND m_hWnd
; // window we're associated with
108 }; // end of CLASS CIDropTarget
110 bool CIDropTarget::DragLeave()
113 // Remove the UI feedback
115 m_pTarget
->OnLeave();
118 // Release the held object
122 } // end of CIDropTarget::DragLeave
124 MRESULT
CIDropTarget::DragOver ()
133 ::DrgAccessDraginfo(m_pDragInfo
);
134 switch(m_pDragInfo
->usOperation
)
138 return (MRFROM2SHORT(DOR_NODROPOP
, 0));
141 m_pDragItem
= ::DrgQueryDragitemPtr(m_pDragInfo
, 0);
142 ulBytes
= ::DrgQueryStrName( m_pDragItem
->hstrContainerName
147 return (MRFROM2SHORT(DOR_NODROPOP
, 0));
154 uOp
= m_pDragInfo
->usOperation
;
157 uIndicator
= DOR_DROP
;
158 ulItems
= (ULONG
)::DrgQueryDragitemCount(m_pDragInfo
);
159 for (i
= 0; i
< ulItems
; i
++)
161 m_pDragItem
= ::DrgQueryDragitemPtr(m_pDragInfo
, i
);
162 if (((m_pDragItem
->fsSupportedOps
& DO_COPYABLE
) &&
163 (uOp
== (USHORT
)DO_COPY
)) ||
164 ((m_pDragItem
->fsSupportedOps
& DO_MOVEABLE
) &&
165 (uOp
== (USHORT
)DO_COPY
)))
167 if (::DrgVerifyRMF(m_pDragItem
, "DRM_OS2FILE", "DRF_UNKNOWN"))
168 uIndicator
= (USHORT
)DOR_DROP
;
170 uIndicator
= (USHORT
)DOR_NEVERDROP
;
174 return (MRFROM2SHORT(uIndicator
, uOp
));
175 } // end of CIDropTarget::DragOver
177 // #pragma page "CIDropTarget::Drop"
178 /////////////////////////////////////////////////////////////////////////////
180 // CIDropTarget::Drop
182 // Instructs the drop target to paste data that was just now dropped on it.
185 // pIDataSource -- the data to paste
186 // dwKeyState -- kbd & mouse state
187 // pt -- mouse coordinates
188 // pdwEffect -- effect flag
193 /////////////////////////////////////////////////////////////////////////////
194 MRESULT
CIDropTarget::Drop ()
203 ::DrgAccessDraginfo(m_pDragInfo
);
204 switch(m_pDragInfo
->usOperation
)
208 return (MRFROM2SHORT(DOR_NODROPOP
, 0));
211 m_pDragItem
= ::DrgQueryDragitemPtr(m_pDragInfo
, 0);
212 ulBytes
= ::DrgQueryStrName( m_pDragItem
->hstrContainerName
217 return (MRFROM2SHORT(DOR_NODROPOP
, 0));
224 uOp
= m_pDragInfo
->usOperation
;
227 uIndicator
= DOR_DROP
;
228 ulItems
= (ULONG
)::DrgQueryDragitemCount(m_pDragInfo
);
229 for (i
= 0; i
< ulItems
; i
++)
231 m_pDragItem
= ::DrgQueryDragitemPtr(m_pDragInfo
, i
);
232 if (((m_pDragItem
->fsSupportedOps
& DO_COPYABLE
) &&
233 (uOp
== (USHORT
)DO_COPY
)) ||
234 ((m_pDragItem
->fsSupportedOps
& DO_MOVEABLE
) &&
235 (uOp
== (USHORT
)DO_COPY
)))
237 if (::DrgVerifyRMF(m_pDragItem
, "DRM_OS2FILE", "DRF_UNKNOWN"))
238 uIndicator
= (USHORT
)DOR_DROP
;
240 uIndicator
= (USHORT
)DOR_NEVERDROP
;
245 // First ask the drop target if it wants data
247 if (m_pTarget
->OnDrop( m_pDragInfo
->xDrop
254 // And now it has the data
256 eRc
= m_pTarget
->OnData( m_pDragInfo
->xDrop
261 //else: OnDrop() returned FALSE, no need to copy data
264 // Release the held object
267 return (MRFROM2SHORT(uIndicator
, uOp
));
268 } // end of CIDropTarget::Drop
270 // ----------------------------------------------------------------------------
272 // ----------------------------------------------------------------------------
274 wxDropTarget::wxDropTarget (
275 wxDataObject
* pDataObject
278 m_dataObject
= pDataObject
;
279 m_pDropTarget
= new CIDropTarget(this);
280 } // end of wxDropTarget::wxDropTarget
282 wxDropTarget::~wxDropTarget()
285 } // end of wxDropTarget::~wxDropTarget
287 bool wxDropTarget::GetData ()
289 wxDataFormat vFormat
= GetSupportedFormat(m_pDropTarget
->GetDataSource());
291 if (vFormat
== wxDF_INVALID
)
296 // Under OS/2 we already have the data via the attached DRAGITEM's
299 } // end of wxDropTarget::GetData
301 wxDataFormat
wxDropTarget::GetSupportedFormat (
302 PDRAGINFO pDataSource
306 wxDataFormat vFormat
;
307 wxDataFormat
* pFormats
;
308 ULONG ulFormats
= m_dataObject
->GetFormatCount(wxDataObject::Set
);
309 ULONG ulItems
= (ULONG
)::DrgQueryDragitemCount(pDataSource
);
316 pFormats
= ulFormats
== 1 ? &vFormat
: new wxDataFormat
[ulFormats
];
317 m_dataObject
->GetAllFormats( pFormats
321 for (n
= 0; n
< ulFormats
; n
++)
323 switch(pFormats
[n
].GetType())
328 sMechanism
= "DRM_OS2FILE";
329 sFormat
= "DRF_TEXT";
333 sMechanism
= "DRM_OS2FILE";
334 sFormat
= "DRF_OEMTEXT";
338 sMechanism
= "DRM_OS2FILE";
339 sFormat
= "DRF_BITMAP";
343 case wxDF_ENHMETAFILE
:
344 sMechanism
= "DRM_OS2FILE";
345 sFormat
= "DRF_METAFILE";
349 sMechanism
= "DRM_OS2FILE";
350 sFormat
= "DRF_TIFF";
354 sMechanism
= "DRM_OS2FILE";
355 sFormat
= "DRF_SYLK";
359 sMechanism
= "DRM_OS2FILE";
364 sMechanism
= "DRM_OS2FILE";
372 case wxDF_UNICODETEXT
:
374 sMechanism
= "DRM_OS2FILE";
375 sFormat
= "DRF_UNKNOWN";
379 sMechanism
= "DRM_OBJECT";
380 sFormat
= "DRF_UNKNOWN";
383 for (i
= 0; i
< ulItems
; i
++)
385 pDragItem
= ::DrgQueryDragitemPtr(pDataSource
, i
);
386 if (::DrgVerifyRMF(pDragItem
, sMechanism
.c_str(), sFormat
.c_str()))
394 vFormat
= pFormats
[n
];
398 if (pFormats
!= &vFormat
)
401 // Free memory if we allocated it
405 return (n
< ulFormats
? vFormat
: wxFormatInvalid
);
406 } // end of wxDropTarget::GetSupportedFormat
408 bool wxDropTarget::IsAcceptedData (
409 PDRAGINFO pDataSource
412 return (GetSupportedFormat(pDataSource
) != wxDF_INVALID
);
413 } // end of wxDropTarget::IsAcceptedData
415 void wxDropTarget::Release ()
417 m_pDropTarget
->Free();
418 } // end of wxDropTarget::Release
421 wxDragResult
wxDropTarget::OnData (
423 , wxCoord
WXUNUSED(y
)
424 , wxDragResult
WXUNUSED(vResult
)
427 return (wxDragResult
)0;
428 } // end of wxDropTarget::OnData
430 bool wxDropTarget::OnDrop (
432 , wxCoord
WXUNUSED(y
)
436 } // end of wxDropTarget::OnDrop
438 //-------------------------------------------------------------------------
440 //-------------------------------------------------------------------------
442 wxDropSource::wxDropSource (
447 } // end of wxDropSource::wxDropSource
449 wxDropSource::wxDropSource (
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
;
527 } // end of GuiAdvDnd_CDropSource::GiveFeedback
529 void wxDropSource::Init ()
531 m_pDragInfo
= ::DrgAllocDraginfo(m_ulItems
);
534 // Set a default drag image struct with what we know so far
536 m_vDragImage
.cb
= sizeof(DRAGIMAGE
);
537 m_vDragImage
.cptl
= 0; // non-zero if fl is DRG_POLYGON
538 m_vDragImage
.hImage
= 0; // Set in GiveFeedback
539 m_vDragImage
.sizlStretch
.cx
= 20L;
540 m_vDragImage
.sizlStretch
.cy
= 20L;
541 m_vDragImage
.fl
= DRG_ICON
| DRG_STRETCH
;
542 m_vDragImage
.cxOffset
= 0;
543 m_vDragImage
.cyOffset
= 0;
545 HSTR hStrType
= ::DrgAddStrHandle(DRT_UNKNOWN
);
549 char zContainer
[128];
550 USHORT uSize
= GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()) + 1;
551 char* pzBuffer
= new char[uSize
];
553 memset(pzBuffer
, '\0', GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()));
554 pzBuffer
[GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat())] = '\0';
555 GetDataObject()->GetDataHere( GetDataObject()->GetPreferredFormat()
559 strcpy(zFormats
, "<DRM_OS2FILE, DRF_UNKNOWN>");
560 strcpy(zContainer
, GetDataObject()->GetPreferredFormat().GetId().c_str());
562 hStrRMF
= ::DrgAddStrHandle(zFormats
);
563 hStrContainer
= ::DrgAddStrHandle(zContainer
);
565 m_pDragItem
= new DRAGITEM
[m_ulItems
];
566 for (ULONG i
= 0; i
< m_ulItems
; i
++)
568 m_pDragItem
[i
].hwndItem
= m_pWindow
->GetHWND();
569 m_pDragItem
[i
].hstrType
= hStrType
;
570 m_pDragItem
[i
].hstrRMF
= hStrRMF
;
571 m_pDragItem
[i
].hstrContainerName
= hStrContainer
;
572 m_pDragItem
[i
].fsControl
= 0;
573 m_pDragItem
[i
].fsSupportedOps
= DO_COPYABLE
| DO_MOVEABLE
| DO_LINKABLE
;
574 m_pDragItem
[i
].hstrSourceName
= ::DrgAddStrHandle(pzBuffer
);
575 m_pDragItem
[i
].hstrTargetName
= m_pDragItem
[i
].hstrSourceName
;
576 m_pDragItem
[i
].ulItemID
= i
;
577 ::DrgSetDragitem( m_pDragInfo
584 delete [] m_pDragItem
;
585 } // end of wxDropSource::Init
587 #endif //wxUSE_DRAG_AND_DROP