]>
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
253 wxDragResult eRc
= wxDragNone
;;
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
= _T("DRM_OS2FILE");
331 sFormat
= _T("DRF_TEXT");
335 sMechanism
= _T("DRM_OS2FILE");
336 sFormat
= _T("DRF_OEMTEXT");
340 sMechanism
= _T("DRM_OS2FILE");
341 sFormat
= _T("DRF_BITMAP");
345 case wxDF_ENHMETAFILE
:
346 sMechanism
= _T("DRM_OS2FILE");
347 sFormat
= _T("DRF_METAFILE");
351 sMechanism
= _T("DRM_OS2FILE");
352 sFormat
= _T("DRF_TIFF");
356 sMechanism
= _T("DRM_OS2FILE");
357 sFormat
= _T("DRF_SYLK");
361 sMechanism
= _T("DRM_OS2FILE");
362 sFormat
= _T("DRF_DIF");
366 sMechanism
= _T("DRM_OS2FILE");
367 sFormat
= _T("DRF_DIB");
374 case wxDF_UNICODETEXT
:
376 sMechanism
= _T("DRM_OS2FILE");
377 sFormat
= _T("DRF_UNKNOWN");
381 sMechanism
= _T("DRM_OBJECT");
382 sFormat
= _T("DRF_UNKNOWN");
385 for (i
= 0; i
< ulItems
; i
++)
387 pDragItem
= ::DrgQueryDragitemPtr(pDataSource
, i
);
388 if (::DrgVerifyRMF(pDragItem
, (PSZ
)sMechanism
.c_str(), (PSZ
)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
);
555 wxChar zFormats
[128];
556 wxChar zContainer
[128];
557 USHORT uSize
= GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()) + 1;
558 wxChar
* pzBuffer
= new wxChar
[uSize
];
560 memset(pzBuffer
, '\0', GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()));
561 pzBuffer
[GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat())] = '\0';
562 GetDataObject()->GetDataHere( GetDataObject()->GetPreferredFormat()
566 wxStrcpy(zFormats
, _T("<DRM_OS2FILE, DRF_UNKNOWN>"));
567 wxStrcpy(zContainer
, GetDataObject()->GetPreferredFormat().GetId());
569 hStrRMF
= ::DrgAddStrHandle((PSZ
)zFormats
);
570 hStrContainer
= ::DrgAddStrHandle((PSZ
)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((PSZ
)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