ControlFavorites.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:11k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // ControlFavorites.cpp: implementation of the CControlFavorites class.
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "resource.h"
  22. #include "ControlFavorites.h"
  23. #ifdef _DEBUG
  24. #undef THIS_FILE
  25. static char THIS_FILE[]=__FILE__;
  26. #define new DEBUG_NEW
  27. #endif
  28. IMPLEMENT_XTP_CONTROL(CControlFavorites, CXTPControlButton)
  29. CControlFavorites::CControlFavorites(LPCTSTR strRootDir)
  30. {
  31. m_strRootDir = strRootDir;
  32. }
  33. void CControlFavorites::Copy(CXTPControl* pControl, BOOL bRecursive)
  34. {
  35. ASSERT(DYNAMIC_DOWNCAST(CControlFavorites, pControl));
  36. CXTPControlButton::Copy(pControl, bRecursive);
  37. m_strRootDir = ((CControlFavorites*)pControl)->m_strRootDir;
  38. }
  39. void CControlFavorites::DoPropExchange(CXTPPropExchange* pPX)
  40. {
  41. CXTPControlButton::DoPropExchange(pPX);
  42. PX_String(pPX, _T("RootDir"), m_strRootDir);
  43. }
  44. void CControlFavorites::OnCalcDynamicSize(DWORD /*dwMode*/)
  45. {
  46. if (GetParent()->GetType() !=xtpBarTypePopup)
  47. return;
  48. ASSERT(m_pControls->GetAt(m_nIndex) == this);
  49. while (m_nIndex + 1 < m_pControls->GetCount())
  50. {
  51. CXTPControl* pControl = m_pControls->GetAt(m_nIndex + 1);
  52. if (
  53. pControl->GetID() == ID_FAVORITE_LINK ||
  54. pControl->GetID() == ID_FAVORITE_FOLDER)
  55. {
  56. m_pControls->Remove(pControl);
  57. }
  58. else break;
  59. }
  60. if (m_pParent->IsCustomizeMode())
  61. {
  62. m_dwHideFlags = 0;
  63. return;
  64. }
  65. m_dwHideFlags |= xtpHideGeneric;
  66. //CString         strPath2;
  67. CString         str;
  68. WIN32_FIND_DATA wfd;
  69. HANDLE          h;
  70. int             nPos = 0;
  71. int             nEndPos = 0;
  72. #define INTERNET_MAX_PATH_LENGTH 2048
  73. TCHAR           buf[INTERNET_MAX_PATH_LENGTH];
  74. CStringArray    astrFavorites;
  75. CStringArray    astrFavoritesUrl;
  76. CStringArray    astrDirs;
  77. // make sure there's a trailing backslash
  78. if(m_strRootDir[m_strRootDir.GetLength() - 1] != _T('\'))
  79. m_strRootDir += _T('\');
  80. int nStartPos = m_nIndex + 1;
  81. // now scan the directory, first for .URL files and then for subdirectories
  82. // that may also contain .URL files
  83. h = FindFirstFile(m_strRootDir + _T("*.*"), &wfd);
  84. if(h != INVALID_HANDLE_VALUE)
  85. {
  86. nEndPos = nStartPos;
  87. do
  88. {
  89. if((wfd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))==0)
  90. {
  91. str = wfd.cFileName;
  92. if(str.Right(4).CompareNoCase(_T(".url")) == 0)
  93. {
  94. // an .URL file is formatted just like an .INI file, so we can
  95. // use GetPrivateProfileString() to get the information we want
  96. ::GetPrivateProfileString(_T("InternetShortcut"), _T("URL"),
  97. _T(""), buf, INTERNET_MAX_PATH_LENGTH,
  98. m_strRootDir + str);
  99. str = str.Left(str.GetLength() - 4);
  100. // scan through the array and perform an insertion sort
  101. // to make sure the menu ends up in alphabetic order
  102. for(nPos = nStartPos ; nPos < nEndPos ; ++nPos)
  103. {
  104. if(str.CompareNoCase(astrFavorites[nPos]) < 0)
  105. break;
  106. }
  107. astrFavorites.InsertAt(nPos, str);
  108. astrFavoritesUrl.InsertAt(nPos, buf);
  109. ++nEndPos;
  110. }
  111. }
  112. } while(FindNextFile(h, &wfd));
  113. FindClose(h);
  114. // Now add these items to the menu
  115. for(nPos = nStartPos ; nPos < nEndPos ; ++nPos)
  116. {
  117. CXTPControlButton* pControl = (CXTPControlButton*)m_pControls->Add(xtpControlButton, ID_FAVORITE_LINK, astrFavoritesUrl[nPos], nPos, TRUE);
  118. pControl->SetCaption(astrFavorites[nPos]);
  119. pControl->SetTooltip(astrFavorites[nPos]);
  120. pControl->SetFlags(xtpFlagManualUpdate);
  121. pControl->SetStyle(xtpButtonIconAndCaption);
  122. }
  123. // now that we've got all the .URL files, check the subdirectories for more
  124. int nLastDir = 0;
  125. h = FindFirstFile(m_strRootDir + _T("*.*"), &wfd);
  126. ASSERT(h != INVALID_HANDLE_VALUE);
  127. do
  128. {
  129. if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  130. {
  131. // ignore the current and parent directory entries
  132. if(lstrcmp(wfd.cFileName, _T(".")) == 0 || lstrcmp(wfd.cFileName, _T("..")) == 0)
  133. continue;
  134. for(nPos = 0 ; nPos < nLastDir ; ++nPos)
  135. {
  136. if(astrDirs[nPos].CompareNoCase(wfd.cFileName) > 0)
  137. break;
  138. }
  139. CXTPControlPopup* pControl = (CXTPControlPopup*)m_pControls->Add(xtpControlButtonPopup, ID_FAVORITE_FOLDER, _T(""), nStartPos + nPos, TRUE);
  140. CXTPControls* pChildControls = pControl->GetCommandBar()->GetControls();
  141. pChildControls->Add(new CControlFavorites(m_strRootDir + wfd.cFileName), 0);
  142. pControl->SetCaption(wfd.cFileName);
  143. pControl->SetFlags(xtpFlagManualUpdate);
  144. astrDirs.InsertAt(nPos, wfd.cFileName);
  145. ++nLastDir;
  146. }
  147. } while(FindNextFile(h, &wfd));
  148. FindClose(h);
  149. }
  150. }
  151. BOOL CControlFavorites::IsCustomizeDragOverAvail(CXTPCommandBar* pCommandBar, CPoint /*point*/, DROPEFFECT& dropEffect)
  152. {
  153. if (pCommandBar->GetType() != xtpBarTypePopup)
  154. {
  155. dropEffect = DROPEFFECT_NONE;
  156. return FALSE;
  157. }
  158. return TRUE;
  159. }
  160. //////////////////////////////////////////////////////////////////////////
  161. // CControlShell
  162. CControlShellFile::CControlShellFile(XT_TVITEMDATA* lptvid)
  163. {
  164. m_lptvid = lptvid;
  165. }
  166. void CControlShellFile::OnExecute()
  167. {
  168. CXTPControl::OnExecute();
  169. SHELLEXECUTEINFO sei;
  170. ::ZeroMemory(&sei, sizeof(SHELLEXECUTEINFO));
  171. sei.cbSize = sizeof(SHELLEXECUTEINFO);
  172. sei.fMask = SEE_MASK_INVOKEIDLIST;
  173. sei.hwnd = AfxGetMainWnd()->m_hWnd;
  174. sei.nShow = SW_SHOWNORMAL;
  175. sei.hInstApp = AfxGetInstanceHandle();
  176. sei.lpIDList = GetFullyQualPidl(m_lptvid->lpsfParent, m_lptvid->lpi);
  177. ::ShellExecuteEx(&sei);
  178. }
  179. CControlShell::CControlShell()
  180. {
  181. m_lptvid = NULL;
  182. }
  183. CControlShell::CControlShell(XT_TVITEMDATA* lptvid)
  184. {
  185. m_lptvid = lptvid;
  186. }
  187. IMPLEMENT_XTP_CONTROL(CControlShell, CXTPControlButton)
  188. BOOL CControlShell::IsCustomizeDragOverAvail(CXTPCommandBar* pCommandBar, CPoint /*point*/, DROPEFFECT& dropEffect)
  189. {
  190. if (pCommandBar->GetType() != xtpBarTypePopup)
  191. {
  192. dropEffect = DROPEFFECT_NONE;
  193. return FALSE;
  194. }
  195. return TRUE;
  196. }
  197. void CControlShell::InitTreeViewItems(LPSHELLFOLDER lpsf, LPCITEMIDLIST lpifq, CArray<XT_TVITEMDATA*, XT_TVITEMDATA*>& items)
  198. {
  199. // Allocate a shell memory object.
  200. CShellMalloc lpMalloc;
  201. if (!lpMalloc)
  202. return;
  203. // Get the IEnumIDList object for the given folder.
  204. LPENUMIDLIST lpe = NULL;
  205. if (SUCCEEDED(lpsf->EnumObjects(AfxGetMainWnd()->GetSafeHwnd(), SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &lpe)))
  206. {
  207. ULONG        ulFetched = 0;
  208. LPITEMIDLIST lpi = NULL;
  209. // Enumerate through the list of folder and non-folder objects.
  210. while (lpe->Next(1, &lpi, &ulFetched) == S_OK)
  211. {
  212. // Allocate memory for ITEMDATA struct
  213. XT_TVITEMDATA* lptvid = (XT_TVITEMDATA*)lpMalloc.Alloc(sizeof(XT_TVITEMDATA));
  214. if (lptvid == NULL)
  215. {
  216. if (lpe) {
  217. lpe->Release();
  218. }
  219. if (lpi) {
  220. lpMalloc.Free(lpi);
  221. }
  222. return;
  223. }
  224. // Now, make a copy of the ITEMIDLIST and store the parent folders SF.
  225. lptvid->lpi = DuplicateItem(lpMalloc, lpi);
  226. lptvid->lpsfParent = lpsf;
  227. lptvid->lpifq = ConcatPidls(lpifq, lpi);
  228. lpsf->AddRef();
  229. items.Add(lptvid);
  230. // Free the pidl that the shell gave us.
  231. if (lpi) {
  232. lpMalloc.Free(lpi);
  233. lpi = 0;
  234. }
  235. }
  236. if (lpi) {
  237. lpMalloc.Free(lpi);
  238. }
  239. if (lpe) {
  240. lpe->Release();
  241. }
  242. }
  243. }
  244. int AFX_CDECL TreeViewCompareProc2(const void *lparam1, const void *lparam2)
  245. {
  246. XT_TVITEMDATA* lptvid1 = *(XT_TVITEMDATA**)lparam1;
  247. XT_TVITEMDATA* lptvid2 = *(XT_TVITEMDATA**)lparam2;
  248. HRESULT hr = lptvid1->lpsfParent->CompareIDs(0, lptvid1->lpi, lptvid2->lpi);
  249. if (FAILED(hr)) {
  250. return 0;
  251. }
  252. return (short)SCODE_CODE(GetScode(hr));
  253. }
  254. void CControlShell::OnCalcDynamicSize(DWORD /*dwMode*/)
  255. {
  256. if (GetParent()->GetType() != xtpBarTypePopup)
  257. return;
  258. ASSERT(m_pControls->GetAt(m_nIndex) == this);
  259. while (m_nIndex + 1 < m_pControls->GetCount())
  260. {
  261. CXTPControl* pControl = m_pControls->GetAt(m_nIndex + 1);
  262. if (pControl->GetID() == ID_CONTROL_SHELL)
  263. {
  264. m_pControls->Remove(pControl);
  265. }
  266. else break;
  267. }
  268. if (m_pParent->IsCustomizeMode())
  269. {
  270. m_dwHideFlags = 0;
  271. return;
  272. }
  273. m_dwHideFlags |= xtpHideGeneric;
  274. LPSHELLFOLDER lpsfDesktop = NULL;
  275. LPSHELLFOLDER lpsf = NULL;
  276. LPCITEMIDLIST lpifq = NULL;
  277. if (m_lptvid != NULL && m_lptvid->lpsfParent != NULL )
  278. {
  279. LPSHELLFOLDER _lpsf = NULL;
  280. if (SUCCEEDED(m_lptvid->lpsfParent->BindToObject(m_lptvid->lpi,
  281. 0, IID_IShellFolder, (LPVOID *)&_lpsf))) 
  282. {
  283. lpifq = m_lptvid->lpifq;
  284. lpsf = _lpsf;
  285. }
  286. }
  287. else
  288. {
  289. ::SHGetDesktopFolder( &lpsfDesktop); 
  290. lpsf = lpsfDesktop;
  291. }
  292. if (lpsf == NULL)
  293. return;
  294. CArray<XT_TVITEMDATA*, XT_TVITEMDATA*> items;
  295. InitTreeViewItems(lpsf, lpifq, items);
  296. qsort(items.GetData(), items.GetSize(), sizeof(XT_TVITEMDATA*), TreeViewCompareProc2);
  297. for (int nIndex = 0; nIndex < items.GetSize(); nIndex++)
  298. {
  299. XT_TVITEMDATA* lptvid = items[nIndex];
  300. CXTPControl* pControl = NULL;
  301. // Create a fully qualified path to the current item
  302. // the SH* shell api's take a fully qualified path pidl,
  303. // (see GetIcon above where I call SHGetFileInfo) whereas the
  304. // interface methods take a relative path pidl.
  305. ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_DISPLAYATTRMASK | SFGAO_REMOVABLE;
  306. // Determine what type of object we have.
  307. lpsf->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lptvid->lpi, &ulAttrs);
  308. if ((ulAttrs & SFGAO_FOLDER))
  309. {
  310. pControl = (CXTPControlPopup*)m_pControls->Add(xtpControlButtonPopup, ID_CONTROL_SHELL, _T(""), m_nIndex + nIndex + 1, TRUE);
  311. CXTPControls* pChildControls = pControl->GetCommandBar()->GetControls();
  312. pChildControls->Add(new CControlShell(lptvid), ID_CONTROL_SHELL, _T(""), 0, TRUE);
  313. }
  314. else
  315. {
  316. pControl = m_pControls->Add(new CControlShellFile(lptvid), ID_CONTROL_SHELL, _T(""), m_nIndex + nIndex + 1, TRUE);
  317. }
  318. CString strBuff;
  319. GetName(lpsf, lptvid->lpi, SHGDN_NORMAL, strBuff);
  320. pControl->SetCaption(strBuff);
  321. pControl->SetStyle(xtpButtonIconAndCaption);
  322. pControl->SetFlags(xtpFlagManualUpdate);
  323. pControl->SetIconId(GetItemIcon(lptvid->lpifq, 
  324. SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON) + ID_SHELLIMAGELIST_BASE);
  325. }
  326. if (lpsfDesktop)
  327. {
  328. lpsfDesktop->Release( );
  329. }
  330. }