]>
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 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
19 #if wxUSE_DRAG_AND_DROP
21 #include "wx/window.h"
23 #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 (
452 } // end of wxDropSource::wxDropSource
454 wxDropSource::wxDropSource (
461 } // end of wxDropSource::wxDropSource
463 wxDropSource::~wxDropSource ()
465 ::DrgFreeDraginfo(m_pDragInfo
);
466 } // end of wxDropSource::~wxDropSource
468 wxDragResult
wxDropSource::DoDragDrop (
473 // Need to specify drag items in derived classes that know their data types
474 // before calling DoDragDrop
476 if (::DrgDrag( m_pWindow
->GetHWND()
484 switch(m_pDragInfo
->usOperation
)
500 } // end of wxDropSource::DoDragDrop
502 bool wxDropSource::GiveFeedback (
506 const wxCursor
& rCursor
= GetCursor(eEffect
);
510 ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)rCursor
.GetHCURSOR());
511 m_vDragImage
.hImage
= (LHANDLE
)rCursor
.GetHCURSOR();
515 m_pDragInfo
->usOperation
= DO_COPY
;
519 m_pDragInfo
->usOperation
= DO_MOVE
;
523 m_pDragInfo
->usOperation
= DO_LINK
;
537 } // end of GuiAdvDnd_CDropSource::GiveFeedback
539 void wxDropSource::Init ()
541 m_pDragInfo
= ::DrgAllocDraginfo(m_ulItems
);
544 // Set a default drag image struct with what we know so far
546 m_vDragImage
.cb
= sizeof(DRAGIMAGE
);
547 m_vDragImage
.cptl
= 0; // non-zero if fl is DRG_POLYGON
548 m_vDragImage
.hImage
= 0; // Set in GiveFeedback
549 m_vDragImage
.sizlStretch
.cx
= 20L;
550 m_vDragImage
.sizlStretch
.cy
= 20L;
551 m_vDragImage
.fl
= DRG_ICON
| DRG_STRETCH
;
552 m_vDragImage
.cxOffset
= 0;
553 m_vDragImage
.cyOffset
= 0;
555 HSTR hStrType
= ::DrgAddStrHandle(DRT_UNKNOWN
);
558 wxChar zFormats
[128];
559 wxChar zContainer
[128];
560 USHORT uSize
= GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()) + 1;
561 wxChar
* pzBuffer
= new wxChar
[uSize
];
563 memset(pzBuffer
, '\0', GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()));
564 pzBuffer
[GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat())] = '\0';
565 GetDataObject()->GetDataHere( GetDataObject()->GetPreferredFormat()
569 wxStrcpy(zFormats
, _T("<DRM_OS2FILE, DRF_UNKNOWN>"));
570 wxStrcpy(zContainer
, GetDataObject()->GetPreferredFormat().GetId());
572 hStrRMF
= ::DrgAddStrHandle((PSZ
)zFormats
);
573 hStrContainer
= ::DrgAddStrHandle((PSZ
)zContainer
);
575 m_pDragItem
= new DRAGITEM
[m_ulItems
];
576 for (ULONG i
= 0; i
< m_ulItems
; i
++)
578 m_pDragItem
[i
].hwndItem
= m_pWindow
->GetHWND();
579 m_pDragItem
[i
].hstrType
= hStrType
;
580 m_pDragItem
[i
].hstrRMF
= hStrRMF
;
581 m_pDragItem
[i
].hstrContainerName
= hStrContainer
;
582 m_pDragItem
[i
].fsControl
= 0;
583 m_pDragItem
[i
].fsSupportedOps
= DO_COPYABLE
| DO_MOVEABLE
| DO_LINKABLE
;
584 m_pDragItem
[i
].hstrSourceName
= ::DrgAddStrHandle((PSZ
)pzBuffer
);
585 m_pDragItem
[i
].hstrTargetName
= m_pDragItem
[i
].hstrSourceName
;
586 m_pDragItem
[i
].ulItemID
= i
;
587 ::DrgSetDragitem( m_pDragInfo
594 delete [] m_pDragItem
;
595 } // end of wxDropSource::Init
597 #endif //wxUSE_DRAG_AND_DROP