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.

468 lines
11 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 1996.
  5. //
  6. // File: sdetails.cxx
  7. //
  8. // Contents: implementation of IShellDetails
  9. //
  10. // Classes: CJobsSD
  11. //
  12. // Functions:
  13. //
  14. // History: 1/4/1996 RaviR Created
  15. //
  16. //____________________________________________________________________________
  17. #include "..\pch\headers.hxx"
  18. #pragma hdrstop
  19. #include "dbg.h"
  20. #include "macros.h"
  21. #include "resource.h"
  22. #include "dll.hxx"
  23. #include "jobidl.hxx"
  24. #include "util.hxx"
  25. #include "common.hxx"
  26. //
  27. // extern
  28. //
  29. extern HINSTANCE g_hInstance;
  30. //////////////////////////////////////////////////////////////////////////////
  31. // Forward declaration of local functions
  32. //
  33. BOOL
  34. GetLocaleDateTimeString(
  35. SYSTEMTIME* pst,
  36. DWORD dwDateFlags,
  37. DWORD dwTimeFlags,
  38. TCHAR szBuff[],
  39. int cchBuffLen,
  40. LPSHELLDETAILS lpDetails);
  41. //////////////////////////////////////////////////////////////////////////////
  42. //
  43. // Define the columns (used by CJobsSD::GetDetailsOf)
  44. //
  45. struct COL_INFO
  46. {
  47. UINT idString;
  48. int fmt;
  49. UINT cxChar;
  50. };
  51. const COL_INFO c_ColumnHeaders[] =
  52. {
  53. {IDS_NAME, LVCFMT_LEFT, 30},
  54. {IDS_SCHEDULE, LVCFMT_LEFT, 20},
  55. {IDS_NEXTRUNTIME, LVCFMT_LEFT, 15},
  56. {IDS_LASTRUNTIME, LVCFMT_LEFT, 15},
  57. {IDS_STATUS, LVCFMT_LEFT, 25},
  58. #if !defined(_CHICAGO_)
  59. {IDS_LASTEXITCODE, LVCFMT_RIGHT, 15},
  60. {IDS_CREATOR, LVCFMT_LEFT, 15}
  61. #endif // !defined(_CHICAGO_)
  62. };
  63. //____________________________________________________________________________
  64. //
  65. // Class: CJobsSD
  66. //
  67. // Purpose: Provide IShellDetails interface to Job Folder objects.
  68. //
  69. // History: 1/24/1996 RaviR Created
  70. //____________________________________________________________________________
  71. class CJobsSD : public IShellDetails
  72. {
  73. public:
  74. CJobsSD(HWND hwnd) : m_ulRefs(1), m_hwnd(hwnd) {}
  75. ~CJobsSD() {}
  76. // IUnknown methods
  77. DECLARE_STANDARD_IUNKNOWN;
  78. // IShellDetails methods
  79. STDMETHOD(GetDetailsOf)(LPCITEMIDLIST pidl, UINT iColumn,
  80. LPSHELLDETAILS pDetails);
  81. STDMETHOD(ColumnClick)(UINT iColumn);
  82. private:
  83. HWND m_hwnd;
  84. CDllRef m_DllRef;
  85. };
  86. //____________________________________________________________________________
  87. //
  88. // Member: CJobsSD::IUnknown methods
  89. //____________________________________________________________________________
  90. IMPLEMENT_STANDARD_IUNKNOWN(CJobsSD)
  91. STDMETHODIMP
  92. CJobsSD::QueryInterface(REFIID riid, LPVOID* ppvObj)
  93. {
  94. if (IsEqualIID(IID_IUnknown, riid) ||
  95. IsEqualIID(IID_IShellDetails, riid))
  96. {
  97. *ppvObj = (IUnknown*)(IShellDetails*) this;
  98. this->AddRef();
  99. return S_OK;
  100. }
  101. else
  102. {
  103. *ppvObj = NULL;
  104. return E_NOINTERFACE;
  105. }
  106. }
  107. inline
  108. HRESULT
  109. CopyToSTRRET(STRRET &str, LPTSTR pszIn)
  110. {
  111. UINT uiByteLen = (lstrlen(pszIn) + 1) * sizeof(TCHAR);
  112. #ifdef UNICODE
  113. str.uType = STRRET_WSTR;
  114. str.pOleStr = (LPWSTR) SHAlloc(uiByteLen);
  115. if (str.pOleStr == NULL)
  116. {
  117. CHECK_HRESULT(E_OUTOFMEMORY);
  118. return E_OUTOFMEMORY;
  119. }
  120. CopyMemory(str.pOleStr, pszIn, uiByteLen);
  121. #else // ANSI
  122. str.uType = STRRET_CSTR;
  123. CopyMemory(str.cStr, pszIn, uiByteLen);
  124. #endif // ANSI
  125. return S_OK;
  126. }
  127. //____________________________________________________________________________
  128. //
  129. // Member: CJobsSD::GetDetailsOf
  130. //
  131. // Arguments: [pidl] -- IN
  132. // [iColumn] -- IN
  133. // [lpDetails] -- IN
  134. //
  135. // Returns: HRESULT.
  136. //
  137. // History: 1/8/1996 RaviR Created
  138. //
  139. //____________________________________________________________________________
  140. STDMETHODIMP
  141. CJobsSD::GetDetailsOf(
  142. LPCITEMIDLIST pidl,
  143. UINT iColumn,
  144. LPSHELLDETAILS lpDetails)
  145. {
  146. // TRACE(CJobsSD, GetDetailsOf);
  147. HRESULT hr = S_OK;
  148. TCHAR tcBuff[SCH_XBIGBUF_LEN] = TEXT("");
  149. if (iColumn >= COLUMN_COUNT)
  150. {
  151. return E_FAIL;
  152. }
  153. if (NULL == pidl)
  154. {
  155. //
  156. // Caller wants strings for the column headers
  157. //
  158. LoadString(g_hInstance,
  159. c_ColumnHeaders[iColumn].idString,
  160. tcBuff,
  161. SCH_XBIGBUF_LEN);
  162. lpDetails->fmt = c_ColumnHeaders[iColumn].fmt;
  163. lpDetails->cxChar = c_ColumnHeaders[iColumn].cxChar;
  164. }
  165. else
  166. {
  167. CJobID & jid = *(PJOBID)pidl;
  168. //
  169. // Fill tcBuff with the string describing column iColumn of
  170. // object jid. If jid represents a template object, only the
  171. // name column is not blank.
  172. //
  173. if (!jid.IsTemplate() || iColumn == COLUMN_NAME)
  174. {
  175. switch (iColumn)
  176. {
  177. case COLUMN_NAME:
  178. {
  179. lstrcpy(tcBuff, jid.GetName());
  180. break;
  181. }
  182. case COLUMN_SCHEDULE:
  183. {
  184. if (jid.IsJobFlagOn(TASK_FLAG_DISABLED) == TRUE)
  185. {
  186. LoadString(g_hInstance,
  187. IDS_DISABLED,
  188. tcBuff,
  189. SCH_XBIGBUF_LEN);
  190. }
  191. else if (jid.GetTriggerCount() > 1)
  192. {
  193. LoadString(g_hInstance,
  194. IDS_MULTIPLE_TRIGGERS,
  195. tcBuff,
  196. SCH_XBIGBUF_LEN);
  197. }
  198. else
  199. {
  200. hr = GetTriggerStringFromTrigger(&jid.GetTrigger(),
  201. tcBuff,
  202. SCH_XBIGBUF_LEN,
  203. lpDetails);
  204. }
  205. break;
  206. }
  207. case COLUMN_LASTRUNTIME:
  208. {
  209. SYSTEMTIME &st = jid.GetLastRunTime();
  210. if (st.wYear == 0 || st.wMonth == 0 || st.wDay == 0)
  211. {
  212. LoadString(g_hInstance,
  213. IDS_NEVER,
  214. tcBuff,
  215. SCH_XBIGBUF_LEN);
  216. }
  217. else
  218. {
  219. GetLocaleDateTimeString(&st,
  220. DATE_SHORTDATE,
  221. 0,
  222. tcBuff,
  223. SCH_XBIGBUF_LEN, lpDetails);
  224. }
  225. break;
  226. }
  227. case COLUMN_NEXTRUNTIME:
  228. jid.GetNextRunTimeString(tcBuff, SCH_XBIGBUF_LEN, FALSE, lpDetails);
  229. break;
  230. case COLUMN_STATUS:
  231. {
  232. ULONG ids = 0;
  233. if (jid.IsRunning())
  234. {
  235. ids = IDS_RUNNING;
  236. }
  237. else if (jid.WasRunMissed())
  238. {
  239. ids = IDS_MISSED;
  240. }
  241. else if (jid.DidJobStartFail())
  242. {
  243. ids = IDS_START_FAILED;
  244. }
  245. else if(jid.DidJobBadAcct())
  246. {
  247. ids = IDS_BAD_ACCT;
  248. }
  249. else if(jid.DidJobRestAcct())
  250. {
  251. ids = IDS_REST_ACCT;
  252. }
  253. if (ids)
  254. {
  255. LoadString(g_hInstance, ids, tcBuff, SCH_XBIGBUF_LEN);
  256. }
  257. break;
  258. }
  259. #if !defined(_CHICAGO_)
  260. case COLUMN_LASTEXITCODE:
  261. wsprintf(tcBuff, TEXT("0x%x"), jid.GetExitCode());
  262. break;
  263. case COLUMN_CREATOR:
  264. lstrcpy(tcBuff, jid.GetCreator());
  265. break;
  266. #endif // !defined(_CHICAGO_)
  267. }
  268. }
  269. }
  270. hr = CopyToSTRRET(lpDetails->str, tcBuff);
  271. return hr;
  272. }
  273. //____________________________________________________________________________
  274. //
  275. // Member: CJobsSD::ColumnClick
  276. //
  277. // Arguments: [iColumn] -- IN
  278. //
  279. // Returns: STDMETHODIMP
  280. //
  281. // History: 1/8/1996 RaviR Created
  282. //
  283. //____________________________________________________________________________
  284. STDMETHODIMP
  285. CJobsSD::ColumnClick(
  286. UINT iColumn)
  287. {
  288. TRACE(CJobsSD, ColumnClick);
  289. ShellFolderView_ReArrange(m_hwnd, iColumn);
  290. return S_OK;
  291. }
  292. //
  293. //Define the UNICODE RLM control character.
  294. //
  295. #ifdef UNICODE
  296. #define RLM TEXT("\x200f")
  297. #else
  298. #define RLM TEXT("\xfe")
  299. #endif
  300. //+-------------------------------------------------------------------------
  301. //
  302. // Function: GetLocaleDateTimeString, public
  303. //
  304. // Synopsis: Use the proper locale-formatted time and date
  305. //
  306. // History: 07/09/95 RaviR Created.
  307. //
  308. //--------------------------------------------------------------------------
  309. BOOL
  310. GetLocaleDateTimeString(
  311. SYSTEMTIME* pst,
  312. DWORD dwDateFlags,
  313. DWORD dwTimeFlags,
  314. TCHAR szBuff[],
  315. int cchBuffLen,
  316. LPSHELLDETAILS lpDetails)
  317. {
  318. if (pst->wYear == 0 || pst->wMonth == 0 || pst->wDay == 0)
  319. {
  320. szBuff = TEXT('\0');
  321. return TRUE;
  322. }
  323. LCID lcid = GetUserDefaultLCID();
  324. TCHAR Time[150] = TEXT("");
  325. TCHAR Date[150] = TEXT("");
  326. if (0 == GetTimeFormat(lcid, dwTimeFlags, pst, NULL, Time, 150))
  327. {
  328. DEBUG_OUT_LASTERROR;
  329. return FALSE;
  330. }
  331. #ifdef UNICODE
  332. if (lpDetails) {
  333. if (lpDetails->fmt & LVCFMT_RIGHT_TO_LEFT) {
  334. dwDateFlags |= DATE_RTLREADING;
  335. } else if (lpDetails->fmt & LVCFMT_LEFT_TO_RIGHT) {
  336. dwDateFlags |= DATE_LTRREADING;
  337. }
  338. }
  339. #endif
  340. if (0 == GetDateFormat(lcid, dwDateFlags, pst, NULL, Date, 150))
  341. {
  342. DEBUG_OUT_LASTERROR;
  343. return FALSE;
  344. }
  345. //
  346. //Force the time to appears as if it is preceded by BiDi character.
  347. //
  348. #ifdef UNICODE
  349. if (dwDateFlags & DATE_RTLREADING) {
  350. lstrcpy(szBuff, RLM);
  351. lstrcat(szBuff, Time);
  352. } else
  353. #endif
  354. lstrcpy(szBuff, Time);
  355. lstrcat(szBuff, TEXT(" "));
  356. lstrcat(szBuff, Date);
  357. return TRUE;
  358. }
  359. //____________________________________________________________________________
  360. //
  361. // Function: CJobsShellDetails_Create
  362. //
  363. // Synopsis: S
  364. //
  365. // Arguments: [hwnd] -- IN
  366. // [riid] -- IN
  367. // [ppvObj] -- IN
  368. //
  369. // Returns: HRESULT
  370. //
  371. // History: 1/24/1996 RaviR Created
  372. //____________________________________________________________________________
  373. HRESULT
  374. JFGetShellDetails(
  375. HWND hwnd,
  376. LPVOID* ppvObj)
  377. {
  378. CJobsSD* pObj = new CJobsSD(hwnd);
  379. if (NULL == pObj)
  380. {
  381. return E_OUTOFMEMORY;
  382. }
  383. HRESULT hr = pObj->QueryInterface(IID_IShellDetails, ppvObj);
  384. pObj->Release();
  385. return hr;
  386. }