DataObject.h
上传用户:hy_wanghao
上传日期:2007-01-08
资源大小:279k
文件大小:12k
- #if !defined(AFX_DATAOBJECT_H__20001229_075F_904E_7D1B_0080AD509054__INCLUDED_)
- #define AFX_DATAOBJECT_H__20001229_075F_904E_7D1B_0080AD509054__INCLUDED_
- #pragma once
- #include "AmigaFileStream.h"
- #include "Misc.h"
- #include "EnumFormatETC.h"
- /////////////////////////////////////////////////////////////////////////////
- // CDataObject
- class ATL_NO_VTABLE CDataObject :
- public CComObjectRootEx<CComSingleThreadModel>,
- public IDataObject
- {
- public:
- DECLARE_NOT_AGGREGATABLE(CDataObject)
- DECLARE_PROTECT_FINAL_CONSTRUCT()
- BEGIN_COM_MAP(CDataObject)
- COM_INTERFACE_ENTRY(IDataObject)
- END_COM_MAP()
- CFolder *m_pFolder; // CFolder reference
- CPidlList m_pidls; // The list of files
- // The source window's HWND
- HWND m_hWnd;
- // These flags are used in the communication going on when doing
- // a copy/cut/paste operation.
- DWORD m_dwPasteSucceeded;
- DWORD m_dwPerformedDropEffect;
- DWORD m_dwPreferredDropEffect;
- HRESULT FinalConstruct()
- {
- m_pFolder = NULL;
- m_hWnd = NULL;
- m_dwPasteSucceeded =
- m_dwPerformedDropEffect =
- m_dwPreferredDropEffect = DROPEFFECT_NONE;
- return S_OK;
- }
- void FinalRelease()
- {
- if( m_pFolder!=NULL ) m_pFolder->Release();
- }
- HRESULT _Init(CFolder *pFolder, HWND hWnd, LPCITEMIDLIST *pPidls, int nCount)
- {
- ATLTRACE(_T("CDataObject::_Initn"));
- ATLASSERT(pFolder);
- ATLASSERT(pPidls);
- m_pFolder = pFolder;
- m_pFolder->AddRef();
- m_hWnd = hWnd;
- m_pidls.Copy(pPidls, nCount, TRUE);
- return S_OK;
- }
- private:
- HRESULT _GetAmigaFileDescriptor(CAdfVolume &vol, int i, FILEDESCRIPTOR *p)
- {
- ATLASSERT(vol.IsOpen());
- ATLASSERT(p);
-
- ::ZeroMemory(p, sizeof(FILEDESCRIPTOR));
- CPidl pidl;
- pidl.Copy(m_pFolder->m_pidlPath);
- pidl.Concatenate(m_pidls[i]);
- TCHAR szPath[MAX_PATH];
- PidlGetFilePath(szPath, pidl);
- if( vol.ChangeDirectory(szPath)==FALSE ) return E_FAIL;
- // Get information about the file
- CAdfFile f;
- TCHAR szName[MAXNAMELEN+1];
- PidlGetName(szName, pidl);
- if( vol.GetFile(szName, _T("r"), f)==FALSE ) return E_FAIL;
- p->dwFlags = FD_FILESIZE | FD_CREATETIME | FD_WRITESTIME | FD_ATTRIBUTES;
- f.GetName(p->cFileName, lengthof(p->cFileName));
- p->nFileSizeHigh = 0;
- p->nFileSizeLow = f.GetSize();
- p->ftCreationTime = f.GetFileTime();
- p->ftLastWriteTime = f.GetFileTime();
- DWORD dwAttribs = 0;
- if( f.IsDirectory() ) dwAttribs |= FILE_ATTRIBUTE_DIRECTORY;
- DWORD dwAccess = f.GetAccess();
- if( hasW(dwAccess) ) dwAttribs |= FILE_ATTRIBUTE_READONLY;
- if( hasH(dwAccess) ) dwAttribs |= FILE_ATTRIBUTE_HIDDEN;
- if( hasA(dwAccess) ) dwAttribs |= FILE_ATTRIBUTE_ARCHIVE;
- if( dwAttribs==0 ) dwAttribs = FILE_ATTRIBUTE_NORMAL;
- p->dwFileAttributes = dwAttribs;
- // BUG: We loose several Amiga file attributes
- return S_OK;
- }
- HRESULT _GetFileDescriptors(FILEDESCRIPTOR *p)
- {
- ATLASSERT(p);
- CAdfDevice dev;
- CAdfVolume vol;
- HRESULT Hr;
- HR( m_pFolder->_OpenAmigaDevice(m_pFolder->m_pidl, TRUE, NULL, dev, vol) );
- for( UINT i=0; i<m_pidls.GetCount(); i++ ) {
- _GetAmigaFileDescriptor(vol,i,p);
- p++;
- }
- return S_OK;
- }
- // IDataObject
- public:
- STDMETHOD(GetData)(FORMATETC *pFormatetc, STGMEDIUM *pMedium)
- {
- ATLTRACE(_T("CDataObject::GetDatan"));
- ATLASSERT(m_pFolder);
- VALIDATE_POINTER(pFormatetc);
- VALIDATE_POINTER(pMedium);
- if( m_pidls.GetCount()==0 ) return E_UNEXPECTED;
- ATLTRACE(_T("Format = 0x%04x, '%s'n"), pFormatetc->cfFormat, DbgGetCF(pFormatetc->cfFormat));
- ATLTRACE(_T("TYMED = 0x%04xn"), pFormatetc->tymed);
- HRESULT Hr;
- ::ZeroMemory(pMedium, sizeof(STGMEDIUM));
- if( pFormatetc->cfFormat == _Module.m_CFSTR_ADFID ) {
- // Internal CF used to query which CFolder the IDataObject comes from
- HR( _GetDWORD(pMedium, m_pFolder->m_dwFolderID) );
- return S_OK;
- }
- else if( pFormatetc->cfFormat == _Module.m_CFSTR_FILEDESCRIPTOR ) {
- // The CFSTR_FILEDESCRIPTOR format will be queried by the Shell before
- // the CFSTR_FILECONTENTS.
- // It returns descriptions of the files the IDataObject contains.
- if( (pFormatetc->tymed & TYMED_HGLOBAL)==0 ) return DV_E_TYMED;
-
- FILEGROUPDESCRIPTOR fgd = { 0 };
- DWORD fgd_size = sizeof(fgd)-sizeof(FILEDESCRIPTOR);
- fgd.cItems = m_pidls.GetCount();
- DWORD dwTotalSize = fgd_size + (sizeof(FILEDESCRIPTOR)*fgd.cItems);
- HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT | GMEM_DISCARDABLE, dwTotalSize);
- if( hMem==NULL ) return E_OUTOFMEMORY;
- LPBYTE p = (LPBYTE)::GlobalLock(hMem);
- ::CopyMemory(p, &fgd, fgd_size );
- p += fgd_size;
- HR( _GetFileDescriptors((FILEDESCRIPTOR *)p) );
- ::GlobalUnlock(hMem);
- pMedium->tymed = TYMED_HGLOBAL;
- pMedium->hGlobal = hMem;
- pMedium->pUnkForRelease = NULL;
- return S_OK;
- }
- else if( pFormatetc->cfFormat == _Module.m_CFSTR_FILECONTENTS ) {
- // The CFSTR_FILECONTENTS gets called for each file.
- // It must return the IStream for the file.
- if( (pFormatetc->tymed & TYMED_ISTREAM)==0 ) return DV_E_TYMED;
- // HACK: Explorer will call us with index -1 when clipdata goes
- // out of scope (view closes) ????
- LONG iIndex = pFormatetc->lindex;
- if( iIndex<0 || iIndex>=(LONG)(m_pidls.GetCount()) ) return DV_E_LINDEX;
- // Need to initialize Stream attributes
- CPidl pidl;
- pidl.Copy(m_pFolder->m_pidlPath);
- pidl.Concatenate(m_pidls[iIndex]);
- // Extract the filepath and name contained in the
- // full PIDL.
- TCHAR szPath[MAX_PATH];
- TCHAR szName[MAXNAMELEN+1];
- PidlGetFilePath(szPath, pidl);
- PidlGetName(szName, pidl);
- CComObject<CAmigaFileStream> *pStream;
- HR( CComObject<CAmigaFileStream>::CreateInstance(&pStream) );
- HR( pStream->_Init(m_pFolder->m_pidl, szPath, szName) );
- HR( pStream->QueryInterface(IID_IStream, (LPVOID *)&pMedium->pstm) );
- pMedium->tymed = TYMED_ISTREAM;
- pMedium->pUnkForRelease = NULL;
- return S_OK;
- }
- else if( pFormatetc->cfFormat == _Module.m_CFSTR_PERFORMEDDROPEFFECT ) {
- HR( _GetDWORD(pMedium, m_dwPerformedDropEffect) );
- return S_OK;
- }
- else if( pFormatetc->cfFormat == _Module.m_CFSTR_PREFERREDDROPEFFECT ) {
- // If we're not doing a "cut" operation (like in cut&paste)
- // let the IDropTarget decide which effect we prefer.
- if( m_dwPreferredDropEffect==DROPEFFECT_NONE ) return DV_E_FORMATETC;
- HR( _GetDWORD(pMedium, m_dwPreferredDropEffect) );
- return S_OK;
- }
- return DV_E_FORMATETC;
- }
- STDMETHOD(GetDataHere)(FORMATETC* /*pFormatetc*/, STGMEDIUM* /*pMedium*/)
- {
- ATLTRACENOTIMPL(_T("CDataObject::GetDataHere"));
- }
- STDMETHOD(QueryGetData)(FORMATETC* pFormatetc)
- {
- ATLASSERT(pFormatetc);
- ATLTRACE(_T("CDataObject::QueryGetData = 0x%04x, '%s'n"), pFormatetc->cfFormat, DbgGetCF(pFormatetc->cfFormat));
- if( pFormatetc->cfFormat!=_Module.m_CFSTR_FILEDESCRIPTOR &&
- pFormatetc->cfFormat!=_Module.m_CFSTR_FILECONTENTS )
- {
- return DV_E_FORMATETC;
- }
- if( (pFormatetc->dwAspect & DVASPECT_CONTENT)==0 )
- {
- return DV_E_DVASPECT;
- }
- return S_OK;
- }
- STDMETHOD(EnumFormatEtc)(DWORD /*dwDirection*/, IEnumFORMATETC** ppenumFormatEtc)
- {
- ATLTRACE(_T("CDataObject::EnumFormatEtcn"));
- VALIDATE_POINTER(ppenumFormatEtc);
- HRESULT Hr;
- CComObject<CEnumFORMATETC> *obj;
- HR( CComObject<CEnumFORMATETC>::CreateInstance(&obj) );
- return obj->QueryInterface(IID_IEnumFORMATETC, (LPVOID *)ppenumFormatEtc);
- }
- STDMETHOD(SetData)(FORMATETC* pFormatEtc, STGMEDIUM* pMedium, BOOL fRelease)
- {
- ATLTRACE(_T("CDataObject::SetDatan"));
- ATLASSERT(m_pFolder);
- VALIDATE_POINTER(pFormatEtc);
- VALIDATE_POINTER(pMedium);
- HRESULT Hr;
- ATLTRACE(_T("Format = 0x%04x, '%s'n"), pFormatEtc->cfFormat, DbgGetCF(pFormatEtc->cfFormat));
- ATLTRACE(_T("TYMED = 0x%04xn"), pFormatEtc->tymed);
- if( pFormatEtc->cfFormat == _Module.m_CFSTR_PASTESUCCEEDED ) {
- HR( _SetDWORD(pMedium, fRelease, m_dwPasteSucceeded) );
- // To handle Delete-on-Paste, we check this guy...
- if( m_dwPasteSucceeded==DROPEFFECT_MOVE ) {
- // If we all agreed that it was a 'move', then we're
- // responsible for deleting the files.
- if( m_dwPerformedDropEffect==DROPEFFECT_MOVE ) {
- m_pFolder->_DeleteFiles(m_pidls, m_pidls.GetCount());
- ::OleSetClipboard(NULL);
- }
- // At least we should refresh the view
- m_pFolder->_SendViewMessage(m_hWnd, WM_COMMAND, ID_VIEW_REFRESH);
- }
- return S_OK;
- }
- else if( pFormatEtc->cfFormat == _Module.m_CFSTR_PERFORMEDDROPEFFECT ) {
- HR( _SetDWORD(pMedium, fRelease, m_dwPerformedDropEffect) );
- return S_OK;
- }
- else if( pFormatEtc->cfFormat == _Module.m_CFSTR_PREFERREDDROPEFFECT ) {
- HR( _SetDWORD(pMedium, fRelease, m_dwPreferredDropEffect) );
- return S_OK;
- }
- return DV_E_FORMATETC;
- }
- STDMETHOD(GetCanonicalFormatEtc)(FORMATETC*, FORMATETC*)
- {
- ATLTRACENOTIMPL(_T("CDataObject::GetCanonicalFormatEtc"));
- }
- STDMETHOD(DAdvise)(FORMATETC *, DWORD, IAdviseSink *, DWORD *)
- {
- ATLTRACENOTIMPL(_T("CDataObject::DAdvise"));
- }
- STDMETHOD(DUnadvise)(DWORD)
- {
- ATLTRACENOTIMPL(_T("CDataObject::DUnadvise"));
- }
- STDMETHOD(EnumDAdvise)(IEnumSTATDATA **)
- {
- ATLTRACENOTIMPL(_T("CDataObject::EnumDAdvise"));
- }
- // Implementation
- HRESULT _SetDWORD(STGMEDIUM *pMedium, BOOL fRelease, DWORD &dwData)
- {
- ATLASSERT(pMedium);
- ATLASSERT(pMedium->hGlobal);
- LPDWORD p = (LPDWORD)::GlobalLock(pMedium->hGlobal);
- ATLASSERT(p);
- if( p==NULL ) return E_OUTOFMEMORY;
- dwData = *p;
- ::GlobalUnlock(pMedium->hGlobal);
- if( fRelease ) ::ReleaseStgMedium(pMedium);
- return S_OK;
- }
- HRESULT _GetDWORD(STGMEDIUM *pMedium, DWORD dwData)
- {
- ATLASSERT(pMedium);
- HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE | GMEM_DISCARDABLE, sizeof(DWORD));
- if( hMem==NULL ) return E_OUTOFMEMORY;
- LPDWORD p = (LPDWORD)::GlobalLock(hMem);
- ATLASSERT(p);
- *p = dwData;
- ::GlobalUnlock(hMem);
- pMedium->tymed = TYMED_HGLOBAL;
- pMedium->hGlobal = hMem;
- pMedium->pUnkForRelease = NULL;
- return S_OK;
- }
- };
- /////////////////////////////////////////////////////////////////////////////
- // IDataObject helper functions
- ATLINLINE HRESULT DataObj_SetDWORD(IDataObject *pDataObj, CLIPFORMAT cf, DWORD dw)
- {
- ATLASSERT(pDataObj);
- HRESULT Hr = E_OUTOFMEMORY;
- LPDWORD pdw = (LPDWORD)::GlobalAlloc(GPTR, sizeof(DWORD));
- if( pdw ) {
- FORMATETC fmte = { cf, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
- STGMEDIUM medium;
- *pdw = dw;
- medium.tymed = TYMED_HGLOBAL;
- medium.hGlobal = pdw;
- medium.pUnkForRelease = NULL;
- Hr = pDataObj->SetData(&fmte, &medium, TRUE);
- if( FAILED(Hr) ) ::GlobalFree((HGLOBAL)pdw);
- }
- return Hr;
- }
- ATLINLINE HRESULT DataObj_GetDWORD(IDataObject *pDataObj, CLIPFORMAT cf, LPDWORD pdwOut)
- {
- ATLASSERT(pDataObj);
- ATLASSERT(pdwOut);
- FORMATETC fmte = { cf, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
- STGMEDIUM medium;
- HRESULT Hr = pDataObj->GetData(&fmte, &medium);
- if( SUCCEEDED(Hr) ) {
- LPDWORD pdw = (LPDWORD)::GlobalLock(medium.hGlobal);
- if( pdw ) {
- *pdwOut = *pdw;
- ::GlobalUnlock(medium.hGlobal);
- }
- else {
- Hr = E_UNEXPECTED;
- }
- ::ReleaseStgMedium(&medium);
- }
- return Hr;
- }
- #endif // !defined(AFX_DATAOBJECT_H__20001229_075F_904E_7D1B_0080AD509054__INCLUDED_)