Support for new native OS/2 tree control with drag-and-drop.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@18909 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
David Webster
2003-01-24 22:31:41 +00:00
parent c0ae383ac0
commit 4fd899b671
13 changed files with 3769 additions and 576 deletions

View File

@@ -27,113 +27,560 @@
// global
// ----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
// Private functions
/////////////////////////////////////////////////////////////////////////////
static wxDragResult ConvertDragEffectToResult (
DWORD dwEffect
)
{
switch (dwEffect)
{
case DO_COPY:
return wxDragCopy;
case DO_LINK:
return wxDragLink;
case DO_MOVE:
return wxDragMove;
default:
case DO_DEFAULT:
return wxDragNone;
}
} // end of ConvertDragEffectToResult
static DWORD ConvertDragResultToEffect (
wxDragResult eResult
)
{
switch (eResult)
{
case wxDragCopy:
return DO_COPY;
case wxDragLink:
return DO_LINK;
case wxDragMove:
return DO_MOVE;
default:
case wxDragNone:
return DO_DEFAULT;
}
} // end of ConvertDragResultToEffect
class CIDropTarget
{
public:
CIDropTarget(wxDropTarget* pTarget)
{
m_pTarget = pTarget;
m_pDragItem = NULL;
}
virtual ~CIDropTarget() { }
//
// Accessors for CDropTarget
//
void Free(void) { ::DrgFreeDraginfo(m_pDragInfo); }
PDRAGINFO GetDataSource(void) { return m_pDragInfo; }
void SetDataSource(PDRAGINFO pDragInfo) { m_pDragInfo = pDragInfo; }
void SetHWND(HWND hWnd) { m_hWnd = hWnd; }
//
// CIDropTarget methods
//
bool DragLeave(void);
MRESULT DragOver(void);
MRESULT Drop(void);
protected:
PDRAGINFO m_pDragInfo;
PDRAGITEM m_pDragItem; // !NULL between DragEnter and DragLeave/Drop
wxDropTarget* m_pTarget; // the real target (we're just a proxy)
HWND m_hWnd; // window we're associated with
}; // end of CLASS CIDropTarget
bool CIDropTarget::DragLeave()
{
//
// Remove the UI feedback
//
m_pTarget->OnLeave();
//
// Release the held object
//
Free();
return TRUE;
} // end of CIDropTarget::DragLeave
MRESULT CIDropTarget::DragOver ()
{
char zBuffer[128];
ULONG ulBytes;
USHORT uOp;
USHORT uIndicator;
ULONG ulItems;
ULONG i;
::DrgAccessDraginfo(m_pDragInfo);
switch(m_pDragInfo->usOperation)
{
case DO_UNKNOWN:
Free();
return (MRFROM2SHORT(DOR_NODROPOP, 0));
case DO_DEFAULT:
m_pDragItem = ::DrgQueryDragitemPtr(m_pDragInfo, 0);
ulBytes = ::DrgQueryStrName( m_pDragItem->hstrContainerName
,128
,zBuffer
);
if (!ulBytes)
return (MRFROM2SHORT(DOR_NODROPOP, 0));
else
uOp = DO_MOVE;
break;
case DO_COPY:
case DO_MOVE:
uOp = m_pDragInfo->usOperation;
break;
}
uIndicator = DOR_DROP;
ulItems = (ULONG)::DrgQueryDragitemCount(m_pDragInfo);
for (i = 0; i < ulItems; i++)
{
m_pDragItem = ::DrgQueryDragitemPtr(m_pDragInfo, i);
if (((m_pDragItem->fsSupportedOps & DO_COPYABLE) &&
(uOp == (USHORT)DO_COPY)) ||
((m_pDragItem->fsSupportedOps & DO_MOVEABLE) &&
(uOp == (USHORT)DO_COPY)))
{
if (::DrgVerifyRMF(m_pDragItem, "DRM_OS2FILE", "DRF_UNKNOWN"))
uIndicator = (USHORT)DOR_DROP;
else
uIndicator = (USHORT)DOR_NEVERDROP;
}
}
Free();
return (MRFROM2SHORT(uIndicator, uOp));
} // end of CIDropTarget::DragOver
// #pragma page "CIDropTarget::Drop"
/////////////////////////////////////////////////////////////////////////////
//
// CIDropTarget::Drop
//
// Instructs the drop target to paste data that was just now dropped on it.
//
// PARAMETERS
// pIDataSource -- the data to paste
// dwKeyState -- kbd & mouse state
// pt -- mouse coordinates
// pdwEffect -- effect flag
//
// RETURN VALUE
// STDMETHODIMP S_OK
//
/////////////////////////////////////////////////////////////////////////////
MRESULT CIDropTarget::Drop ()
{
char zBuffer[128];
ULONG ulBytes;
USHORT uOp;
USHORT uIndicator;
ULONG ulItems;
ULONG i;
::DrgAccessDraginfo(m_pDragInfo);
switch(m_pDragInfo->usOperation)
{
case DO_UNKNOWN:
Free();
return (MRFROM2SHORT(DOR_NODROPOP, 0));
case DO_DEFAULT:
m_pDragItem = ::DrgQueryDragitemPtr(m_pDragInfo, 0);
ulBytes = ::DrgQueryStrName( m_pDragItem->hstrContainerName
,128
,zBuffer
);
if (!ulBytes)
return (MRFROM2SHORT(DOR_NODROPOP, 0));
else
uOp = DO_MOVE;
break;
case DO_COPY:
case DO_MOVE:
uOp = m_pDragInfo->usOperation;
break;
}
uIndicator = DOR_DROP;
ulItems = (ULONG)::DrgQueryDragitemCount(m_pDragInfo);
for (i = 0; i < ulItems; i++)
{
m_pDragItem = ::DrgQueryDragitemPtr(m_pDragInfo, i);
if (((m_pDragItem->fsSupportedOps & DO_COPYABLE) &&
(uOp == (USHORT)DO_COPY)) ||
((m_pDragItem->fsSupportedOps & DO_MOVEABLE) &&
(uOp == (USHORT)DO_COPY)))
{
if (::DrgVerifyRMF(m_pDragItem, "DRM_OS2FILE", "DRF_UNKNOWN"))
uIndicator = (USHORT)DOR_DROP;
else
uIndicator = (USHORT)DOR_NEVERDROP;
}
}
//
// First ask the drop target if it wants data
//
if (m_pTarget->OnDrop( m_pDragInfo->xDrop
,m_pDragInfo->yDrop
))
{
wxDragResult eRc;
//
// And now it has the data
//
eRc = m_pTarget->OnData( m_pDragInfo->xDrop
,m_pDragInfo->yDrop
,eRc
);
}
//else: OnDrop() returned FALSE, no need to copy data
//
// Release the held object
//
Free();
return (MRFROM2SHORT(uIndicator, uOp));
} // end of CIDropTarget::Drop
// ----------------------------------------------------------------------------
// wxDropTarget
// ----------------------------------------------------------------------------
wxDropTarget::wxDropTarget(
wxDropTarget::wxDropTarget (
wxDataObject* pDataObject
)
{
// TODO:
};
m_dataObject = pDataObject;
m_pDropTarget = new CIDropTarget(this);
} // end of wxDropTarget::wxDropTarget
wxDropTarget::~wxDropTarget()
{
};
Release();
} // end of wxDropTarget::~wxDropTarget
void wxDropTarget::Register(
WXHWND hwnd
bool wxDropTarget::GetData ()
{
wxDataFormat vFormat = GetSupportedFormat(m_pDropTarget->GetDataSource());
if (vFormat == wxDF_INVALID)
{
return FALSE;
}
//
// Under OS/2 we already have the data via the attached DRAGITEM's
//
return TRUE;
} // end of wxDropTarget::GetData
wxDataFormat wxDropTarget::GetSupportedFormat (
PDRAGINFO pDataSource
) const
{
PDRAGITEM pDragItem;
wxDataFormat vFormat;
wxDataFormat* pFormats;
ULONG ulFormats = m_dataObject->GetFormatCount(wxDataObject::Set);
ULONG ulItems = (ULONG)::DrgQueryDragitemCount(pDataSource);
ULONG i;
ULONG n;
wxString sMechanism;
wxString sFormat;
bool bValid = FALSE;
pFormats = ulFormats == 1 ? &vFormat : new wxDataFormat[ulFormats];
m_dataObject->GetAllFormats( pFormats
,wxDataObject::Set
);
for (n = 0; n < ulFormats; n++)
{
switch(pFormats[n].GetType())
{
case wxDF_TEXT:
case wxDF_FILENAME:
case wxDF_HTML:
sMechanism = "DRM_OS2FILE";
sFormat = "DRF_TEXT";
break;
case wxDF_OEMTEXT:
sMechanism = "DRM_OS2FILE";
sFormat = "DRF_OEMTEXT";
break;
case wxDF_BITMAP:
sMechanism = "DRM_OS2FILE";
sFormat = "DRF_BITMAP";
break;
case wxDF_METAFILE:
case wxDF_ENHMETAFILE:
sMechanism = "DRM_OS2FILE";
sFormat = "DRF_METAFILE";
break;
case wxDF_TIFF:
sMechanism = "DRM_OS2FILE";
sFormat = "DRF_TIFF";
break;
case wxDF_SYLK:
sMechanism = "DRM_OS2FILE";
sFormat = "DRF_SYLK";
break;
case wxDF_DIF:
sMechanism = "DRM_OS2FILE";
sFormat = "DRF_DIF";
break;
case wxDF_DIB:
sMechanism = "DRM_OS2FILE";
sFormat = "DRF_DIB";
break;
case wxDF_PALETTE:
case wxDF_PENDATA:
case wxDF_RIFF:
case wxDF_WAVE:
case wxDF_UNICODETEXT:
case wxDF_LOCALE:
sMechanism = "DRM_OS2FILE";
sFormat = "DRF_UNKNOWN";
break;
case wxDF_PRIVATE:
sMechanism = "DRM_OBJECT";
sFormat = "DRF_UNKNOWN";
break;
}
for (i = 0; i < ulItems; i++)
{
pDragItem = ::DrgQueryDragitemPtr(pDataSource, i);
if (::DrgVerifyRMF(pDragItem, sMechanism.c_str(), sFormat.c_str()))
{
bValid = TRUE;
break;
}
}
if (bValid)
{
vFormat = pFormats[n];
break;
}
}
if (pFormats != &vFormat)
{
//
// Free memory if we allocated it
//
delete [] pFormats;
}
return (n < ulFormats ? vFormat : wxFormatInvalid);
} // end of wxDropTarget::GetSupportedFormat
bool wxDropTarget::IsAcceptedData (
PDRAGINFO pDataSource
) const
{
return (GetSupportedFormat(pDataSource) != wxDF_INVALID);
} // end of wxDropTarget::IsAcceptedData
void wxDropTarget::Release ()
{
m_pDropTarget->Free();
} // end of wxDropTarget::Release
wxDragResult wxDropTarget::OnData (
wxCoord WXUNUSED(vX)
, wxCoord WXUNUSED(y)
, wxDragResult WXUNUSED(vResult)
)
{
//TODO:
};
void wxDropTarget::Revoke(
WXHWND hwnd
)
{
//TODO:
};
wxDragResult wxDropTarget::OnDragOver(
wxCoord x
, wxCoord y
, wxDragResult vDef
)
{
//TODO:
return vDef;
};
bool wxDropTarget::OnDrop(
wxCoord x
, wxCoord y
)
{
//TODO:
return FALSE;
};
wxDragResult wxDropTarget::OnData(
wxCoord x
, wxCoord y
, wxDragResult vResult
)
{
//TODO:
return (wxDragResult)0;
};
} // end of wxDropTarget::OnData
bool wxDropTarget::GetData()
{
//TODO:
return FALSE;
};
bool wxDropTarget::IsAcceptable(
DRAGINFO* pInfo
bool wxDropTarget::OnDrop (
wxCoord WXUNUSED(x)
, wxCoord WXUNUSED(y)
)
{
//TODO:
return FALSE;
};
return TRUE;
} // end of wxDropTarget::OnDrop
//-------------------------------------------------------------------------
// wxDropSource
//-------------------------------------------------------------------------
wxDropSource::wxDropSource(
wxDropSource::wxDropSource (
wxWindow* pWin
)
{
// TODO
};
Init();
} // end of wxDropSource::wxDropSource
wxDropSource::wxDropSource(
wxDropSource::wxDropSource (
wxDataObject& rData
, wxWindow* pWin
)
{
// TODO
};
Init();
SetData(rData);
} // end of wxDropSource::wxDropSource
wxDropSource::~wxDropSource()
wxDropSource::~wxDropSource ()
{
// TODO
};
::DrgFreeDraginfo(m_pDragInfo);
} // end of wxDropSource::~wxDropSource
wxDragResult wxDropSource::DoDragDrop(
wxDragResult wxDropSource::DoDragDrop (
int WXUNUSED(flags)
)
{
// TODO
return wxDragError;
};
//
// Need to specify drag items in derived classes that know their data types
// before calling DoDragDrop
//
if (::DrgDrag( m_pWindow->GetHWND()
,m_pDragInfo
,&m_vDragImage
,m_ulItems
,VK_BUTTON2
,NULL
) != NULLHANDLE)
{
switch(m_pDragInfo->usOperation)
{
case DO_COPY:
return wxDragCopy;
void wxDropSource::Init()
case DO_MOVE:
return wxDragCopy;
case DO_LINK:
return wxDragCopy;
default:
return wxDragNone;
}
}
return wxDragError;
} // end of wxDropSource::DoDragDrop
bool wxDropSource::GiveFeedback (
wxDragResult eEffect
)
{
// TODO
};
const wxCursor& rCursor = GetCursor(eEffect);
if (rCursor.Ok())
{
::WinSetPointer(HWND_DESKTOP, (HPOINTER)rCursor.GetHCURSOR());
m_vDragImage.hImage = (LHANDLE)rCursor.GetHCURSOR();
switch(eEffect)
{
case wxDragCopy:
m_pDragInfo->usOperation = DO_COPY;
break;
case wxDragMove:
m_pDragInfo->usOperation = DO_MOVE;
break;
case wxDragLink:
m_pDragInfo->usOperation = DO_LINK;
break;
}
return TRUE;
}
else
{
return FALSE;
}
} // end of GuiAdvDnd_CDropSource::GiveFeedback
void wxDropSource::Init ()
{
m_pDragInfo = ::DrgAllocDraginfo(m_ulItems);
//
// Set a default drag image struct with what we know so far
//
m_vDragImage.cb = sizeof(DRAGIMAGE);
m_vDragImage.cptl = 0; // non-zero if fl is DRG_POLYGON
m_vDragImage.hImage = 0; // Set in GiveFeedback
m_vDragImage.sizlStretch.cx = 20L;
m_vDragImage.sizlStretch.cy = 20L;
m_vDragImage.fl = DRG_ICON | DRG_STRETCH;
m_vDragImage.cxOffset = 0;
m_vDragImage.cyOffset = 0;
HSTR hStrType = ::DrgAddStrHandle(DRT_UNKNOWN);
HSTR hStrRMF;
HSTR hStrContainer;
char zFormats[128];
char zContainer[128];
USHORT uSize = GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()) + 1;
char* pzBuffer = new char[uSize];
memset(pzBuffer, '\0', GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat()));
pzBuffer[GetDataObject()->GetDataSize(GetDataObject()->GetPreferredFormat())] = '\0';
GetDataObject()->GetDataHere( GetDataObject()->GetPreferredFormat()
,(void*)pzBuffer
);
strcpy(zFormats, "<DRM_OS2FILE, DRF_UNKNOWN>");
strcpy(zContainer, GetDataObject()->GetPreferredFormat().GetId().c_str());
hStrRMF = ::DrgAddStrHandle(zFormats);
hStrContainer = ::DrgAddStrHandle(zContainer);
m_pDragItem = new DRAGITEM[m_ulItems];
for (ULONG i = 0; i < m_ulItems; i++);
{
m_pDragItem[i].hwndItem = m_pWindow->GetHWND();
m_pDragItem[i].hstrType = hStrType;
m_pDragItem[i].hstrRMF = hStrRMF;
m_pDragItem[i].hstrContainerName = hStrContainer;
m_pDragItem[i].fsControl = 0;
m_pDragItem[i].fsSupportedOps = DO_COPYABLE | DO_MOVEABLE | DO_LINKABLE;
m_pDragItem[i].hstrSourceName = ::DrgAddStrHandle(pzBuffer);
m_pDragItem[i].hstrTargetName = m_pDragItem[i].hstrSourceName;
m_pDragItem[i].ulItemID = i;
::DrgSetDragitem( m_pDragInfo
,&m_pDragItem[i]
,sizeof(DRAGITEM)
,0
);
}
delete [] pzBuffer;
delete [] m_pDragItem;
} // end of wxDropSource::Init
#endif //wxUSE_DRAG_AND_DROP