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.

676 lines
16 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // File: util.cpp
  4. //
  5. // Description:
  6. //
  7. // Copyright (c) 2000 Microsoft Corp.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. // App Includes
  11. #include "precomp.h"
  12. #include "main.h"
  13. #include "resource.h"
  14. #include <shlobj.h>
  15. #include <shfolder.h>
  16. ////////////////////////// Function Prototypes ////////////////////////////////
  17. int CALLBACK ChangeDirectoryCallback(HWND hWnd,
  18. UINT uMsg,
  19. LPARAM lParam,
  20. LPARAM lpData);
  21. ///////////////////////////
  22. // GVAR_LOCAL
  23. //
  24. // Global Variable
  25. //
  26. static struct GVAR_LOCAL
  27. {
  28. HKEY hRootKey;
  29. } GVAR_LOCAL =
  30. {
  31. NULL
  32. };
  33. ///////////////////////////////
  34. // Util::Init
  35. //
  36. HRESULT Util::Init(HINSTANCE hInstance)
  37. {
  38. HRESULT hr = S_OK;
  39. if (SUCCEEDED(hr))
  40. {
  41. LRESULT lr = NOERROR;
  42. DWORD dwDisposition = 0;
  43. lr = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  44. REG_KEY_PROJECTOR,
  45. NULL,
  46. NULL,
  47. 0,
  48. KEY_ALL_ACCESS,
  49. NULL,
  50. &GVAR_LOCAL.hRootKey,
  51. &dwDisposition);
  52. if (lr != NOERROR)
  53. {
  54. DBG_ERR(("InitApp, failed to open registry key"));
  55. hr = E_FAIL;
  56. }
  57. }
  58. return hr;
  59. }
  60. ///////////////////////////////
  61. // Util::Term
  62. //
  63. HRESULT Util::Term(void)
  64. {
  65. RegCloseKey(GVAR_LOCAL.hRootKey);
  66. GVAR_LOCAL.hRootKey = NULL;
  67. return S_OK;
  68. }
  69. ///////////////////////////////
  70. // GetMyPicturesFolder
  71. //
  72. HRESULT Util::GetMyPicturesFolder(TCHAR *pszFolder,
  73. DWORD cchFolder)
  74. {
  75. HRESULT hr = S_OK;
  76. // set the directory of the images.
  77. hr = SHGetFolderPath(NULL,
  78. CSIDL_MYPICTURES,
  79. NULL,
  80. 0,
  81. pszFolder);
  82. return hr;
  83. }
  84. ///////////////////////////////
  85. // GetProgramFilesFolder
  86. //
  87. HRESULT Util::GetProgramFilesFolder(TCHAR *pszFolder,
  88. DWORD cchFolder)
  89. {
  90. HRESULT hr = S_OK;
  91. // set the directory of the images.
  92. hr = SHGetFolderPath(NULL,
  93. CSIDL_PROGRAM_FILES,
  94. NULL,
  95. 0,
  96. pszFolder);
  97. return hr;
  98. }
  99. ///////////////////////////////
  100. // Util::GetAppDirs
  101. //
  102. HRESULT Util::GetAppDirs(TCHAR *pszDeviceDir,
  103. DWORD cchDeviceDir,
  104. TCHAR *pszImageDir,
  105. DWORD cchImageDir)
  106. {
  107. HRESULT hr = S_OK;
  108. ASSERT(pszDeviceDir != NULL);
  109. ASSERT(pszImageDir != NULL);
  110. ASSERT(cchDeviceDir > 0);
  111. ASSERT(cchImageDir > 0);
  112. if ((pszDeviceDir == NULL) ||
  113. (pszImageDir == NULL) ||
  114. (cchDeviceDir == 0) ||
  115. (cchImageDir == 0))
  116. {
  117. return E_INVALIDARG;
  118. }
  119. // preload the image dir buffer with the "My Pictures" path
  120. // so that it is set as the default directory if we don't
  121. // have an overriding one in the registry.
  122. if (SUCCEEDED(hr))
  123. {
  124. hr = GetMyPicturesFolder(pszImageDir,
  125. cchImageDir);
  126. }
  127. // preload the device dir buffer with the "Program Files\MSProjector"
  128. // install path so that it is set as the default directory if we don't
  129. // have an overriding one in the registry.
  130. if (SUCCEEDED(hr))
  131. {
  132. hr = GetProgramFilesFolder(pszDeviceDir,
  133. cchDeviceDir);
  134. }
  135. if (SUCCEEDED(hr))
  136. {
  137. if (pszDeviceDir[_tcslen(pszDeviceDir) - 1] != '\\')
  138. {
  139. _tcscat(pszDeviceDir, _T("\\"));
  140. }
  141. _tcscat(pszDeviceDir, DEFAULT_INSTALL_PATH);
  142. }
  143. if (SUCCEEDED(hr))
  144. {
  145. // get the image dir.
  146. hr = GetRegString(REG_VAL_IMAGE_DIR,
  147. pszImageDir,
  148. cchImageDir,
  149. TRUE);
  150. if (FAILED(hr))
  151. {
  152. DBG_ERR(("GetAppDirs, failed to get/set image directory. "
  153. "This should never happen"));
  154. ASSERT(FALSE);
  155. }
  156. // get the device dir
  157. hr = GetRegString(REG_VAL_DEVICE_DIR,
  158. pszDeviceDir,
  159. cchDeviceDir,
  160. TRUE);
  161. if (FAILED(hr))
  162. {
  163. DBG_ERR(("GetAppDirs, failed to get/set image directory. "
  164. "This should never happen"));
  165. ASSERT(FALSE);
  166. }
  167. }
  168. return hr;
  169. }
  170. ///////////////////////////////
  171. // Util::GetRegString
  172. //
  173. HRESULT Util::GetRegString(const TCHAR *pszValueName,
  174. TCHAR *pszDir,
  175. DWORD cchDir,
  176. BOOL bSetIfNotExist)
  177. {
  178. HRESULT hr = S_OK;
  179. ASSERT(pszValueName != NULL);
  180. ASSERT(pszDir != NULL);
  181. ASSERT(cchDir > 0);
  182. if ((pszValueName == NULL) ||
  183. (pszDir == NULL) ||
  184. (cchDir <= 0))
  185. {
  186. return E_INVALIDARG;
  187. }
  188. if (SUCCEEDED(hr))
  189. {
  190. LRESULT lr = NOERROR;
  191. DWORD dwType = REG_SZ;
  192. lr = RegQueryValueEx(GVAR_LOCAL.hRootKey,
  193. pszValueName,
  194. NULL,
  195. &dwType,
  196. (BYTE*) pszDir,
  197. &cchDir);
  198. if (lr != NOERROR)
  199. {
  200. if (bSetIfNotExist)
  201. {
  202. // we need the number of bytes we are writing to the registry.
  203. DWORD dwLength = _tcslen(pszDir) * sizeof(TCHAR) + 1;
  204. lr = RegSetValueEx(GVAR_LOCAL.hRootKey,
  205. pszValueName,
  206. NULL,
  207. REG_SZ,
  208. (BYTE*) pszDir,
  209. dwLength);
  210. }
  211. else
  212. {
  213. hr = E_FAIL;
  214. DBG_ERR(("GetRegString, failed to get '%ls' from registry, hr = 0x%08lx",
  215. pszValueName,
  216. hr));
  217. }
  218. }
  219. }
  220. return hr;
  221. }
  222. ///////////////////////////////
  223. // Util::SetRegString
  224. //
  225. HRESULT Util::SetRegString(const TCHAR *pszValueName,
  226. TCHAR *pszDir,
  227. DWORD cchDir)
  228. {
  229. HRESULT hr = S_OK;
  230. ASSERT(pszValueName != NULL);
  231. ASSERT(pszDir != NULL);
  232. ASSERT(cchDir > 0);
  233. if ((pszValueName == NULL) ||
  234. (pszDir == NULL) ||
  235. (cchDir <= 0))
  236. {
  237. return E_INVALIDARG;
  238. }
  239. if (SUCCEEDED(hr))
  240. {
  241. LRESULT lr = NOERROR;
  242. DWORD dwLength = _tcslen(pszDir) * sizeof(TCHAR) + 1;
  243. // we need the number of bytes we are writing to the registry.
  244. lr = RegSetValueEx(GVAR_LOCAL.hRootKey,
  245. pszValueName,
  246. NULL,
  247. REG_SZ,
  248. (BYTE*) pszDir,
  249. dwLength);
  250. if (lr != NOERROR)
  251. {
  252. hr = E_FAIL;
  253. DBG_ERR(("SetRegString, failed to set '%ls' to registry, hr = 0x%08lx",
  254. pszValueName,
  255. hr));
  256. }
  257. }
  258. return hr;
  259. }
  260. ///////////////////////////////
  261. // Util::GetRegDWORD
  262. //
  263. HRESULT Util::GetRegDWORD(const TCHAR *pszValueName,
  264. DWORD *pdwValue,
  265. BOOL bSetIfNotExist)
  266. {
  267. HRESULT hr = S_OK;
  268. ASSERT(pszValueName != NULL);
  269. ASSERT(pdwValue != NULL);
  270. if ((pszValueName == NULL) ||
  271. (pdwValue == NULL))
  272. {
  273. return E_INVALIDARG;
  274. }
  275. if (SUCCEEDED(hr))
  276. {
  277. LRESULT lr = NOERROR;
  278. DWORD dwType = REG_DWORD;
  279. DWORD dwSize = sizeof(DWORD);
  280. lr = RegQueryValueEx(GVAR_LOCAL.hRootKey,
  281. pszValueName,
  282. NULL,
  283. &dwType,
  284. (BYTE*) pdwValue,
  285. &dwSize);
  286. if (lr != NOERROR)
  287. {
  288. if (bSetIfNotExist)
  289. {
  290. // we need the number of bytes we are writing to the registry.
  291. lr = RegSetValueEx(GVAR_LOCAL.hRootKey,
  292. pszValueName,
  293. NULL,
  294. REG_SZ,
  295. (BYTE*) pdwValue,
  296. dwSize);
  297. }
  298. else
  299. {
  300. hr = E_FAIL;
  301. DBG_ERR(("GetRegDWORD, failed to get '%ls' from registry, hr = 0x%08lx",
  302. pszValueName,
  303. hr));
  304. }
  305. }
  306. }
  307. return hr;
  308. }
  309. ///////////////////////////////
  310. // Util::SetRegDWORD
  311. //
  312. HRESULT Util::SetRegDWORD(const TCHAR *pszValueName,
  313. DWORD dwValue)
  314. {
  315. HRESULT hr = S_OK;
  316. ASSERT(pszValueName != NULL);
  317. if (pszValueName == NULL)
  318. {
  319. return E_INVALIDARG;
  320. }
  321. if (SUCCEEDED(hr))
  322. {
  323. LRESULT lr = NOERROR;
  324. // we need the number of bytes we are writing to the registry.
  325. lr = RegSetValueEx(GVAR_LOCAL.hRootKey,
  326. pszValueName,
  327. NULL,
  328. REG_DWORD,
  329. (BYTE*) &dwValue,
  330. sizeof(DWORD));
  331. if (lr != NOERROR)
  332. {
  333. hr = E_FAIL;
  334. DBG_ERR(("SetRegDWORD, failed to set '%ls' to registry, hr = 0x%08lx",
  335. pszValueName,
  336. hr));
  337. }
  338. }
  339. return hr;
  340. }
  341. ///////////////////////////////
  342. // Util::BrowseForDirectory
  343. //
  344. bool Util::BrowseForDirectory(HWND hWnd,
  345. const TCHAR *pszPrompt,
  346. TCHAR *pszDirectory,
  347. DWORD cchDirectory )
  348. {
  349. bool bResult = false;
  350. LPMALLOC pMalloc;
  351. HRESULT hr = SHGetMalloc(&pMalloc);
  352. if (SUCCEEDED(hr))
  353. {
  354. TCHAR szDisplayName[_MAX_PATH + 1] = {0};
  355. TCHAR szDirectory[_MAX_PATH + 1] = {0};
  356. BROWSEINFO BrowseInfo = {0};
  357. BrowseInfo.hwndOwner = hWnd;
  358. BrowseInfo.pszDisplayName = szDisplayName;
  359. BrowseInfo.lpszTitle = pszPrompt;
  360. BrowseInfo.ulFlags = BIF_RETURNONLYFSDIRS;
  361. BrowseInfo.lpfn = ChangeDirectoryCallback;
  362. BrowseInfo.lParam = (LPARAM)szDirectory;
  363. BrowseInfo.iImage = 0;
  364. LPITEMIDLIST pidl = SHBrowseForFolder(&BrowseInfo);
  365. if (pidl != NULL)
  366. {
  367. TCHAR szResult[MAX_PATH + 1] = {0};
  368. if (SHGetPathFromIDList(pidl, szResult))
  369. {
  370. _tcsncpy(pszDirectory, szResult, cchDirectory);
  371. bResult = true;
  372. }
  373. pMalloc->Free(pidl);
  374. }
  375. pMalloc->Release();
  376. }
  377. return bResult;
  378. }
  379. ///////////////////////////////
  380. // ChangeDirectoryCallback
  381. //
  382. int CALLBACK ChangeDirectoryCallback(HWND hWnd,
  383. UINT uMsg,
  384. LPARAM lParam,
  385. LPARAM lpData )
  386. {
  387. if (uMsg == BFFM_INITIALIZED)
  388. {
  389. SendMessage(hWnd, BFFM_SETSELECTION, 1, (LPARAM)lpData );
  390. }
  391. return 0;
  392. }
  393. ///////////////////////////////
  394. // Util::FormatTime
  395. //
  396. HRESULT Util::FormatTime(HINSTANCE hInstance,
  397. UINT nTotalSeconds,
  398. TCHAR *pszTime,
  399. DWORD cchTime)
  400. {
  401. ASSERT(pszTime != NULL);
  402. HRESULT hr = S_OK;
  403. int iResult = 0;
  404. TCHAR szString[255 + 1] = {0};
  405. UINT nMinutes = nTotalSeconds / 60;
  406. UINT nSeconds = nTotalSeconds % 60;
  407. UINT uiStrResID = 0;
  408. if (pszTime == NULL)
  409. {
  410. return E_INVALIDARG;
  411. }
  412. if (nMinutes == 0)
  413. {
  414. if (nSeconds == 1)
  415. {
  416. uiStrResID = IDS_SECOND;
  417. }
  418. else
  419. {
  420. uiStrResID = IDS_SECONDS;
  421. }
  422. }
  423. else if (nSeconds == 0)
  424. {
  425. if (nMinutes == 1)
  426. {
  427. uiStrResID = IDS_MINUTE;
  428. }
  429. else
  430. {
  431. uiStrResID = IDS_MINUTES;
  432. }
  433. }
  434. else if ((nMinutes == 1) && (nSeconds == 1))
  435. {
  436. uiStrResID = IDS_MINUTE_AND_SECOND;
  437. }
  438. else if (nMinutes == 1)
  439. {
  440. uiStrResID = IDS_MINUTE_AND_SECONDS;
  441. }
  442. else if (nSeconds == 1)
  443. {
  444. uiStrResID = IDS_MINUTES_AND_SECOND;
  445. }
  446. else
  447. {
  448. uiStrResID = IDS_MINUTES_AND_SECONDS;
  449. }
  450. if (uiStrResID != 0)
  451. {
  452. iResult = ::LoadString(hInstance,
  453. uiStrResID,
  454. szString,
  455. sizeof(szString) / sizeof(TCHAR));
  456. }
  457. if (iResult != 0)
  458. {
  459. if (nMinutes == 0)
  460. {
  461. _sntprintf(pszTime, cchTime, szString, nSeconds);
  462. }
  463. else if (nSeconds == 0)
  464. {
  465. _sntprintf(pszTime, cchTime, szString, nMinutes);
  466. }
  467. else
  468. {
  469. _sntprintf(pszTime, cchTime, szString, nMinutes, nSeconds);
  470. }
  471. }
  472. return hr;
  473. }
  474. ///////////////////////////////
  475. // Util::FormatScale
  476. //
  477. HRESULT Util::FormatScale(HINSTANCE hInstance,
  478. DWORD dwImageScaleFactor,
  479. TCHAR *pszScale,
  480. DWORD cchScale)
  481. {
  482. ASSERT(pszScale != NULL);
  483. HRESULT hr = S_OK;
  484. int iResult = 0;
  485. TCHAR szString[255 + 1] = {0};
  486. UINT uiStrResID = IDS_PERCENT;
  487. if (pszScale == NULL)
  488. {
  489. return E_INVALIDARG;
  490. }
  491. if (uiStrResID != 0)
  492. {
  493. iResult = ::LoadString(hInstance,
  494. uiStrResID,
  495. szString,
  496. sizeof(szString) / sizeof(TCHAR));
  497. }
  498. if (iResult != 0)
  499. {
  500. _sntprintf(pszScale, cchScale, szString, dwImageScaleFactor);
  501. }
  502. return hr;
  503. }
  504. ///////////////////////////////
  505. // EndsWithChar
  506. //
  507. static BOOL EndsWithChar( LPCTSTR psz, TCHAR c )
  508. {
  509. TCHAR* pszLast = _tcsrchr( (TCHAR*)psz, c ); // find last occurence of char in psz
  510. return(( NULL != pszLast ) && ( *_tcsinc( pszLast ) == _T('\0') ) );
  511. }
  512. ///////////////////////////////
  513. // StripTrailingChar
  514. //
  515. static void StripTrailingChar(TCHAR* input, TCHAR c)
  516. {
  517. while (EndsWithChar(input, c))
  518. {
  519. TCHAR* p = input + _tcsclen(input) - 1;
  520. *p = _T('\0');
  521. }
  522. return;
  523. }
  524. ///////////////////////////////
  525. // GetString
  526. //
  527. BOOL Util::GetString(HINSTANCE hInstance,
  528. INT iStrResID,
  529. TCHAR *pszString,
  530. DWORD cchString,
  531. ...)
  532. {
  533. TCHAR szFmtString[255 + 1] = {0};
  534. INT iResult = 0;
  535. va_list vaList;
  536. BOOL bSuccess = FALSE;
  537. iResult = ::LoadString(hInstance,
  538. iStrResID,
  539. szFmtString,
  540. sizeof(szFmtString) / sizeof(TCHAR));
  541. if (iResult != 0)
  542. {
  543. va_start(vaList, cchString);
  544. _vsntprintf(pszString, cchString - 1, szFmtString, vaList);
  545. va_end(vaList);
  546. bSuccess = TRUE;
  547. }
  548. else
  549. {
  550. bSuccess = FALSE;
  551. }
  552. return bSuccess;
  553. }
  554. ///////////////////////////////
  555. // DoesDirExist
  556. //
  557. BOOL Util::DoesDirExist( LPCTSTR pszPath )
  558. {
  559. TCHAR szTemp[MAX_PATH] = {0};
  560. _tcscpy( szTemp, pszPath );
  561. StripTrailingChar( szTemp, _T('\\') );
  562. DWORD dw = GetFileAttributes( szTemp );
  563. return((dw != 0xFFFFFFFF) && (dw & FILE_ATTRIBUTE_DIRECTORY) );
  564. }