Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

207 lines
4.6 KiB

  1. //*******************************************************************************************
  2. //
  3. // Filename : XIcon.cpp
  4. //
  5. // Implementation file for CIconTemp and CXIcon
  6. //
  7. // Copyright (c) 1994 - 1996 Microsoft Corporation. All rights reserved
  8. //
  9. //*******************************************************************************************
  10. #include "Pch.H"
  11. #include "ThisDll.H"
  12. #include "Unknown.H"
  13. #include "XIcon.H"
  14. class CIconTemp : public CObjTemp
  15. {
  16. public:
  17. CIconTemp() : CObjTemp() {}
  18. CIconTemp(HICON hi) : CObjTemp() {Attach(hi);}
  19. ~CIconTemp() {if (m_hObj) DestroyIcon(Detach());}
  20. operator HICON() const {return((HICON)m_hObj);}
  21. HICON Attach(HICON hObjNew) {return((HICON)CObjTemp::Attach((HANDLE)hObjNew));}
  22. HICON Detach() {return((HICON)CObjTemp::Detach());}
  23. } ;
  24. BOOL CXIcon::Init(HWND hwndLB, UINT idiDef)
  25. {
  26. m_hwndLB = hwndLB;
  27. m_cimlLg.Create(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 8);
  28. m_cimlSm.Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 8);
  29. HICON hIcon = LoadIcon(g_ThisDll.GetInstance(), MAKEINTRESOURCE(idiDef));
  30. return(m_cimlLg && m_cimlSm && AddIcon(hIcon)>=0);
  31. }
  32. UINT CXIcon::GetIDString(LPTSTR pszIDString, UINT uIDLen,
  33. LPCTSTR szIconFile, int iIndex, UINT wFlags)
  34. {
  35. static const TCHAR szIDFmt[] = TEXT("\"%s\" %d %08x");
  36. TCHAR szIDString[MAX_PATH + 2*ARRAYSIZE(szIDFmt)];
  37. int iRet = wsprintf(szIDString, szIDFmt, szIconFile, iIndex, wFlags);
  38. lstrcpyn(pszIDString, szIDString, uIDLen);
  39. return(iRet + 1);
  40. }
  41. int CXIcon::GetCachedIndex(LPCTSTR szIconFile, int iIndex, UINT wFlags)
  42. {
  43. TCHAR szIDString[MAX_PATH*2];
  44. GetIDString(szIDString, ARRAYSIZE(szIDString), szIconFile, iIndex, wFlags);
  45. int iLB = ListBox_FindStringExact(m_hwndLB, -1, szIDString);
  46. if (iLB < 0)
  47. {
  48. return(-1);
  49. }
  50. return (int)((INT_PTR)ListBox_GetItemData(m_hwndLB, iLB));
  51. }
  52. int CXIcon::CacheIcons(HICON hiLarge, HICON hiSmall,
  53. LPCTSTR szIconFile, int iIndex, UINT wFlags)
  54. {
  55. CIconTemp ciLarge(hiLarge);
  56. CIconTemp ciSmall(hiSmall);
  57. if (!hiLarge || !hiSmall)
  58. {
  59. return(-1);
  60. }
  61. TCHAR szIDString[MAX_PATH*2];
  62. GetIDString(szIDString, ARRAYSIZE(szIDString), szIconFile, iIndex, wFlags);
  63. int iLB = ListBox_AddString(m_hwndLB, szIDString);
  64. if (iLB < 0)
  65. {
  66. return(-1);
  67. }
  68. int iLarge = AddIcon(ciLarge, AI_LARGE);
  69. if (iLarge >= 0)
  70. {
  71. int iSmall = AddIcon(ciSmall, AI_SMALL);
  72. if (iSmall >= 0)
  73. {
  74. if (iLarge == iSmall)
  75. {
  76. // Should always happen;
  77. ListBox_SetItemData(m_hwndLB, iLB, iLarge);
  78. return(iLarge);
  79. }
  80. ImageList_Remove(m_cimlSm, iSmall);
  81. }
  82. ImageList_Remove(m_cimlLg, iLarge);
  83. }
  84. ListBox_DeleteString(m_hwndLB, iLB);
  85. return(-1);
  86. }
  87. HRESULT CXIcon::ExtractIcon(LPCTSTR szIconFile, int iIndex, UINT wFlags,
  88. HICON *phiconLarge, HICON *phiconSmall, DWORD dwSizes)
  89. {
  90. return(E_NOTIMPL);
  91. }
  92. int CXIcon::GetIcon(IShellFolder *psf, LPCITEMIDLIST pidl)
  93. {
  94. int iImage = -1;
  95. IExtractIcon *pxi;
  96. HRESULT hres = psf->GetUIObjectOf(NULL, 1, &pidl, IID_IExtractIcon, NULL, (LPVOID *)&pxi);
  97. if (FAILED(hres))
  98. {
  99. return(0);
  100. }
  101. CEnsureRelease erExtractIcon(pxi);
  102. TCHAR szIconFile[MAX_PATH];
  103. int iIndex;
  104. UINT wFlags = 0;
  105. hres = pxi->GetIconLocation(GIL_FORSHELL,
  106. szIconFile, ARRAYSIZE(szIconFile), &iIndex, &wFlags);
  107. if (FAILED(hres))
  108. {
  109. return(0);
  110. }
  111. //
  112. // if GIL_DONTCACHE was returned by the icon handler, dont
  113. // lookup the previous icon, assume a cache miss.
  114. //
  115. if (!(wFlags & GIL_DONTCACHE))
  116. {
  117. iImage = GetCachedIndex(szIconFile, iIndex, wFlags);
  118. }
  119. // if we miss our cache...
  120. if (iImage == -1)
  121. {
  122. HICON hiconLarge = NULL;
  123. HICON hiconSmall = NULL;
  124. int cxIcon = GetSystemMetrics(SM_CXICON);
  125. int cxSmIcon = GetSystemMetrics(SM_CXSMICON);
  126. // try getting it from the Extract member fuction
  127. hres = pxi->Extract(szIconFile, iIndex, &hiconLarge, &hiconSmall,
  128. MAKELONG(cxIcon, cxSmIcon));
  129. // S_FALSE means can you please do it
  130. if (hres == S_FALSE)
  131. {
  132. hres = ExtractIcon(szIconFile, iIndex, wFlags,
  133. &hiconLarge, &hiconSmall, MAKELONG(cxIcon, cxSmIcon));
  134. }
  135. if (SUCCEEDED(hres))
  136. {
  137. // Let CacheIcons check and destroy the hicon's
  138. iImage = CacheIcons(hiconLarge, hiconSmall, szIconFile, iIndex, wFlags);
  139. }
  140. // if we failed in any way pick a default icon
  141. if (iImage == -1)
  142. {
  143. if (wFlags & GIL_SIMULATEDOC)
  144. {
  145. iImage = 0; // II_DOCUMENT;
  146. }
  147. else if ((wFlags & GIL_PERINSTANCE) && PathIsExe(szIconFile))
  148. {
  149. iImage = 0; // II_APPLICATION;
  150. }
  151. else
  152. {
  153. iImage = 0; // II_DOCNOASSOC;
  154. }
  155. }
  156. }
  157. if (iImage < 0)
  158. {
  159. iImage = 0; // II_DOCNOASSOC;
  160. }
  161. return(iImage);
  162. }