]>
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
7 // Copyright: (c) 1998 AUTHOR
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
14 #if wxUSE_DRAG_AND_DROP
20 #include "wx/window.h"
21 #include "wx/gdicmn.h"
28 // ----------------------------------------------------------------------------
30 // ----------------------------------------------------------------------------
32 /////////////////////////////////////////////////////////////////////////////
34 /////////////////////////////////////////////////////////////////////////////
37 static wxDragResult
ConvertDragEffectToResult (
56 } // end of ConvertDragEffectToResult
58 static DWORD
ConvertDragResultToEffect (
77 } // end of ConvertDragResultToEffect
83 CIDropTarget(wxDropTarget
* pTarget
)
88 virtual ~CIDropTarget() { }
91 // Accessors for CDropTarget
93 void Free(void) { ::DrgFreeDraginfo(m_pDragInfo
); }
94 PDRAGINFO
GetDataSource(void) { return m_pDragInfo
; }
95 void SetDataSource(PDRAGINFO pDragInfo
) { m_pDragInfo
= pDragInfo
; }
96 void SetHWND(HWND hWnd
) { m_hWnd
= hWnd
; }
99 // CIDropTarget methods
101 bool DragLeave(void);
102 MRESULT
DragOver(void);
107 PDRAGINFO m_pDragInfo
;
108 PDRAGITEM m_pDragItem
; // !NULL between DragEnter and DragLeave/Drop
109 wxDropTarget
* m_pTarget
; // the real target (we're just a proxy)
110 HWND m_hWnd
; // window we're associated with
111 }; // end of CLASS CIDropTarget
113 bool CIDropTarget::DragLeave()
116 // Remove the UI feedback
118 m_pTarget
->OnLeave();
121 // Release the held object
125 } // end of CIDropTarget::DragLeave
127 MRESULT
CIDropTarget::DragOver ()
136 ::DrgAccessDraginfo(m_pDragInfo
);
137 switch(m_pDragInfo
->usOperation
)
141 return (MRFROM2SHORT(DOR_NODROPOP
, 0));
144 m_pDragItem
= ::DrgQueryDragitemPtr(m_pDragInfo
, 0);
145 ulBytes
= ::DrgQueryStrName( m_pDragItem
->hstrContainerName
150 return (MRFROM2SHORT(DOR_NODROPOP
, 0));
157 uOp
= m_pDragInfo
->usOperation
;
160 uIndicator
= DOR_DROP
;
161 ulItems
= (ULONG
)::DrgQueryDragitemCount(m_pDragInfo
);
162 for (i
= 0; i
< ulItems
; i
++)
164 m_pDragItem
= ::DrgQueryDragitemPtr(m_pDragInfo
, i
);
165 if (((m_pDragItem
->fsSupportedOps
& DO_COPYABLE
) &&
166 (uOp
== (USHORT
)DO_COPY
)) ||
167 ((m_pDragItem
->fsSupportedOps
& DO_MOVEABLE
) &&
168 (uOp
== (USHORT
)DO_COPY
)))
170 if (::DrgVerifyRMF(m_pDragItem
, "DRM_OS2FILE", "DRF_UNKNOWN"))
171 uIndicator
= (USHORT
)DOR_DROP
;
173 uIndicator
= (USHORT
)DOR_NEVERDROP
;
177 return (MRFROM2SHORT(uIndicator
, uOp
));
178 } // end of CIDropTarget::DragOver
180 // #pragma page "CIDropTarget::Drop"
181 /////////////////////////////////////////////////////////////////////////////
183 // CIDropTarget::Drop
185 // Instructs the drop target to paste data that was just now dropped on it.
188 // pIDataSource -- the data to paste
189 // dwKeyState -- kbd & mouse state
190 // pt -- mouse coordinates
191 // pdwEffect -- effect flag
196 /////////////////////////////////////////////////////////////////////////////
197 MRESULT
CIDropTarget::Drop ()
206 ::DrgAccessDraginfo(m_pDragInfo
);
207 switch(m_pDragInfo
->usOperation
)
211 return (MRFROM2SHORT(DOR_NODROPOP
, 0));
214 m_pDragItem
= ::DrgQueryDragitemPtr(m_pDragInfo
, 0);
215 ulBytes
= ::DrgQueryStrName( m_pDragItem
->hstrContainerName
220 return (MRFROM2SHORT(DOR_NODROPOP
, 0));
227 uOp
= m_pDragInfo
->usOperation
;
230 uIndicator
= DOR_DROP
;
231 ulItems
= (ULONG
)::DrgQueryDragitemCount(m_pDragInfo
);
232 for (i
= 0; i
< ulItems
; i
++)
234 m_pDragItem
= ::DrgQueryDragitemPtr(m_pDragInfo
, i
);
235 if (((m_pDragItem
->fsSupportedOps
& DO_COPYABLE
) &&
236 (uOp
== (USHORT
)DO_COPY
)) ||
237 ((m_pDragItem
->fsSupportedOps
& DO_MOVEABLE
) &&
238 (uOp
== (USHORT
)DO_COPY
)))
240 if (::DrgVerifyRMF(m_pDragItem
, "DRM_OS2FILE", "DRF_UNKNOWN"))
241 uIndicator
= (USHORT
)DOR_DROP
;
243 uIndicator
= (USHORT
)DOR_NEVERDROP
;
248 // First ask the drop target if it wants data
250 if (m_pTarget
->OnDrop( m_pDragInfo
->xDrop
254 wxDragResult eRc
= wxDragNone
;
257 // And now it has the data
259 eRc
= m_pTarget
->OnData( m_pDragInfo
->xDrop
264 //else: OnDrop() returned false, no need to copy data
267 // Release the held object
270 return (MRFROM2SHORT(uIndicator
, uOp
));
271 } // end of CIDropTarget::Drop
273 // ----------------------------------------------------------------------------
275 // ----------------------------------------------------------------------------
277 wxDropTarget::wxDropTarget (
278 wxDataObject
* pDataObject
281 m_dataObject
= pDataObject
;
282 m_pDropTarget
= new CIDropTarget(this);
283 } // end of wxDropTarget::wxDropTarget
285 wxDropTarget::~wxDropTarget()
288 } // end of wxDropTarget::~wxDropTarget
290 bool wxDropTarget::GetData ()
292 wxDataFormat vFormat
= GetSupportedFormat(m_pDropTarget
->GetDataSource());
294 if (vFormat
== wxDF_INVALID
)
299 // Under OS/2 we already have the data via the attached DRAGITEM's
302 } // end of wxDropTarget::GetData
304 wxDataFormat
wxDropTarget::GetSupportedFormat (
305 PDRAGINFO pDataSource
309 wxDataFormat vFormat
;
310 wxDataFormat
* pFormats
;
311 ULONG ulFormats
= m_dataObject
->GetFormatCount(wxDataObject::Set
);
312 ULONG ulItems
= (ULONG
)::DrgQueryDragitemCount(pDataSource
);
319 pFormats
= ulFormats
== 1 ? &vFormat
: new wxDataFormat
[ulFormats
];
320 m_dataObject
->GetAllFormats( pFormats
324 for (n
= 0; n
< ulFormats
; n
++)
326 switch(pFormats
[n
].GetType())
331 sMechanism
= wxT("DRM_OS2FILE");
332 sFormat
= wxT("DRF_TEXT");
336 sMechanism
= wxT("DRM_OS2FILE");
337 sFormat
= wxT("DRF_OEMTEXT");
341 sMechanism
= wxT("DRM_OS2FILE");
342 sFormat
= wxT("DRF_BITMAP");
346 case wxDF_ENHMETAFILE
:
347 sMechanism
= wxT("DRM_OS2FILE");
348 sFormat
= wxT("DRF_METAFILE");
352 sMechanism
= wxT("DRM_OS2FILE");
353 sFormat
= wxT("DRF_TIFF");
357 sMechanism
= wxT("DRM_OS2FILE");
358 sFormat
= wxT("DRF_SYLK");
362 sMechanism
= wxT("DRM_OS2FILE");
363 sFormat
= wxT("DRF_DIF");
367 sMechanism
= wxT("DRM_OS2FILE");
368 sFormat
= wxT("DRF_DIB");
375 case wxDF_UNICODETEXT
:
377 sMechanism
= wxT("DRM_OS2FILE");
378 sFormat
= wxT("DRF_UNKNOWN");
382 sMechanism
= wxT("DRM_OBJECT");
383 sFormat
= wxT("DRF_UNKNOWN");
386 for (i
= 0; i
< ulItems
; i
++)
388 pDragItem
= ::DrgQueryDragitemPtr(pDataSource
, i
);
389 if (::DrgVerifyRMF(pDragItem
, sMechanism
.c_str(), sFormat
.c_str()))
397 vFormat
= pFormats
[n
];
401 if (pFormats
!= &vFormat
)
404 // Free memory if we allocated it
408 return (n
< ulFormats
? vFormat
: wxFormatInvalid
);
409 } // end of wxDropTarget::GetSupportedFormat
411 bool wxDropTarget::IsAcceptedData (
412 PDRAGINFO pDataSource
415 return (GetSupportedFormat(pDataSource
) != wxDF_INVALID
);
416 } // end of wxDropTarget::IsAcceptedData
418 void wxDropTarget::Release ()
420 m_pDropTarget
->Free();
421 } // end of wxDropTarget::Release
424 wxDragResult
wxDropTarget::OnData (
426 , wxCoord
WXUNUSED(y
)
427 , wxDragResult
WXUNUSED(vResult
)
430 return (wxDragResult
)0;
431 } // end of wxDropTarget::OnData
433 bool wxDropTarget::OnDrop (
435 , wxCoord
WXUNUSED(y
)
439 } // end of wxDropTarget::OnDrop
441 //-------------------------------------------------------------------------
443 //-------------------------------------------------------------------------
445 wxDropSource::wxDropSource ( wxWindow
* WXUNUSED(pWin
) )
448 } // end of wxDropSource::wxDropSource
450 wxDropSource::wxDropSource ( wxDataObject
& rData
, wxWindow
* WXUNUSED(pWin
) )
454 } // end of wxDropSource::wxDropSource
456 wxDropSource::~wxDropSource ()
458 ::DrgFreeDraginfo(m_pDragInfo
);
459 } // end of wxDropSource::~wxDropSource
461 wxDragResult
wxDropSource::DoDragDrop (
466 // Need to specify drag items in derived classes that know their data types
467 // before calling DoDragDrop
469 if (::DrgDrag( m_pWindow
->GetHWND()
477 switch(m_pDragInfo
->usOperation
)
493 } // end of wxDropSource::DoDragDrop
495 bool wxDropSource::GiveFeedback (
499 const wxCursor
& rCursor
= GetCursor(eEffect
);
503 ::WinSetPointer(HWND_DESKTOP
, (HPOINTER
)rCursor
.GetHCURSOR());
504 m_vDragImage
.hImage
= (LHANDLE
)rCursor
.GetHCURSOR();
508 m_pDragInfo
->usOperation
= DO_COPY
;
512 m_pDragInfo
->usOperation
= DO_MOVE
;
516 m_pDragInfo
->usOperation
= DO_LINK
;
530 } // end of GuiAdvDnd_CDropSource::GiveFeedback
532 void wxDropSource::Init ()
534 m_pDragInfo
= ::DrgAllocDraginfo(m_ulItems
);
537 // Set a default drag image struct with what we know so far
539 m_vDragImage
.cb
= sizeof(DRAGIMAGE
);
540 m_vDragImage
.cptl
= 0; // non-zero if fl is DRG_POLYGON
541 m_vDragImage
.hImage
= 0; // Set in GiveFeedback
542 m_vDragImage
.sizlStretch
.cx
= 20L;
543 m_vDragImage
.sizlStretch
.cy
= 20L;
544 m_vDragImage
.fl
= DRG_ICON
| DRG_STRETCH
;
545 m_vDragImage
.cxOffset
= 0;
546 m_vDragImage
.cyOffset
= 0;
548 HSTR hStrType
= ::DrgAddStrHandle(DRT_UNKNOWN
);
551 wxChar zFormats
[128];
552 wxChar zContainer
[128];
553 USHORT uSize
= (USHORT
)(GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()) + 1);
554 wxChar
* pzBuffer
= new wxChar
[uSize
];
556 memset(pzBuffer
, '\0', GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()));
557 pzBuffer
[GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat())] = '\0';
558 GetDataObject()->GetDataHere( GetDataObject()->GetPreferredFormat()
562 wxStrcpy(zFormats
, wxT("<DRM_OS2FILE, DRF_UNKNOWN>"));
563 wxStrcpy(zContainer
, GetDataObject()->GetPreferredFormat().GetId());
565 hStrRMF
= ::DrgAddStrHandle((PSZ
)zFormats
);
566 hStrContainer
= ::DrgAddStrHandle((PSZ
)zContainer
);
568 m_pDragItem
= new DRAGITEM
[m_ulItems
];
569 for (ULONG i
= 0; i
< m_ulItems
; i
++)
571 m_pDragItem
[i
].hwndItem
= m_pWindow
->GetHWND();
572 m_pDragItem
[i
].hstrType
= hStrType
;
573 m_pDragItem
[i
].hstrRMF
= hStrRMF
;
574 m_pDragItem
[i
].hstrContainerName
= hStrContainer
;
575 m_pDragItem
[i
].fsControl
= 0;
576 m_pDragItem
[i
].fsSupportedOps
= DO_COPYABLE
| DO_MOVEABLE
| DO_LINKABLE
;
577 m_pDragItem
[i
].hstrSourceName
= ::DrgAddStrHandle((PSZ
)pzBuffer
);
578 m_pDragItem
[i
].hstrTargetName
= m_pDragItem
[i
].hstrSourceName
;
579 m_pDragItem
[i
].ulItemID
= i
;
580 ::DrgSetDragitem( m_pDragInfo
587 delete [] m_pDragItem
;
588 } // end of wxDropSource::Init
590 #endif //wxUSE_DRAG_AND_DROP