]>
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
17 #include "wx/window.h"
19 #include "wx/gdicmn.h"
26 // ----------------------------------------------------------------------------
28 // ----------------------------------------------------------------------------
30 /////////////////////////////////////////////////////////////////////////////
32 /////////////////////////////////////////////////////////////////////////////
35 static wxDragResult
ConvertDragEffectToResult (
54 } // end of ConvertDragEffectToResult
56 static DWORD
ConvertDragResultToEffect (
75 } // end of ConvertDragResultToEffect
81 CIDropTarget(wxDropTarget
* pTarget
)
86 virtual ~CIDropTarget() { }
89 // Accessors for CDropTarget
91 void Free(void) { ::DrgFreeDraginfo(m_pDragInfo
); }
92 PDRAGINFO
GetDataSource(void) { return m_pDragInfo
; }
93 void SetDataSource(PDRAGINFO pDragInfo
) { m_pDragInfo
= pDragInfo
; }
94 void SetHWND(HWND hWnd
) { m_hWnd
= hWnd
; }
97 // CIDropTarget methods
100 MRESULT
DragOver(void);
105 PDRAGINFO m_pDragInfo
;
106 PDRAGITEM m_pDragItem
; // !NULL between DragEnter and DragLeave/Drop
107 wxDropTarget
* m_pTarget
; // the real target (we're just a proxy)
108 HWND m_hWnd
; // window we're associated with
109 }; // end of CLASS CIDropTarget
111 bool CIDropTarget::DragLeave()
114 // Remove the UI feedback
116 m_pTarget
->OnLeave();
119 // Release the held object
123 } // end of CIDropTarget::DragLeave
125 MRESULT
CIDropTarget::DragOver ()
134 ::DrgAccessDraginfo(m_pDragInfo
);
135 switch(m_pDragInfo
->usOperation
)
139 return (MRFROM2SHORT(DOR_NODROPOP
, 0));
142 m_pDragItem
= ::DrgQueryDragitemPtr(m_pDragInfo
, 0);
143 ulBytes
= ::DrgQueryStrName( m_pDragItem
->hstrContainerName
148 return (MRFROM2SHORT(DOR_NODROPOP
, 0));
155 uOp
= m_pDragInfo
->usOperation
;
158 uIndicator
= DOR_DROP
;
159 ulItems
= (ULONG
)::DrgQueryDragitemCount(m_pDragInfo
);
160 for (i
= 0; i
< ulItems
; i
++)
162 m_pDragItem
= ::DrgQueryDragitemPtr(m_pDragInfo
, i
);
163 if (((m_pDragItem
->fsSupportedOps
& DO_COPYABLE
) &&
164 (uOp
== (USHORT
)DO_COPY
)) ||
165 ((m_pDragItem
->fsSupportedOps
& DO_MOVEABLE
) &&
166 (uOp
== (USHORT
)DO_COPY
)))
168 if (::DrgVerifyRMF(m_pDragItem
, "DRM_OS2FILE", "DRF_UNKNOWN"))
169 uIndicator
= (USHORT
)DOR_DROP
;
171 uIndicator
= (USHORT
)DOR_NEVERDROP
;
175 return (MRFROM2SHORT(uIndicator
, uOp
));
176 } // end of CIDropTarget::DragOver
178 // #pragma page "CIDropTarget::Drop"
179 /////////////////////////////////////////////////////////////////////////////
181 // CIDropTarget::Drop
183 // Instructs the drop target to paste data that was just now dropped on it.
186 // pIDataSource -- the data to paste
187 // dwKeyState -- kbd & mouse state
188 // pt -- mouse coordinates
189 // pdwEffect -- effect flag
194 /////////////////////////////////////////////////////////////////////////////
195 MRESULT
CIDropTarget::Drop ()
204 ::DrgAccessDraginfo(m_pDragInfo
);
205 switch(m_pDragInfo
->usOperation
)
209 return (MRFROM2SHORT(DOR_NODROPOP
, 0));
212 m_pDragItem
= ::DrgQueryDragitemPtr(m_pDragInfo
, 0);
213 ulBytes
= ::DrgQueryStrName( m_pDragItem
->hstrContainerName
218 return (MRFROM2SHORT(DOR_NODROPOP
, 0));
225 uOp
= m_pDragInfo
->usOperation
;
228 uIndicator
= DOR_DROP
;
229 ulItems
= (ULONG
)::DrgQueryDragitemCount(m_pDragInfo
);
230 for (i
= 0; i
< ulItems
; i
++)
232 m_pDragItem
= ::DrgQueryDragitemPtr(m_pDragInfo
, i
);
233 if (((m_pDragItem
->fsSupportedOps
& DO_COPYABLE
) &&
234 (uOp
== (USHORT
)DO_COPY
)) ||
235 ((m_pDragItem
->fsSupportedOps
& DO_MOVEABLE
) &&
236 (uOp
== (USHORT
)DO_COPY
)))
238 if (::DrgVerifyRMF(m_pDragItem
, "DRM_OS2FILE", "DRF_UNKNOWN"))
239 uIndicator
= (USHORT
)DOR_DROP
;
241 uIndicator
= (USHORT
)DOR_NEVERDROP
;
246 // First ask the drop target if it wants data
248 if (m_pTarget
->OnDrop( m_pDragInfo
->xDrop
252 wxDragResult eRc
= wxDragNone
;
255 // And now it has the data
257 eRc
= m_pTarget
->OnData( m_pDragInfo
->xDrop
262 //else: OnDrop() returned false, no need to copy data
265 // Release the held object
268 return (MRFROM2SHORT(uIndicator
, uOp
));
269 } // end of CIDropTarget::Drop
271 // ----------------------------------------------------------------------------
273 // ----------------------------------------------------------------------------
275 wxDropTarget::wxDropTarget (
276 wxDataObject
* pDataObject
279 m_dataObject
= pDataObject
;
280 m_pDropTarget
= new CIDropTarget(this);
281 } // end of wxDropTarget::wxDropTarget
283 wxDropTarget::~wxDropTarget()
286 } // end of wxDropTarget::~wxDropTarget
288 bool wxDropTarget::GetData ()
290 wxDataFormat vFormat
= GetSupportedFormat(m_pDropTarget
->GetDataSource());
292 if (vFormat
== wxDF_INVALID
)
297 // Under OS/2 we already have the data via the attached DRAGITEM's
300 } // end of wxDropTarget::GetData
302 wxDataFormat
wxDropTarget::GetSupportedFormat (
303 PDRAGINFO pDataSource
307 wxDataFormat vFormat
;
308 wxDataFormat
* pFormats
;
309 ULONG ulFormats
= m_dataObject
->GetFormatCount(wxDataObject::Set
);
310 ULONG ulItems
= (ULONG
)::DrgQueryDragitemCount(pDataSource
);
317 pFormats
= ulFormats
== 1 ? &vFormat
: new wxDataFormat
[ulFormats
];
318 m_dataObject
->GetAllFormats( pFormats
322 for (n
= 0; n
< ulFormats
; n
++)
324 switch(pFormats
[n
].GetType())
329 sMechanism
= _T("DRM_OS2FILE");
330 sFormat
= _T("DRF_TEXT");
334 sMechanism
= _T("DRM_OS2FILE");
335 sFormat
= _T("DRF_OEMTEXT");
339 sMechanism
= _T("DRM_OS2FILE");
340 sFormat
= _T("DRF_BITMAP");
344 case wxDF_ENHMETAFILE
:
345 sMechanism
= _T("DRM_OS2FILE");
346 sFormat
= _T("DRF_METAFILE");
350 sMechanism
= _T("DRM_OS2FILE");
351 sFormat
= _T("DRF_TIFF");
355 sMechanism
= _T("DRM_OS2FILE");
356 sFormat
= _T("DRF_SYLK");
360 sMechanism
= _T("DRM_OS2FILE");
361 sFormat
= _T("DRF_DIF");
365 sMechanism
= _T("DRM_OS2FILE");
366 sFormat
= _T("DRF_DIB");
373 case wxDF_UNICODETEXT
:
375 sMechanism
= _T("DRM_OS2FILE");
376 sFormat
= _T("DRF_UNKNOWN");
380 sMechanism
= _T("DRM_OBJECT");
381 sFormat
= _T("DRF_UNKNOWN");
384 for (i
= 0; i
< ulItems
; i
++)
386 pDragItem
= ::DrgQueryDragitemPtr(pDataSource
, i
);
387 if (::DrgVerifyRMF(pDragItem
, (PSZ
)sMechanism
.c_str(), (PSZ
)sFormat
.c_str()))
395 vFormat
= pFormats
[n
];
399 if (pFormats
!= &vFormat
)
402 // Free memory if we allocated it
406 return (n
< ulFormats
? vFormat
: wxFormatInvalid
);
407 } // end of wxDropTarget::GetSupportedFormat
409 bool wxDropTarget::IsAcceptedData (
410 PDRAGINFO pDataSource
413 return (GetSupportedFormat(pDataSource
) != wxDF_INVALID
);
414 } // end of wxDropTarget::IsAcceptedData
416 void wxDropTarget::Release ()
418 m_pDropTarget
->Free();
419 } // end of wxDropTarget::Release
422 wxDragResult
wxDropTarget::OnData (
424 , wxCoord
WXUNUSED(y
)
425 , wxDragResult
WXUNUSED(vResult
)
428 return (wxDragResult
)0;
429 } // end of wxDropTarget::OnData
431 bool wxDropTarget::OnDrop (
433 , wxCoord
WXUNUSED(y
)
437 } // end of wxDropTarget::OnDrop
439 //-------------------------------------------------------------------------
441 //-------------------------------------------------------------------------
443 wxDropSource::wxDropSource ( wxWindow
* WXUNUSED(pWin
) )
446 } // end of wxDropSource::wxDropSource
448 wxDropSource::wxDropSource ( wxDataObject
& rData
, wxWindow
* WXUNUSED(pWin
) )
452 } // end of wxDropSource::wxDropSource
454 wxDropSource::~wxDropSource ()
456 ::DrgFreeDraginfo(m_pDragInfo
);
457 } // end of wxDropSource::~wxDropSource
459 wxDragResult
wxDropSource::DoDragDrop (
464 // Need to specify drag items in derived classes that know their data types
465 // before calling DoDragDrop
467 if (::DrgDrag( m_pWindow
->GetHWND()
475 switch(m_pDragInfo
->usOperation
)
491 } // end of wxDropSource::DoDragDrop
493 bool wxDropSource::GiveFeedback (
497 const wxCursor
& rCursor
= GetCursor(eEffect
);
501 ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)rCursor
.GetHCURSOR());
502 m_vDragImage
.hImage
= (LHANDLE
)rCursor
.GetHCURSOR();
506 m_pDragInfo
->usOperation
= DO_COPY
;
510 m_pDragInfo
->usOperation
= DO_MOVE
;
514 m_pDragInfo
->usOperation
= DO_LINK
;
528 } // end of GuiAdvDnd_CDropSource::GiveFeedback
530 void wxDropSource::Init ()
532 m_pDragInfo
= ::DrgAllocDraginfo(m_ulItems
);
535 // Set a default drag image struct with what we know so far
537 m_vDragImage
.cb
= sizeof(DRAGIMAGE
);
538 m_vDragImage
.cptl
= 0; // non-zero if fl is DRG_POLYGON
539 m_vDragImage
.hImage
= 0; // Set in GiveFeedback
540 m_vDragImage
.sizlStretch
.cx
= 20L;
541 m_vDragImage
.sizlStretch
.cy
= 20L;
542 m_vDragImage
.fl
= DRG_ICON
| DRG_STRETCH
;
543 m_vDragImage
.cxOffset
= 0;
544 m_vDragImage
.cyOffset
= 0;
546 HSTR hStrType
= ::DrgAddStrHandle(DRT_UNKNOWN
);
549 wxChar zFormats
[128];
550 wxChar zContainer
[128];
551 USHORT uSize
= (USHORT
)(GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()) + 1);
552 wxChar
* pzBuffer
= new wxChar
[uSize
];
554 memset(pzBuffer
, '\0', GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()));
555 pzBuffer
[GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat())] = '\0';
556 GetDataObject()->GetDataHere( GetDataObject()->GetPreferredFormat()
560 wxStrcpy(zFormats
, _T("<DRM_OS2FILE, DRF_UNKNOWN>"));
561 wxStrcpy(zContainer
, GetDataObject()->GetPreferredFormat().GetId());
563 hStrRMF
= ::DrgAddStrHandle((PSZ
)zFormats
);
564 hStrContainer
= ::DrgAddStrHandle((PSZ
)zContainer
);
566 m_pDragItem
= new DRAGITEM
[m_ulItems
];
567 for (ULONG i
= 0; i
< m_ulItems
; i
++)
569 m_pDragItem
[i
].hwndItem
= m_pWindow
->GetHWND();
570 m_pDragItem
[i
].hstrType
= hStrType
;
571 m_pDragItem
[i
].hstrRMF
= hStrRMF
;
572 m_pDragItem
[i
].hstrContainerName
= hStrContainer
;
573 m_pDragItem
[i
].fsControl
= 0;
574 m_pDragItem
[i
].fsSupportedOps
= DO_COPYABLE
| DO_MOVEABLE
| DO_LINKABLE
;
575 m_pDragItem
[i
].hstrSourceName
= ::DrgAddStrHandle((PSZ
)pzBuffer
);
576 m_pDragItem
[i
].hstrTargetName
= m_pDragItem
[i
].hstrSourceName
;
577 m_pDragItem
[i
].ulItemID
= i
;
578 ::DrgSetDragitem( m_pDragInfo
585 delete [] m_pDragItem
;
586 } // end of wxDropSource::Init
588 #endif //wxUSE_DRAG_AND_DROP