]>
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
= _T("DRM_OS2FILE");
333 sFormat
= _T("DRF_TEXT");
337 sMechanism
= _T("DRM_OS2FILE");
338 sFormat
= _T("DRF_OEMTEXT");
342 sMechanism
= _T("DRM_OS2FILE");
343 sFormat
= _T("DRF_BITMAP");
347 case wxDF_ENHMETAFILE
:
348 sMechanism
= _T("DRM_OS2FILE");
349 sFormat
= _T("DRF_METAFILE");
353 sMechanism
= _T("DRM_OS2FILE");
354 sFormat
= _T("DRF_TIFF");
358 sMechanism
= _T("DRM_OS2FILE");
359 sFormat
= _T("DRF_SYLK");
363 sMechanism
= _T("DRM_OS2FILE");
364 sFormat
= _T("DRF_DIF");
368 sMechanism
= _T("DRM_OS2FILE");
369 sFormat
= _T("DRF_DIB");
376 case wxDF_UNICODETEXT
:
378 sMechanism
= _T("DRM_OS2FILE");
379 sFormat
= _T("DRF_UNKNOWN");
383 sMechanism
= _T("DRM_OBJECT");
384 sFormat
= _T("DRF_UNKNOWN");
387 for (i
= 0; i
< ulItems
; i
++)
389 pDragItem
= ::DrgQueryDragitemPtr(pDataSource
, i
);
390 if (::DrgVerifyRMF(pDragItem
, (PSZ
)sMechanism
.c_str(), (PSZ
)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
, _T("<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