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.

206 lines
5.4 KiB

  1. // this file implements shell command files.
  2. // .scf scffile
  3. // when executed, they run a shell internal command.
  4. // they can have stream storage, or whatnot in them
  5. //
  6. // file format is *PURPOSELY* text so that folks can create and modify by hand
  7. #include "shellprv.h"
  8. #include <desktopp.h>
  9. #include <trayp.h>
  10. extern HWND g_hwndTray; // desktop.cpp
  11. void SFC_IECommand(LPCTSTR pszFile)
  12. {
  13. TCHAR szCommand[40];
  14. if (GetPrivateProfileString(TEXT("IE"), TEXT("Command"), TEXT(""), szCommand, ARRAYSIZE(szCommand), pszFile))
  15. {
  16. if (!lstrcmpi(szCommand, TEXT("Channels"))
  17. && !SHRestricted2W(REST_NoChannelUI, NULL, 0))
  18. {
  19. Channel_QuickLaunch();
  20. }
  21. }
  22. }
  23. void SFC_TrayCommand(LPCTSTR pszFile)
  24. {
  25. HWND hwnd = g_hwndTray;
  26. if (hwnd && IsWindowInProcess(hwnd))
  27. {
  28. TCHAR szCommand[40];
  29. if (GetPrivateProfileString(TEXT("Taskbar"), TEXT("Command"), TEXT(""), szCommand, ARRAYSIZE(szCommand), pszFile))
  30. {
  31. char szAnsiCommand[40];
  32. SHTCharToAnsi(szCommand, szAnsiCommand, ARRAYSIZE(szAnsiCommand));
  33. LPSTR psz = StrDupA(szAnsiCommand);
  34. if (psz)
  35. {
  36. if (!PostMessage(hwnd, TM_PRIVATECOMMAND, 0, (LPARAM)psz))
  37. LocalFree(psz);
  38. }
  39. }
  40. }
  41. }
  42. const struct
  43. {
  44. UINT id;
  45. void (*pfn)(LPCTSTR pszBuf);
  46. }
  47. c_sCmdInfo[] =
  48. {
  49. { 2, SFC_TrayCommand},
  50. { 3, SFC_IECommand},
  51. };
  52. STDAPI_(void) ShellExecCommandFile(LPCITEMIDLIST pidl)
  53. {
  54. TCHAR szFile[MAX_PATH];
  55. if (SHGetPathFromIDList(pidl, szFile))
  56. {
  57. UINT uID = GetPrivateProfileInt(TEXT("Shell"), TEXT("Command"), 0, szFile);
  58. if (uID)
  59. {
  60. for (int i = 0; i < ARRAYSIZE(c_sCmdInfo); i++)
  61. {
  62. if (uID == c_sCmdInfo[i].id)
  63. {
  64. c_sCmdInfo[i].pfn(szFile);
  65. break;
  66. }
  67. }
  68. }
  69. }
  70. }
  71. class CShellCmdFileIcon : public IExtractIconA, public IExtractIconW, public IPersistFile
  72. {
  73. public:
  74. // IUnknown
  75. STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
  76. STDMETHODIMP_(ULONG) AddRef();
  77. STDMETHODIMP_(ULONG) Release();
  78. // IExtractIconA
  79. STDMETHODIMP GetIconLocation(UINT uFlags, LPSTR pszIconFile, UINT cchMax, int* piIndex, UINT* pwFlags);
  80. STDMETHODIMP Extract(LPCSTR pszFile, UINT nIconIndex, HICON* phiconLarge, HICON* phiconSmall, UINT nIconSize) {return S_FALSE;};
  81. // IExtractIconW
  82. STDMETHODIMP GetIconLocation(UINT uFlags, LPWSTR pszIconFile, UINT cchMax, int* piIndex, UINT* pwFlags);
  83. STDMETHODIMP Extract(LPCWSTR pszFile, UINT nIconIndex, HICON* phiconLarge, HICON* phiconSmall, UINT nIconSize) {return S_FALSE;};
  84. // IPersist
  85. STDMETHODIMP GetClassID(CLSID *pclsid) { *pclsid = CLSID_CmdFileIcon; return S_OK;};
  86. // IPersistFile
  87. STDMETHODIMP IsDirty(void) {return S_FALSE;};
  88. STDMETHODIMP Save(LPCOLESTR pcwszFileName, BOOL bRemember) {return S_OK;};
  89. STDMETHODIMP SaveCompleted(LPCOLESTR pcwszFileName){return S_OK;};
  90. STDMETHODIMP Load(LPCOLESTR pcwszFileName, DWORD dwMode);
  91. STDMETHODIMP GetCurFile(LPOLESTR *ppwszFileName);
  92. CShellCmdFileIcon() { _cRef = 1; DllAddRef(); };
  93. private:
  94. ~CShellCmdFileIcon() { DllRelease(); };
  95. LONG _cRef;
  96. TCHAR _szFile[MAX_PATH];
  97. };
  98. ULONG CShellCmdFileIcon::AddRef()
  99. {
  100. return InterlockedIncrement(&_cRef);
  101. }
  102. ULONG CShellCmdFileIcon::Release()
  103. {
  104. if (InterlockedDecrement(&_cRef))
  105. return _cRef;
  106. delete this;
  107. return 0;
  108. }
  109. HRESULT CShellCmdFileIcon::GetIconLocation(UINT uFlags, LPTSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags)
  110. {
  111. TCHAR szData[MAX_PATH + 80];
  112. if (_szFile[0])
  113. {
  114. *pwFlags = 0;
  115. *piIndex = 0;
  116. szIconFile[0] = 0;
  117. GetPrivateProfileString(TEXT("Shell"), TEXT("IconFile"), TEXT(""), szData, ARRAYSIZE(szData), _szFile);
  118. *piIndex = PathParseIconLocation(szData);
  119. lstrcpyn(szIconFile, szData, cchMax);
  120. return S_OK;
  121. }
  122. return E_FAIL;
  123. }
  124. HRESULT CShellCmdFileIcon::GetIconLocation(UINT uFlags, LPSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags)
  125. {
  126. WCHAR szAnsiIconPath[MAX_PATH];
  127. HRESULT hr = GetIconLocation(uFlags, szAnsiIconPath, MAX_PATH, piIndex, pwFlags);
  128. if (SUCCEEDED(hr))
  129. {
  130. SHUnicodeToAnsi(szAnsiIconPath, szIconFile, cchMax);
  131. }
  132. return hr;
  133. }
  134. // IPersistFile::Load
  135. STDMETHODIMP CShellCmdFileIcon::Load(LPCOLESTR pwszFile, DWORD dwMode)
  136. {
  137. SHUnicodeToTChar(pwszFile, _szFile, ARRAYSIZE(_szFile));
  138. return S_OK;
  139. }
  140. STDMETHODIMP CShellCmdFileIcon::GetCurFile(LPOLESTR *ppwszFileName)
  141. {
  142. SHTCharToUnicode(_szFile, *ppwszFileName, ARRAYSIZE(_szFile));
  143. return S_OK;
  144. }
  145. HRESULT CShellCmdFileIcon::QueryInterface(REFIID riid, void **ppv)
  146. {
  147. static const QITAB qit[] =
  148. {
  149. QITABENT(CShellCmdFileIcon, IExtractIconA),
  150. QITABENT(CShellCmdFileIcon, IExtractIconW),
  151. QITABENT(CShellCmdFileIcon, IPersistFile),
  152. QITABENTMULTI(CShellCmdFileIcon, IPersist, IPersistFile),
  153. { 0 },
  154. };
  155. return QISearch(this, qit, riid, ppv);
  156. }
  157. STDAPI CShellCmdFileIcon_CreateInstance(IUnknown* pUnkOuter, REFIID riid, void **ppv)
  158. {
  159. HRESULT hr;
  160. CShellCmdFileIcon *pObj = new CShellCmdFileIcon();
  161. if (pObj)
  162. {
  163. hr = pObj->QueryInterface(riid, ppv);
  164. pObj->Release();
  165. }
  166. else
  167. {
  168. *ppv = NULL;
  169. hr = E_OUTOFMEMORY;
  170. }
  171. return hr;
  172. }