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.

146 lines
4.1 KiB

  1. #include "shellprv.h"
  2. #pragma hdrstop
  3. #include "xiconwrap.h"
  4. // From cplobj.c
  5. EXTERN_C BOOL CPL_FindCPLInfo(LPTSTR pszCmdLine, HICON *phIcon, UINT *ppapl, LPTSTR *pparm);
  6. class CCtrlExtIconBase : public CExtractIconBase
  7. {
  8. public:
  9. HRESULT _GetIconLocationW(UINT uFlags, LPWSTR pszIconFile, UINT cchMax, int *piIndex, UINT *pwFlags);
  10. HRESULT _ExtractW(LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
  11. CCtrlExtIconBase(LPCWSTR pszSubObject);
  12. protected:
  13. ~CCtrlExtIconBase();
  14. private:
  15. TCHAR _szSubObject[MAX_PATH];
  16. HICON _hIcon;
  17. UINT _nControl;
  18. };
  19. CCtrlExtIconBase::CCtrlExtIconBase(LPCWSTR pszSubObject) : CExtractIconBase(), _hIcon(NULL), _nControl(-1)
  20. {
  21. lstrcpyn(_szSubObject, pszSubObject, ARRAYSIZE(_szSubObject));
  22. }
  23. CCtrlExtIconBase::~CCtrlExtIconBase()
  24. {
  25. if (_hIcon)
  26. DestroyIcon(_hIcon);
  27. }
  28. STDAPI ControlExtractIcon_CreateInstance(LPCTSTR pszSubObject, REFIID riid, void** ppv)
  29. {
  30. HRESULT hr;
  31. CCtrlExtIconBase* pceib = new CCtrlExtIconBase(pszSubObject);
  32. if (pceib)
  33. {
  34. hr = pceib->QueryInterface(riid, ppv);
  35. pceib->Release();
  36. }
  37. else
  38. {
  39. hr = E_OUTOFMEMORY;
  40. }
  41. return hr;
  42. }
  43. HRESULT CCtrlExtIconBase::_GetIconLocationW(UINT uFlags, LPWSTR pszIconFile,
  44. UINT cchMax, int *piIndex, UINT *pwFlags)
  45. {
  46. HRESULT hr = S_FALSE;
  47. if (!(uFlags & GIL_OPENICON))
  48. {
  49. lstrcpyn(pszIconFile, _szSubObject, cchMax);
  50. LPTSTR pszComma = StrChr(pszIconFile, TEXT(','));
  51. if (pszComma)
  52. {
  53. *pszComma ++= 0;
  54. *piIndex = StrToInt(pszComma);
  55. *pwFlags = GIL_PERINSTANCE;
  56. //
  57. // normally the index will be negative (a resource id)
  58. // check for some special cases like dynamic icons and bogus ids
  59. //
  60. if (*piIndex == 0)
  61. {
  62. LPTSTR lpExtraParms = NULL;
  63. // this is a dynamic applet icon
  64. *pwFlags |= GIL_DONTCACHE | GIL_NOTFILENAME;
  65. // use the applet index in case there's more than one
  66. if ((_hIcon != NULL) || CPL_FindCPLInfo(_szSubObject, &_hIcon,
  67. &_nControl, &lpExtraParms))
  68. {
  69. *piIndex = _nControl;
  70. }
  71. else
  72. {
  73. // we failed to load the applet all of the sudden
  74. // use the first icon in the cpl file (*piIndex == 0)
  75. //
  76. // Assert(FALSE);
  77. DebugMsg(DM_ERROR,
  78. TEXT("Control Panel CCEIGIL: ") TEXT("Enumeration failed \"%s\""),
  79. _szSubObject);
  80. }
  81. }
  82. else if (*piIndex > 0)
  83. {
  84. // this is an invalid icon for a control panel
  85. // use the first icon in the file
  86. // this may be wrong but it's better than a generic doc icon
  87. // this fixes ODBC32 which is NOT dynamic but returns bogus ids
  88. *piIndex = 0;
  89. }
  90. hr = S_OK;
  91. }
  92. }
  93. return hr;
  94. }
  95. HRESULT CCtrlExtIconBase::_ExtractW(LPCWSTR pszFile, UINT nIconIndex,
  96. HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize)
  97. {
  98. LPTSTR lpExtraParms = NULL;
  99. HRESULT hr = S_FALSE;
  100. //-------------------------------------------------------------------
  101. // if there is no icon index then we must extract by loading the dude
  102. // if we have an icon index then it can be extracted with ExtractIcon
  103. // (which is much faster)
  104. // only perform a custom extract if we have a dynamic icon
  105. // otherwise just return S_FALSE and let our caller call ExtractIcon.
  106. //-------------------------------------------------------------------
  107. LPCTSTR p = StrChr(_szSubObject, TEXT(','));
  108. if ((!p || !StrToInt(p+1)) &&
  109. ((_hIcon != NULL) || CPL_FindCPLInfo(_szSubObject, &_hIcon,
  110. &_nControl, &lpExtraParms)))
  111. {
  112. if (_hIcon)
  113. {
  114. *phiconLarge = CopyIcon(_hIcon);
  115. *phiconSmall = NULL;
  116. if( *phiconLarge )
  117. hr = S_OK;
  118. }
  119. }
  120. return hr;
  121. }