cbformats.cpp
上传用户:yatsl7111
上传日期:2007-01-08
资源大小:1433k
文件大小:15k
源码类别:

图形图象

开发平台:

Visual C++

  1. //*******************************************************************************
  2. // COPYRIGHT NOTES
  3. // ---------------
  4. // You may use this source code, compile or redistribute it as part of your application 
  5. // for free. You cannot redistribute it as a part of a software development 
  6. // library without the agreement of the author. If the sources are 
  7. // distributed along with the application, you should leave the original 
  8. // copyright notes in the source code without any changes.
  9. // This code can be used WITHOUT ANY WARRANTIES at your own risk.
  10. // 
  11. // For the latest updates to this code, check this site:
  12. // http://www.masmex.com 
  13. // after Sept 2000
  14. // 
  15. // Copyright(C) 2000 Philip Oldaker <email: philip@masmex.com>
  16. //*******************************************************************************
  17. #include "stdafx.h"
  18. #include "cbformats.h"
  19. #include "shlobj.h"
  20. #include "ShellPidl.h"
  21. #include <afxpriv.h>
  22. #ifdef _DEBUG
  23. #define new DEBUG_NEW
  24. #undef THIS_FILE
  25. static char THIS_FILE[] = __FILE__;
  26. #endif
  27. //static
  28. CWDClipboardData *CWDClipboardData::Instance()
  29. {
  30. static CWDClipboardData data;
  31. return &data;
  32. }
  33. CWDClipboardData::CWDClipboardData()
  34. {
  35. m_aFormatIDs[e_cfString] = CF_TEXT;
  36. m_aFormatIDs[e_cfHDROP] = CF_HDROP;
  37. m_aFormatIDs[e_cfWebSiteURL] = ::RegisterClipboardFormat(CFSTR_SHELLURL);
  38. #ifdef _UNICODE
  39. m_aFormatIDs[e_cfFileGroupDesc] = ::RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW);
  40. #else
  41. m_aFormatIDs[e_cfFileGroupDesc] = ::RegisterClipboardFormat(CFSTR_FILEDESCRIPTORA);
  42. #endif
  43. m_aFormatIDs[e_cfHTMLFormat] = ::RegisterClipboardFormat(_T("HTML Format"));
  44. m_aFormatIDs[e_cfWebSite] = ::RegisterClipboardFormat(_T("CF_WD_WEBSITE"));
  45. m_aFormatIDs[e_cfRightMenu] = ::RegisterClipboardFormat(_T("CF_WD_RIGHTMENU"));
  46. m_aFormatIDs[e_cfFolder] = ::RegisterClipboardFormat(_T("CF_WD_WEBSITE_CATEGORY"));
  47. m_aFormatIDs[e_cfShellIDList] = ::RegisterClipboardFormat(CFSTR_SHELLIDLIST);
  48. }
  49. CWDClipboardData::~CWDClipboardData()
  50. {
  51. }
  52. bool CWDClipboardData::IsValidFormat(CLIPFORMAT cfFormat)
  53. {
  54. for(int i=0;i < e_cfMax;i++)
  55. {
  56. if (m_aFormatIDs[i] == cfFormat)
  57. break;
  58. }
  59. return(i != e_cfMax);
  60. }
  61. bool CWDClipboardData::IsDataAvailable(COleDataObject *pDataObject)
  62. {
  63. // Iterate through the clipboard formats
  64. pDataObject->BeginEnumFormats();
  65. FORMATETC FormatEtc;
  66. bool bFound=false;
  67. #ifdef _DEBUG
  68. TCHAR szBuf[128];
  69. #endif
  70. while (pDataObject->GetNextFormat(&FormatEtc))
  71. {
  72. #ifdef _DEBUG
  73. szBuf[0] = 0;
  74. if (FormatEtc.cfFormat > CF_MAX)
  75. {
  76. ::GetClipboardFormatName(FormatEtc.cfFormat,szBuf,sizeof(szBuf)-1);
  77. }
  78. else
  79. {
  80. lstrcpy(szBuf,_T("Predefined Format"));
  81. }
  82. TRACE(_T("Enum formats returned %u(%s) %dn"),FormatEtc.cfFormat,szBuf,FormatEtc.tymed);
  83. #endif
  84. if (IsValidFormat(FormatEtc.cfFormat))
  85. {
  86. #ifdef _DEBUG
  87. TRACE(_T("Clipboard format found %u(%s) tymed(%d), Aspect(%d)n"),FormatEtc.cfFormat,szBuf,FormatEtc.tymed,FormatEtc.dwAspect);
  88. #endif
  89. bFound=true;
  90. }
  91. }
  92. return bFound;
  93. }
  94. CLIPFORMAT CWDClipboardData::GetClipboardFormat(eCBFormats format)
  95. {
  96. return m_aFormatIDs[format]; 
  97. }
  98. void CWDClipboardData::SetData(COleDataSource *pOleDataSource,CObject *pObj,eCBFormats format,LPFORMATETC lpFormatEtc)
  99. {
  100. ASSERT(pOleDataSource);
  101. ASSERT(pObj);
  102. // use serialization
  103. CSharedFile file;
  104. CArchive ar(&file,CArchive::store);
  105. pObj->Serialize(ar);
  106. ar.Close();
  107. // cache into drag drop source
  108. pOleDataSource->CacheGlobalData(CWDClipboardData::Instance()->GetClipboardFormat(format),file.Detach(),lpFormatEtc);
  109. }
  110. bool CWDClipboardData::GetData(COleDataObject *pDataObject,CObject *pObj,eCBFormats format)
  111. {
  112. ASSERT(pDataObject);
  113. ASSERT(pObj);
  114. if (pDataObject == NULL || pObj == NULL)
  115. return false;
  116. if (m_aFormatIDs[format] == CF_HDROP)
  117. {
  118. FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  119. STGMEDIUM medium;
  120. if (pDataObject->GetData(CF_HDROP, &medium, &fmte))
  121. {
  122. HDROP hDropInfo = (HDROP)medium.hGlobal;
  123. UINT wNumFilesDropped = DragQueryFile(hDropInfo, 0XFFFFFFFF, NULL, 0);
  124. TCHAR szFile[MAX_PATH];
  125. ASSERT_KINDOF(CCF_HDROP,pObj);
  126. CCF_HDROP *pHDROP = (CCF_HDROP*)pObj;
  127. UINT nLen;
  128. for(UINT i=0; i < wNumFilesDropped;i++)
  129. {
  130. nLen = DragQueryFile(hDropInfo,i,szFile,sizeof(szFile)/sizeof(TCHAR));
  131. if (nLen)
  132. {
  133. pHDROP->AddFileName(szFile);
  134. }
  135. }
  136. if (medium.pUnkForRelease)
  137. medium.pUnkForRelease->Release();
  138. else
  139. GlobalFree(medium.hGlobal);
  140. }
  141. }
  142. else
  143. {
  144. CFile *pFile = pDataObject->GetFileData(CWDClipboardData::Instance()->GetClipboardFormat(format));
  145. if (pFile)
  146. {
  147. CArchive ar(pFile,CArchive::load);
  148. pObj->Serialize(ar);
  149. ar.Close();
  150. delete pFile;
  151. }
  152. }
  153. return true;
  154. }
  155. ///////////////////////////////////////////
  156. //
  157. // Clipboard objects
  158. //
  159. ///////////////////////////////////////////
  160. IMPLEMENT_SERIAL(CCF_App, CObject, 0 );
  161. IMPLEMENT_SERIAL(CCF_WebSites,CObject,0);
  162. IMPLEMENT_SERIAL(CCF_String, CObject, 0 );
  163. IMPLEMENT_SERIAL(CCF_WebSite, CObject, 0 );
  164. IMPLEMENT_SERIAL(CCF_FolderType, CObject, 0 );
  165. IMPLEMENT_SERIAL(CCF_DBFolderList,CObject,0);
  166. IMPLEMENT_SERIAL(CCF_RightMenu, CObject, 0 );
  167. IMPLEMENT_SERIAL(CCF_FileGroupDescriptor,CObject,0);
  168. IMPLEMENT_SERIAL(CCF_ShellIDList,CObject,0);
  169. IMPLEMENT_SERIAL(CCF_HDROP,CObject,0);
  170. ///////////////////////////////////////////
  171. bool CCF_RightMenu::IsRightDrag()
  172. {
  173. return m_bRightDrag;
  174. }
  175. void CCF_RightMenu::SetRightDrag(bool bRightDrag)
  176. {
  177. m_bRightDrag = bRightDrag;
  178. }
  179. void CCF_RightMenu::Serialize(CArchive &ar)
  180. {
  181. if (ar.IsLoading())
  182. {
  183. int nRightDrag;
  184. ar >> nRightDrag;
  185. m_bRightDrag = nRightDrag == 1;
  186. }
  187. else
  188. {
  189. ar << m_bRightDrag;
  190. }
  191. }
  192. CCF_FileGroupDescriptor::CCF_FileGroupDescriptor() 
  193. {
  194. m_pFileDescrs = NULL;
  195. m_nItems = 0;
  196. }
  197. CCF_FileGroupDescriptor::~CCF_FileGroupDescriptor()
  198. {
  199. delete []m_pFileDescrs;
  200. }
  201. LPFILEDESCRIPTOR CCF_FileGroupDescriptor::GetFileDescriptor(UINT nItem)
  202. {
  203. if (m_pFileDescrs == NULL)
  204. return NULL;
  205. if (nItem >= m_nItems)
  206. {
  207. ASSERT(FALSE);
  208. return NULL;
  209. }
  210. return &m_pFileDescrs[nItem];
  211. }
  212. void CCF_FileGroupDescriptor::SetTitle(const CString &sTitle)
  213. {
  214. m_sTitle = sTitle;
  215. }
  216. CString CCF_FileGroupDescriptor::GetFileName(UINT nItem)
  217. {
  218. if (nItem >= m_nItems || m_pFileDescrs == NULL)
  219. {
  220. ASSERT(FALSE);
  221. return CString();
  222. }
  223. return m_pFileDescrs[nItem].cFileName;
  224. }
  225. CString CCF_FileGroupDescriptor::GetTitle(UINT nItem)
  226. {
  227. if (nItem >= m_nItems || m_pFileDescrs == NULL)
  228. {
  229. ASSERT(FALSE);
  230. return CString();
  231. }
  232. CString strLink(m_pFileDescrs[nItem].cFileName);
  233. int nPos = strLink.Find(_T(".URL"));
  234. if (nPos < 0)
  235. nPos = strLink.Find(_T(".url"));
  236. if (nPos > 0)
  237. {
  238. return strLink.Left(nPos);
  239. }
  240. return strLink;
  241. }
  242. void CCF_FileGroupDescriptor::Serialize(CArchive &ar)
  243. {
  244. if (ar.IsLoading())
  245. {
  246. ar.Read(&m_nItems,sizeof(UINT));
  247. if (m_nItems)
  248. {
  249. m_pFileDescrs = new FILEDESCRIPTOR[m_nItems];
  250. ar.Read(m_pFileDescrs,sizeof(FILEDESCRIPTOR)*m_nItems);
  251. for(UINT i=0;i < m_nItems;i++)
  252. TRACE3("(%u) - cFileName %s, Size=%un",i,m_pFileDescrs[i].cFileName,m_pFileDescrs[i].nFileSizeLow);
  253. }
  254. }
  255. else
  256. {
  257. UINT cItems=1;
  258. ar.Write(&cItems,sizeof(UINT));
  259. FILEDESCRIPTOR FileDesc;
  260. ZeroMemory(&FileDesc,sizeof(FILEDESCRIPTOR));
  261. FileDesc.dwFlags = (FD_LINKUI | FD_FILESIZE);
  262. if (!m_sTitle.IsEmpty())
  263. {
  264. lstrcpy(FileDesc.cFileName,m_sTitle);
  265. lstrcat(FileDesc.cFileName,_T(".url"));
  266. FileDesc.nFileSizeLow = lstrlen(FileDesc.cFileName)+24;
  267. ar.Write(&FileDesc,sizeof(FILEDESCRIPTOR));
  268. }
  269. }
  270. }
  271. ////////////////////////////////////////////////
  272. // CCF_HDROP
  273. ////////////////////////////////////////////////
  274. CCF_HDROP::CCF_HDROP() 
  275. {
  276. m_nFiles = 0;
  277. m_fNC = FALSE;
  278. }
  279. CCF_HDROP::~CCF_HDROP()
  280. {
  281. }
  282. CString CCF_HDROP::GetFileName(UINT nItem)
  283. {
  284. if (m_sFileNames.GetSize() > 0)
  285. return m_sFileNames[nItem];
  286. return _T("");
  287. }
  288. void CCF_HDROP::AddDropPoint(CPoint &pt,BOOL fNC)
  289. {
  290. m_pt = pt;
  291. m_fNC = fNC;
  292. }
  293. void CCF_HDROP::AddFileName(LPCTSTR pszFileName)
  294. {
  295. m_sFileNames.SetAtGrow(m_nFiles++,pszFileName);
  296. }
  297. void CCF_HDROP::Serialize(CArchive &ar)
  298. {
  299. if (ar.IsLoading())
  300. {
  301. // handled in GetData
  302. }
  303. else
  304. {
  305. DROPFILES dropfiles;
  306. dropfiles.pFiles = sizeof(dropfiles);
  307. dropfiles.fNC = m_fNC;
  308. dropfiles.pt = m_pt;
  309. #ifdef _UNICODE
  310. dropfiles.fWide = TRUE;
  311. #else
  312. dropfiles.fWide = FALSE;
  313. #endif
  314. ar.Write(&dropfiles,sizeof(DROPFILES));
  315. LPCTSTR pszFileName=NULL;
  316. for(int i=0; i < m_nFiles;i++)
  317. {
  318. pszFileName=m_sFileNames[i];
  319. ar.Write(pszFileName,lstrlen(pszFileName)+sizeof(TCHAR));
  320. }
  321. TCHAR rchar=0;
  322. ar.Write(&rchar,sizeof(TCHAR));
  323. }
  324. }
  325. ////////////////////////////////////////////////
  326. // CCF_ShellIDList
  327. ////////////////////////////////////////////////
  328. CCF_ShellIDList::CCF_ShellIDList() 
  329. {
  330. }
  331. CCF_ShellIDList::~CCF_ShellIDList()
  332. {
  333. }
  334. LPCITEMIDLIST CCF_ShellIDList::operator[](UINT nIndex) const
  335. {
  336. return GetPidl(nIndex);
  337. }
  338. LPCITEMIDLIST CCF_ShellIDList::GetPidl(UINT nIndex) const
  339. {
  340. if (nIndex > (UINT)m_pidls.GetSize()) 
  341. return NULL; 
  342. return(m_pidls[nIndex]); 
  343. }
  344. UINT CCF_ShellIDList::GetCount() const
  345. {
  346. return m_pidls.GetSize();  
  347. }
  348. void CCF_ShellIDList::AddPidl(LPCITEMIDLIST pidl)
  349. {
  350. m_pidls.Add(pidl);
  351. }
  352. void CCF_ShellIDList::Serialize(CArchive &ar)
  353. {
  354. if (ar.IsLoading())
  355. {
  356. // read the header
  357. CIDA cida;
  358. ar.Read(&cida,sizeof(CIDA));
  359. LPCITEMIDLIST pidl=NULL;
  360. UINT nOffset;
  361. // read the ITEMIDLIST structures
  362. for(UINT i=0;i < cida.cidl+1;i++)
  363. {
  364. nOffset = cida.aoffset[i];
  365. ar.GetFile()->Seek(CFile::begin,nOffset*sizeof(UINT));
  366. ar.Read((void*)pidl,sizeof(ITEMIDLIST));
  367. m_pidls.Add(pidl);
  368. }
  369. }
  370. else
  371. {
  372. CShellPidl ShellPidl;
  373. CIDA cida;
  374. cida.cidl = m_pidls.GetSize();
  375. ASSERT(cida.cidl > 1);
  376. if (cida.cidl <= 1)
  377. return;
  378. UINT pidls=cida.cidl-1;
  379. ar.Write(&pidls,sizeof(pidls));
  380. const UINT nOffset=sizeof(UINT);
  381. UINT nElemOffset;
  382. UINT nPidlSize=0;
  383. for(UINT i1=0;i1 < cida.cidl;i1++)
  384. {
  385. nElemOffset = sizeof(cida.cidl)+(cida.cidl*sizeof(nElemOffset))+nOffset+nPidlSize;
  386. ar.Write(&nElemOffset,sizeof(nElemOffset));
  387. nPidlSize += ShellPidl.GetSize(m_pidls[i1]);
  388. }
  389. BYTE nZero=0;
  390. for(int i=0;i < nOffset;i++)
  391. ar.Write(&nZero,sizeof(nZero));
  392. TRACE1("Writing %u pidlsn",cida.cidl);
  393. LPSHELLFOLDER pFolder=ShellPidl.GetFolder((LPITEMIDLIST)m_pidls[0]);
  394. for(UINT i2=0;i2 < cida.cidl;i2++)
  395. {
  396. #ifdef _DEBUG
  397. CString sPath;
  398. ShellPidl.SHPidlToPathEx((LPITEMIDLIST)m_pidls[i2],sPath,pFolder);
  399. TRACE3("Writing pidl %s (%u) size(%u)n",sPath,i2,ShellPidl.GetSize(m_pidls[i2]));
  400. #endif
  401. ar.Write(m_pidls[i2],ShellPidl.GetSize(m_pidls[i2]));
  402. }
  403. if (pFolder)
  404. pFolder->Release();
  405. }
  406. }
  407. ///////////////////////////////////////////////////////////////////
  408. // Private clipboard formats for drag and drop
  409. ///////////////////////////////////////////////////////////////////
  410. const CCF_WebSite &CCF_WebSite::operator=(const CCF_WebSite &rThat)
  411. {
  412. if (this != &rThat)
  413. {
  414. m_strURL = rThat.m_strURL;
  415. m_strTitle = rThat.m_strTitle;
  416. }
  417. return *this;
  418. }
  419. CCF_WebSite::CCF_WebSite(const CCF_WebSite &WebSite)
  420. {
  421. *this = WebSite;
  422. }
  423. ////////////////////////////////////////////
  424. void CCF_App::Serialize(CArchive &ar)
  425. {
  426. if (ar.IsLoading())
  427. {
  428. long hWnd;
  429. ar >> hWnd;
  430. m_hWnd = (HWND)hWnd;
  431. }
  432. else
  433. {
  434. ar << (long)m_hWnd;
  435. }
  436. }
  437. /////////////////////////////////////////
  438. void CCF_WebSites::Serialize(CArchive &ar)
  439. {
  440. m_App.Serialize(ar);
  441. m_listWebSites.Serialize(ar);
  442. }
  443. /////////////////////////////////////////
  444. CCF_String::CCF_String(LPCTSTR pszText) : m_sText(pszText) 
  445. {
  446. }
  447. CCF_String::~CCF_String()
  448. {
  449. }
  450. LPCTSTR CCF_String::GetString()
  451. {
  452. return m_sText;
  453. }
  454. void CCF_String::SetString(LPCTSTR pszText)
  455. {
  456. m_sText = pszText;
  457. }
  458. void CCF_String::Serialize(CArchive &ar)
  459. {
  460. if (ar.IsLoading())
  461. {
  462. TCHAR szText[MAX_PATH+1];
  463. m_sText.Empty();
  464. while (1)
  465. {
  466. ZeroMemory(szText,sizeof(szText));
  467. ar.Read(szText,MAX_PATH);
  468. m_sText += szText;
  469. if (lstrlen(szText) < MAX_PATH)
  470. break;
  471. }
  472. }
  473. else
  474. {
  475. ar.Write((LPCTSTR)m_sText, m_sText.GetLength()*sizeof(TCHAR));
  476. int null=0;
  477. ar.Write(&null,sizeof(null));
  478. }
  479. }
  480. //
  481. // Private clipboard formats for drag and drop
  482. //
  483. CCF_WebSite::CCF_WebSite(LPCTSTR pszURL,LPCTSTR pszTitle) : 
  484. m_strURL(pszURL),
  485. m_strTitle(pszTitle)
  486. {
  487. }
  488. CCF_WebSite::~CCF_WebSite()
  489. {
  490. }
  491. void CCF_WebSite::Serialize(CArchive &ar)
  492. {
  493. if (ar.IsLoading())
  494. {
  495. ar >> m_strURL;
  496. ar >> m_strTitle;
  497. }
  498. else
  499. {
  500. ar << m_strURL;
  501. ar << m_strTitle;
  502. }
  503. }
  504. //
  505. //////////////////////////////////////////////////////
  506. CCF_FolderType::CCF_FolderType(LPCTSTR pszParentCategory,long nCategory,LPCTSTR pszCategory) :
  507. m_strParentCategory(pszParentCategory),
  508. m_nCategory(nCategory),
  509. m_strCategory(pszCategory)
  510. {
  511. }
  512. CCF_FolderType::~CCF_FolderType()
  513. {
  514. }
  515. const CCF_FolderType &CCF_FolderType::operator=(const CCF_FolderType &rThat)
  516. {
  517. if (this != &rThat)
  518. {
  519. m_nCategory = rThat.m_nCategory;
  520. m_strCategory = rThat.m_strCategory;
  521. m_strParentCategory = rThat.m_strParentCategory;
  522. }
  523. return *this;
  524. }
  525. CCF_FolderType::CCF_FolderType(const CCF_FolderType &WebSiteCategory)
  526. {
  527. *this = WebSiteCategory;
  528. }
  529. void CCF_FolderType::Serialize(CArchive &ar)
  530. {
  531. if (ar.IsLoading())
  532. {
  533. ar >> m_nCategory;
  534. ar >> m_strCategory;
  535. ar >> m_strParentCategory;
  536. }
  537. else
  538. {
  539. ar << m_nCategory;
  540. ar << m_strCategory;
  541. ar << m_strParentCategory;
  542. }
  543. }
  544. /////////////////////////////////////////////////
  545. void CCF_DBFolderList::Serialize(CArchive &ar)
  546. {
  547. m_App.Serialize(ar);
  548. if (ar.IsLoading())
  549. {
  550. ar >> m_strDatabase;
  551. }
  552. else
  553. {
  554. ar << m_strDatabase;
  555. }
  556. CList<CCF_FolderType,CCF_FolderType&>::Serialize(ar);
  557. }
  558. template <> void AFXAPI SerializeElements <CCF_FolderType>(CArchive& ar, CCF_FolderType *pWebSite, int nCount )
  559. {
  560.     for ( int i = 0; i < nCount; i++, pWebSite++ )
  561.     {
  562. pWebSite->Serialize(ar);
  563. }
  564. }
  565. template<> void AFXAPI DestructElements<CCF_FolderType> (CCF_FolderType *pElements, int nCount)
  566. {
  567. for ( int n = 0; n < nCount; n++, pElements++ )
  568. {
  569. pElements->CCF_FolderType::~CCF_FolderType();
  570. }
  571. }
  572. template<> void AFXAPI ConstructElements<CCF_FolderType> (CCF_FolderType *pElements, int nCount)
  573. {
  574. for ( int n = 0; n < nCount; n++, pElements++ )
  575. {
  576. pElements->CCF_FolderType::CCF_FolderType();
  577. }
  578. }
  579. ///////////////////////////////////////////////////
  580. template <> void AFXAPI SerializeElements <CCF_WebSite>(CArchive& ar, CCF_WebSite *pWebSite, int nCount )
  581. {
  582.     for ( int i = 0; i < nCount; i++, pWebSite++ )
  583.     {
  584. pWebSite->Serialize(ar);
  585. }
  586. }
  587. template<> void AFXAPI DestructElements<CCF_WebSite> (CCF_WebSite *pElements, int nCount)
  588. {
  589. for ( int n = 0; n < nCount; n++, pElements++ )
  590. {
  591. pElements->CCF_WebSite::~CCF_WebSite();
  592. }
  593. }
  594. template<> void AFXAPI ConstructElements<CCF_WebSite> (CCF_WebSite *pElements, int nCount)
  595. {
  596. for ( int n = 0; n < nCount; n++, pElements++ )
  597. {
  598. pElements->CCF_WebSite::CCF_WebSite();
  599. }
  600. }