Leaked source code of windows server 2003
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.

1814 lines
54 KiB

  1. // =================================================================================
  2. // Common functions
  3. // Written by: Steven J. Bailey on 1/21/96
  4. // =================================================================================
  5. #include "pch.hxx"
  6. #include <shlwapi.h>
  7. #include "xpcomm.h"
  8. #include "strconst.h"
  9. #include "error.h"
  10. #include "deterr.h"
  11. #include "progress.h"
  12. #include "imaildlg.h"
  13. #include "imnact.h"
  14. #include "demand.h"
  15. // =================================================================================
  16. // Prototypes
  17. // =================================================================================
  18. INT_PTR CALLBACK DetailedErrorDlgProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  19. BOOL DetailedErrorDlgProc_OnInitDialog (HWND hwndDlg, HWND hwndFocus, LPARAM lParam);
  20. void DetailedErrorDlgProc_OnCommand (HWND hwndDlg, int id, HWND hwndCtl, UINT codeNotify);
  21. void DetailedErrorDlgProc_OnOk (HWND hwndDlg, HWND hwndCtl, UINT uNotifyCode);
  22. void DetailedErrorDlgProc_OnCancel (HWND hwndDlg, HWND hwndCtl, UINT uNotifyCode);
  23. void DetailedErrorDlgProc_OnDetails (HWND hwndDlg, HWND hwndCtl, UINT uNotifyCode);
  24. // =================================================================================
  25. // Defines
  26. // =================================================================================
  27. #define IDT_PROGRESS_DELAY WM_USER + 1
  28. // =================================================================================
  29. // SzStrAlloc
  30. // =================================================================================
  31. LPTSTR SzStrAlloc (ULONG cch)
  32. {
  33. LPTSTR psz = NULL;
  34. if (!MemAlloc ((LPVOID *)&psz, (cch + 1) * sizeof (TCHAR)))
  35. return NULL;
  36. return psz;
  37. }
  38. // ------------------------------------------------------------------------------------
  39. // InetMailErrorDlgProc (no longer part of CInetMail)
  40. // ------------------------------------------------------------------------------------
  41. INT_PTR CALLBACK InetMailErrorDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  42. {
  43. // Locals
  44. LPINETMAILERROR pError;
  45. static RECT s_rcDialog;
  46. static BOOL s_fDetails=FALSE;
  47. RECT rcDetails, rcDlg;
  48. DWORD cyDetails;
  49. TCHAR szRes[255];
  50. TCHAR szMsg[255 + 50];
  51. HWND hwndDetails;
  52. // Handle Message
  53. switch (uMsg)
  54. {
  55. case WM_INITDIALOG:
  56. // Get the pointer
  57. pError = (LPINETMAILERROR)lParam;
  58. if (!pError)
  59. {
  60. Assert (FALSE);
  61. EndDialog(hwnd, IDCANCEL);
  62. return 1;
  63. }
  64. // Center
  65. CenterDialog (hwnd);
  66. // Set Error message
  67. Assert(pError->pszMessage);
  68. if (pError->pszMessage)
  69. SetDlgItemText(hwnd, idsInetMailError, pError->pszMessage);
  70. // Get whnd of details
  71. hwndDetails = GetDlgItem(hwnd, ideInetMailDetails);
  72. // Set Details
  73. if (!FIsStringEmpty(pError->pszDetails))
  74. {
  75. SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
  76. SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)pError->pszDetails);
  77. SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
  78. SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)g_szCRLF);
  79. SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
  80. SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)g_szCRLF);
  81. }
  82. // Configuration
  83. if (AthLoadString(idsDetails_Config, szRes, sizeof(szRes)/sizeof(TCHAR)))
  84. {
  85. SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
  86. SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szRes);
  87. SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
  88. SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)g_szCRLF);
  89. }
  90. // Account:
  91. if (!FIsStringEmpty(pError->pszAccount))
  92. {
  93. TCHAR szAccount[255 + CCHMAX_ACCOUNT_NAME];
  94. if (AthLoadString(idsDetail_Account, szRes, sizeof(szRes)/sizeof(TCHAR)))
  95. {
  96. wnsprintf(szAccount, ARRAYSIZE(szAccount), " %s %s\r\n", szRes, pError->pszAccount);
  97. SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
  98. SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szAccount);
  99. }
  100. }
  101. // Server:
  102. if (!FIsStringEmpty(pError->pszServer))
  103. {
  104. TCHAR szServer[255 + CCHMAX_SERVER_NAME];
  105. if (AthLoadString(idsDetail_Server, szRes, sizeof(szRes)/sizeof(TCHAR)))
  106. {
  107. wnsprintf(szServer, ARRAYSIZE(szServer), " %s %s\r\n", szRes, pError->pszServer);
  108. SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
  109. SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szServer);
  110. }
  111. }
  112. // User Name:
  113. if (!FIsStringEmpty(pError->pszUserName))
  114. {
  115. TCHAR szUserName[255 + CCHMAX_USERNAME];
  116. if (AthLoadString(idsDetail_UserName, szRes, sizeof(szRes)/sizeof(TCHAR)))
  117. {
  118. wnsprintf(szUserName, ARRAYSIZE(szUserName), " %s %s\r\n", szRes, pError->pszUserName);
  119. SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
  120. SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szUserName);
  121. }
  122. }
  123. // Protocol:
  124. if (!FIsStringEmpty(pError->pszProtocol))
  125. {
  126. TCHAR szProtocol[255 + 10];
  127. if (AthLoadString(idsDetail_Protocol, szRes, sizeof(szRes)/sizeof(TCHAR)))
  128. {
  129. wnsprintf(szProtocol, ARRAYSIZE(szProtocol), " %s %s\r\n", szRes, pError->pszProtocol);
  130. SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
  131. SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szProtocol);
  132. }
  133. }
  134. // Port:
  135. if (AthLoadString(idsDetail_Port, szRes, sizeof(szRes)/sizeof(TCHAR)))
  136. {
  137. wnsprintf(szMsg, ARRAYSIZE(szMsg), " %s %d\r\n", szRes, pError->dwPort);
  138. SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
  139. SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szMsg);
  140. }
  141. // Secure:
  142. if (AthLoadString(idsDetail_Secure, szRes, sizeof(szRes)/sizeof(TCHAR)))
  143. {
  144. wnsprintf(szMsg, ARRAYSIZE(szMsg), " %s %d\r\n", szRes, pError->fSecure);
  145. SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
  146. SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szMsg);
  147. }
  148. // Error Number:
  149. if (pError->dwErrorNumber)
  150. {
  151. if (AthLoadString(idsDetail_ErrorNumber, szRes, sizeof(szRes)/sizeof(TCHAR)))
  152. {
  153. wnsprintf(szMsg, ARRAYSIZE(szMsg), " %s %d\r\n", szRes, pError->dwErrorNumber);
  154. SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
  155. SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szMsg);
  156. }
  157. }
  158. // HRESULT:
  159. if (pError->hrError)
  160. {
  161. if (AthLoadString(idsDetail_HRESULT, szRes, sizeof(szRes)/sizeof(TCHAR)))
  162. {
  163. wnsprintf(szMsg, ARRAYSIZE(szMsg), " %s %08x\r\n", szRes, pError->hrError);
  164. SendMessage(hwndDetails, EM_SETSEL, (WPARAM)-1, (LPARAM)-1);
  165. SendMessage(hwndDetails, EM_REPLACESEL, FALSE, (LPARAM)szMsg);
  166. }
  167. }
  168. // Save Original Size of the dialog
  169. GetWindowRect (hwnd, &s_rcDialog);
  170. // Never show details by default
  171. s_fDetails = FALSE;
  172. // Hide details drop down
  173. if (s_fDetails == FALSE)
  174. {
  175. GetWindowRect(GetDlgItem (hwnd, idcIMProgSplitter), &rcDetails);
  176. cyDetails = s_rcDialog.bottom - rcDetails.top;
  177. MoveWindow(hwnd, s_rcDialog.left, s_rcDialog.top, s_rcDialog.right - s_rcDialog.left, s_rcDialog.bottom - s_rcDialog.top - cyDetails - 1, FALSE);
  178. }
  179. else
  180. {
  181. AthLoadString(idsHideDetails, szRes, sizeof (szRes)/sizeof(TCHAR));
  182. SetWindowText(GetDlgItem(hwnd, idcIMProgSplitter), szRes);
  183. }
  184. // Save the pointer
  185. return 1;
  186. case WM_COMMAND:
  187. switch(GET_WM_COMMAND_ID(wParam,lParam))
  188. {
  189. case IDCANCEL:
  190. case IDOK:
  191. EndDialog(hwnd, IDOK);
  192. return 1;
  193. case idbInetMailDetails:
  194. GetWindowRect (hwnd, &rcDlg);
  195. if (s_fDetails == FALSE)
  196. {
  197. MoveWindow(hwnd, rcDlg.left, rcDlg.top, s_rcDialog.right - s_rcDialog.left, s_rcDialog.bottom - s_rcDialog.top, TRUE);
  198. AthLoadString(idsHideDetails, szRes, sizeof(szRes)/sizeof(TCHAR));
  199. SetWindowText(GetDlgItem (hwnd, idbInetMailDetails), szRes);
  200. s_fDetails = TRUE;
  201. }
  202. else
  203. {
  204. GetWindowRect(GetDlgItem (hwnd, idcIMProgSplitter), &rcDetails);
  205. cyDetails = rcDlg.bottom - rcDetails.top;
  206. MoveWindow (hwnd, rcDlg.left, rcDlg.top, s_rcDialog.right - s_rcDialog.left, s_rcDialog.bottom - s_rcDialog.top - cyDetails - 1, TRUE);
  207. AthLoadString (idsShowDetails, szRes, sizeof(szRes)/sizeof(TCHAR));
  208. SetWindowText (GetDlgItem (hwnd, idbInetMailDetails), szRes);
  209. s_fDetails = FALSE;
  210. }
  211. }
  212. break;
  213. }
  214. // Done
  215. return 0;
  216. }
  217. // =================================================================================
  218. // SzGetSearchTokens
  219. // =================================================================================
  220. LPTSTR SzGetSearchTokens(LPTSTR pszCriteria)
  221. {
  222. // Locals
  223. ULONG iCriteria=0,
  224. cbValueMax,
  225. cbTokens=0,
  226. cbValue,
  227. iSave;
  228. TCHAR chToken;
  229. LPTSTR pszValue=NULL,
  230. pszTokens=NULL;
  231. BOOL fTokenFound;
  232. // Get Length of criteria
  233. cbValueMax = lstrlen(pszCriteria) + 10;
  234. pszValue = SzStrAlloc(cbValueMax);
  235. if (!pszValue)
  236. goto exit;
  237. // Alloc tokens list
  238. pszTokens = SzStrAlloc(cbValueMax);
  239. if (!pszTokens)
  240. goto exit;
  241. // Parse pszCriteria into space separated strings
  242. while(1)
  243. {
  244. // Skip white space
  245. SkipWhitespace (pszCriteria, &iCriteria);
  246. // Save current position
  247. iSave = iCriteria;
  248. // Parse next token
  249. fTokenFound = FStringTok (pszCriteria, &iCriteria, (LPTSTR)"\" ", &chToken, pszValue, cbValueMax, TRUE);
  250. if (!fTokenFound)
  251. break;
  252. // Toke isn't a space ?
  253. if (chToken == _T('"'))
  254. {
  255. // If something was found before the ", then it is a token
  256. if (*pszValue)
  257. {
  258. cbValue = lstrlen(pszValue) + 1;
  259. Assert(cbTokens + cbValue <= cbValueMax);
  260. CopyMemory(pszTokens + cbTokens, pszValue, (int)min(cbValue,cbValueMax-cbTokens));
  261. cbTokens+=cbValue;
  262. }
  263. // Search for ending quote
  264. fTokenFound = FStringTok (pszCriteria, &iCriteria, (LPTSTR)"\"", &chToken, pszValue, cbValueMax, TRUE);
  265. // Done ?
  266. if (chToken == _T('\0'))
  267. {
  268. cbValue = lstrlen(pszValue) + 1;
  269. Assert(cbTokens + cbValue <= cbValueMax);
  270. CopyMemory(pszTokens + cbTokens, pszValue, (int)min(cbValue,cbValueMax-cbTokens));
  271. cbTokens+=cbValue;
  272. break;
  273. }
  274. else if (!fTokenFound || chToken != _T('\"'))
  275. {
  276. iCriteria = iSave + 1;
  277. continue;
  278. }
  279. }
  280. // Add value to token list
  281. cbValue = lstrlen(pszValue) + 1;
  282. Assert(cbTokens + cbValue <= cbValueMax);
  283. CopyMemory(pszTokens + cbTokens, pszValue, (int)min(cbValue,cbValueMax-cbTokens));
  284. cbTokens+=cbValue;
  285. // Done
  286. if (chToken == _T('\0'))
  287. break;
  288. }
  289. // Final NULL
  290. *(pszTokens + cbTokens) = _T('\0');
  291. exit:
  292. // Cleanup
  293. SafeMemFree(pszValue);
  294. // If no tokens, then free it
  295. if (cbTokens == 0)
  296. {
  297. SafeMemFree(pszTokens);
  298. }
  299. // Done
  300. return pszTokens;
  301. }
  302. // =================================================================================
  303. // ProcessNlsError
  304. // =================================================================================
  305. VOID ProcessNlsError (VOID)
  306. {
  307. switch (GetLastError ())
  308. {
  309. case ERROR_INSUFFICIENT_BUFFER:
  310. AssertSz (FALSE, "NLSAPI Error: ERROR_INSUFFICIENT_BUFFER");
  311. break;
  312. case ERROR_INVALID_FLAGS:
  313. AssertSz (FALSE, "NLSAPI Error: ERROR_INVALID_FLAGS");
  314. break;
  315. case ERROR_INVALID_PARAMETER:
  316. AssertSz (FALSE, "NLSAPI Error: ERROR_INVALID_PARAMETER");
  317. break;
  318. case ERROR_NO_UNICODE_TRANSLATION:
  319. AssertSz (FALSE, "NLSAPI Error: ERROR_NO_UNICODE_TRANSLATION");
  320. break;
  321. default:
  322. AssertSz (FALSE, "NLSAPI Error: <Un-resolved error>");
  323. break;
  324. }
  325. }
  326. #ifdef OLDSPOOLER
  327. // =================================================================================
  328. // SzGetLocalHostName
  329. // =================================================================================
  330. LPSTR SzGetLocalHostName (VOID)
  331. {
  332. // Locals
  333. static char s_szLocalHost[255] = {0};
  334. // Gets local host name from socket library
  335. if (*s_szLocalHost == 0)
  336. {
  337. if (gethostname (s_szLocalHost, sizeof (s_szLocalHost)) == SOCKET_ERROR)
  338. {
  339. // $REVIEW - What should i do if this fails ???
  340. Assert (FALSE);
  341. //DebugTrace ("gethostname failed: WSAGetLastError: %ld\n", WSAGetLastError ());
  342. StrCpyNA(s_szLocalHost, "LocalHost", ARRAYSIZE(s_szLocalHost));
  343. }
  344. }
  345. // Done
  346. return s_szLocalHost;
  347. }
  348. // ==========================================================================
  349. // StripIllegalHostChars
  350. // ==========================================================================
  351. VOID StripIllegalHostChars(LPSTR pszSrc, LPTSTR pszDst)
  352. {
  353. char ch;
  354. while (ch = *pszSrc++)
  355. {
  356. if (ch <= 32 || ch >= 127 || ch == '(' || ch == ')' ||
  357. ch == '<' || ch == '>' || ch == '@' || ch == ',' ||
  358. ch == ';' || ch == ':' || ch == '\\' || ch == '"' ||
  359. ch == '[' || ch == ']' || ch == '`' || ch == '\'')
  360. continue;
  361. *pszDst++ = ch;
  362. }
  363. *pszDst = 0;
  364. }
  365. // ==========================================================================
  366. // SzGetLocalHostNameForID
  367. // ==========================================================================
  368. LPSTR SzGetLocalHostNameForID (VOID)
  369. {
  370. // Locals
  371. static char s_szLocalHostId[255] = {0};
  372. // Gets local host name from socket library
  373. if (*s_szLocalHostId == 0)
  374. {
  375. // Get Host name
  376. LPSTR pszDst = s_szLocalHostId, pszSrc = SzGetLocalHostName();
  377. // Strip illegals
  378. StripIllegalHostChars(pszSrc, pszDst);
  379. // if we stripped out everything, then just copy in something
  380. if (*s_szLocalHostId == 0)
  381. StrCpyNA(s_szLocalHostId, "LocalHost", ARRAYSIZE(s_szLocalHostId));
  382. }
  383. return s_szLocalHostId;
  384. }
  385. // =================================================================================
  386. // SzGetLocalPackedIP
  387. // =================================================================================
  388. LPTSTR SzGetLocalPackedIP (VOID)
  389. {
  390. // Locals
  391. static TCHAR s_szLocalPackedIP[255] = {_T('\0')};
  392. // Gets local host name from socket library
  393. if (*s_szLocalPackedIP == _T('\0'))
  394. {
  395. LPHOSTENT hp = NULL;
  396. hp = gethostbyname (SzGetLocalHostName ());
  397. if (hp != NULL)
  398. wnsprintf(s_szLocalPackedIP, ARRAYSIZE(s_szLocalPackedIP), "%08x", *(long *)hp->h_addr);
  399. else
  400. {
  401. // $REVIEW - What should i do if this fails ???
  402. Assert (FALSE);
  403. //DebugTrace ("gethostbyname failed: WSAGetLastError: %ld\n", WSAGetLastError ());
  404. StrCpyN(s_szLocalPackedIP, "LocalHost", ARRAYSIZE(s_szLocalPackedIP));
  405. }
  406. }
  407. // Done
  408. return s_szLocalPackedIP;
  409. }
  410. #endif
  411. // =============================================================================================
  412. // SzGetNormalizedSubject
  413. // =============================================================================================
  414. LPTSTR SzNormalizeSubject (LPTSTR lpszSubject)
  415. {
  416. // Locals
  417. LPTSTR lpszNormal = lpszSubject;
  418. ULONG i = 0, cch = 0, cbSubject;
  419. // Bad Params
  420. if (lpszSubject == NULL)
  421. goto exit;
  422. // Les than 5 "xxx: "
  423. cbSubject = lstrlen (lpszSubject);
  424. if (cbSubject < 4)
  425. goto exit;
  426. // 1, 2, or 3 spaces followed by a ':' then a space
  427. while (cch < 7 && i < cbSubject)
  428. {
  429. // Colon
  430. if (lpszSubject[i] == _T(':'))
  431. {
  432. if (i+1 >= cbSubject)
  433. {
  434. // Should set to null terminator, nor subject
  435. i+=1;
  436. lpszNormal = (LPTSTR)(lpszSubject + i);
  437. break;
  438. }
  439. else if (cch <= 4 && lpszSubject[i+1] == _T(' '))
  440. {
  441. i+=1;
  442. lpszNormal = (LPTSTR)(lpszSubject + i);
  443. i = 0;
  444. SkipWhitespace (lpszNormal, &i);
  445. lpszNormal += i;
  446. break;
  447. }
  448. else
  449. break;
  450. }
  451. // Next Character
  452. if (IsDBCSLeadByte (lpszSubject[i]))
  453. i+=2;
  454. else
  455. i++;
  456. // Count Characters
  457. cch++;
  458. }
  459. exit:
  460. // Done
  461. return lpszNormal;
  462. }
  463. // =============================================================================================
  464. // HrCopyAlloc
  465. // =============================================================================================
  466. HRESULT HrCopyAlloc (LPBYTE *lppbDest, LPBYTE lpbSrc, ULONG cb)
  467. {
  468. // Check Params
  469. AssertSz (lppbDest && lpbSrc, "Null Parameter");
  470. // Alloc Memory
  471. if (!MemAlloc ((LPVOID *)lppbDest, cb))
  472. return TRAPHR (hrMemory);
  473. // Copy Memory
  474. CopyMemory (*lppbDest, lpbSrc, cb);
  475. // Done
  476. return S_OK;
  477. }
  478. // =============================================================================================
  479. // StringDup - duplicates a string
  480. // =============================================================================================
  481. LPTSTR StringDup (LPCTSTR lpcsz)
  482. {
  483. // Locals
  484. LPTSTR lpszDup;
  485. if (lpcsz == NULL)
  486. return NULL;
  487. INT nLen = lstrlen (lpcsz) + 1;
  488. if (!MemAlloc ((LPVOID *)&lpszDup, nLen * sizeof (TCHAR)))
  489. return NULL;
  490. CopyMemory (lpszDup, lpcsz, nLen * sizeof (TCHAR));
  491. return lpszDup;
  492. }
  493. // =============================================================================================
  494. // SkipWhitespace
  495. // Assumes piString points to character boundary
  496. // =============================================================================================
  497. void SkipWhitespace (LPCTSTR lpcsz, ULONG *pi)
  498. {
  499. if (!lpcsz || !pi)
  500. {
  501. Assert (FALSE);
  502. return;
  503. }
  504. #ifdef DEBUG
  505. Assert (*pi <= (ULONG)lstrlen (lpcsz)+1);
  506. #endif
  507. LPTSTR lpsz = (LPTSTR)(lpcsz + *pi);
  508. while (*lpsz != _T('\0'))
  509. {
  510. if (!IsSpace(lpsz))
  511. break;
  512. if (IsDBCSLeadByte (*lpsz))
  513. {
  514. lpsz+=2;
  515. (*pi)+=2;
  516. }
  517. else
  518. {
  519. lpsz++;
  520. (*pi)+=1;
  521. }
  522. }
  523. return;
  524. }
  525. // =============================================================================================
  526. // Converts lpcsz to a UINT
  527. // =============================================================================================
  528. UINT AthUFromSz(LPCTSTR lpcsz)
  529. {
  530. // Locals
  531. UINT u = 0, ch;
  532. // Check Params
  533. AssertSz (lpcsz, "Null parameter");
  534. // Do Loop
  535. LPTSTR lpsz = (LPTSTR)lpcsz;
  536. while ((ch = *lpsz) >= _T('0') && ch <= _T('9'))
  537. {
  538. u = u * 10 + ch - _T('0');
  539. if (IsDBCSLeadByte (*lpsz))
  540. lpsz+=2;
  541. else
  542. lpsz++;
  543. }
  544. return u;
  545. }
  546. // =============================================================================================
  547. // Converts first two characters of lpcsz to a WORD
  548. // =============================================================================================
  549. WORD NFromSz (LPCTSTR lpcsz)
  550. {
  551. TCHAR acWordStr[3];
  552. Assert (lpcsz);
  553. CopyMemory (acWordStr, lpcsz, 2 * sizeof (TCHAR));
  554. acWordStr[2] = _T('\0');
  555. return ((WORD) AthUFromSz (acWordStr));
  556. }
  557. // =============================================================================================
  558. // FindChar
  559. // =============================================================================================
  560. LPTSTR SzFindChar (LPCTSTR lpcsz, TCHAR ch)
  561. {
  562. // Check Params
  563. Assert (lpcsz);
  564. // Local loop
  565. LPTSTR lpsz = (LPTSTR)lpcsz;
  566. // Loop string
  567. while (*lpsz != _T('\0'))
  568. {
  569. if (*lpsz == ch)
  570. return lpsz;
  571. if (IsDBCSLeadByte (*lpsz))
  572. lpsz+=2;
  573. else
  574. lpsz++;
  575. }
  576. return NULL;
  577. }
  578. #ifdef DEAD
  579. // =============================================================================================
  580. // UlDBCSStripTrailingWhitespace
  581. // =============================================================================================
  582. ULONG UlDBCSStripWhitespace(LPSTR lpsz, BOOL fLeading, BOOL fTrailing, ULONG *pcb)
  583. {
  584. // Locals
  585. ULONG cb=0,
  586. iLastSpace=0,
  587. cCharsSinceSpace=0;
  588. BOOL fLastCharSpace = FALSE;
  589. // Get the string length
  590. while (*lpsz)
  591. {
  592. if (cCharsSinceSpace && IsSpace(lpsz))
  593. {
  594. cCharsSinceSpace=0;
  595. iLastSpace=cb;
  596. }
  597. else
  598. cCharsSinceSpace++;
  599. if (IsDBCSLeadByte(*lpsz))
  600. {
  601. lpsz+=2;
  602. cb+=2;
  603. }
  604. else
  605. {
  606. lpsz++;
  607. cb++;
  608. }
  609. }
  610. if (cCharsSinceSpace == 0)
  611. {
  612. *(lpsz + iLastSpace) = _T('\0');
  613. cb = iLastSpace - 1;
  614. }
  615. // Set String Size
  616. if (pcb)
  617. *pcb = cb;
  618. // Done
  619. return cb;
  620. }
  621. #endif // DEAD
  622. // =============================================================================================
  623. // StringTok - similiar to strtok
  624. // =============================================================================================
  625. BOOL FStringTok (LPCTSTR lpcszString,
  626. ULONG *piString,
  627. LPTSTR lpcszTokens,
  628. TCHAR *chToken,
  629. LPTSTR lpszValue,
  630. ULONG cbValueMax,
  631. BOOL fStripTrailingWhitespace)
  632. {
  633. // Locals
  634. LPTSTR lpszStringLoop,
  635. lpszTokenLoop;
  636. ULONG cbValue=0,
  637. nLen=0,
  638. cCharsSinceSpace=0,
  639. iLastSpace=0;
  640. BOOL fTokenFound = FALSE;
  641. // Check Params
  642. AssertSz (lpcszString && piString && lpcszTokens, "These should have been checked.");
  643. // INit = better be on a dbcs boundary
  644. lpszStringLoop = (LPTSTR)(lpcszString + (*piString));
  645. // Loop current
  646. while (*lpszStringLoop)
  647. {
  648. // If DBCS Lead Byte, skip it, it will never match the type of tokens I'm looking for
  649. // Or, If an escape character, don't check delimiters
  650. if (IsDBCSLeadByte(*lpszStringLoop) || *lpszStringLoop == _T('\\'))
  651. {
  652. cCharsSinceSpace+=2;
  653. lpszStringLoop+=2;
  654. cbValue+=2;
  655. continue;
  656. }
  657. // Mark and remember last space
  658. if (cCharsSinceSpace && IsSpace(lpszStringLoop))
  659. {
  660. cCharsSinceSpace=0;
  661. iLastSpace=cbValue;
  662. }
  663. // Count number of characters since last space
  664. else
  665. cCharsSinceSpace++;
  666. // Look for a tokens
  667. lpszTokenLoop=lpcszTokens;
  668. while(*lpszTokenLoop)
  669. {
  670. // Token Match ?
  671. if (*lpszStringLoop == *lpszTokenLoop)
  672. {
  673. // Save the found token
  674. if (chToken)
  675. *chToken = *lpszStringLoop;
  676. // Don't count this character as a charcter seen since last space
  677. cCharsSinceSpace--;
  678. // Were done
  679. fTokenFound = TRUE;
  680. goto done;
  681. }
  682. // Next Token
  683. lpszTokenLoop++;
  684. }
  685. // Next Char
  686. lpszStringLoop++;
  687. cbValue++;
  688. }
  689. done:
  690. // If reached end of string, this is a default token
  691. if (*lpszStringLoop == _T('\0'))
  692. {
  693. if (chToken)
  694. *chToken = *lpszStringLoop;
  695. fTokenFound = TRUE;
  696. }
  697. // Copy value if token found
  698. if (fTokenFound)
  699. {
  700. if (lpszValue && cbValueMax > 0 && cbValue)
  701. {
  702. if (cbValue+1 <= cbValueMax)
  703. {
  704. StrCpyN (lpszValue, lpcszString + (*piString), cbValue+1);
  705. nLen = cbValue-1;
  706. }
  707. else
  708. {
  709. AssertSz (FALSE, "Buffer is too small.");
  710. StrCpyN (lpszValue, lpcszString + (*piString), cbValueMax);
  711. nLen = cbValueMax-1;
  712. }
  713. // Strip Trailing Whitespace ?
  714. if (fStripTrailingWhitespace && cCharsSinceSpace == 0)
  715. {
  716. *(lpszValue + iLastSpace) = _T('\0');
  717. nLen = iLastSpace - 1;
  718. }
  719. }
  720. // No Text
  721. else
  722. {
  723. if (lpszValue)
  724. *lpszValue = _T('\0');
  725. nLen = 0;
  726. cbValue = 0;
  727. }
  728. // Set new string index
  729. *piString += cbValue + 1;
  730. }
  731. // Return whether we found a token
  732. return fTokenFound;
  733. }
  734. // =============================================================================================
  735. // Return TRUE if string is empty or contains only spaces
  736. // =============================================================================================
  737. BOOL FIsStringEmpty (LPTSTR lpszString)
  738. {
  739. // Bad Pointer
  740. if (!lpszString)
  741. return TRUE;
  742. // Check for All spaces
  743. for (; *lpszString != _T('\0'); lpszString++)
  744. {
  745. if (*lpszString != _T(' '))
  746. return FALSE;
  747. }
  748. // Done
  749. return TRUE;
  750. }
  751. BOOL FIsStringEmptyW(LPWSTR lpwszString)
  752. {
  753. // Bad Pointer
  754. if (!lpwszString)
  755. return TRUE;
  756. // Check for All spaces
  757. for (; *lpwszString != L'\0'; lpwszString++)
  758. {
  759. if (*lpwszString != L' ')
  760. return FALSE;
  761. }
  762. // Done
  763. return TRUE;
  764. }
  765. // =================================================================================
  766. // Write some data to the blob
  767. // =================================================================================
  768. HRESULT HrBlobWriteData (LPBYTE lpbBlob, ULONG cbBlob, ULONG *pib, LPBYTE lpbData, ULONG cbData)
  769. {
  770. // Check Parameters
  771. AssertSz (lpbBlob && cbBlob > 0 && pib && cbData > 0 && lpbData, "Bad Parameter");
  772. AssertReadWritePtr (lpbBlob, cbData);
  773. AssertReadWritePtr (lpbData, cbData);
  774. AssertSz (*pib + cbData <= cbBlob, "Blob overflow");
  775. // Copy Data Data
  776. CopyMemory (lpbBlob + (*pib), lpbData, (int)min(cbData, cbBlob-(*pib)));
  777. *pib += cbData;
  778. // Done
  779. return S_OK;
  780. }
  781. // =================================================================================
  782. // Read some data from the blob
  783. // =================================================================================
  784. HRESULT HrBlobReadData (LPBYTE lpbBlob, ULONG cbBlob, ULONG *pib, LPBYTE lpbData, ULONG cbData)
  785. {
  786. // Check Parameters
  787. AssertSz (lpbBlob && cbBlob > 0 && pib && cbData > 0 && lpbData, "Bad Parameter");
  788. AssertReadWritePtr (lpbBlob, cbData);
  789. AssertReadWritePtr (lpbData, cbData);
  790. AssertSz (*pib + cbData <= cbBlob, "Blob overflow");
  791. #ifdef WIN16 // When it happens it cause GPF in Win16, so rather than GPF, remove it from entry.
  792. if ( *pib + cbData > cbBlob )
  793. return E_FAIL;
  794. #endif
  795. // Copy Data Data
  796. CopyMemory (lpbData, lpbBlob + (*pib), cbData);
  797. *pib += cbData;
  798. // Done
  799. return S_OK;
  800. }
  801. // =====================================================================================
  802. // HrFixupHostString - In: saranac.microsoft.com Out: saranac
  803. // =====================================================================================
  804. HRESULT HrFixupHostString (LPTSTR lpszHost)
  805. {
  806. ULONG i = 0;
  807. TCHAR chToken;
  808. if (lpszHost == NULL)
  809. return S_OK;
  810. if (FStringTok (lpszHost, &i, _T("."), &chToken, NULL, 0, FALSE))
  811. {
  812. if (chToken != _T('\0'))
  813. lpszHost[i-1] = _T('\0');
  814. }
  815. return S_OK;
  816. }
  817. // =====================================================================================
  818. // HrFixupAccountString - In: [email protected] Out: sbailey
  819. // =====================================================================================
  820. HRESULT HrFixupAccountString (LPTSTR lpszAccount)
  821. {
  822. ULONG i = 0;
  823. TCHAR chToken;
  824. if (lpszAccount == NULL)
  825. return S_OK;
  826. if (FStringTok (lpszAccount, &i, _T("@"), &chToken, NULL, 0, FALSE))
  827. {
  828. if (chToken != _T('\0'))
  829. lpszAccount[i-1] = _T('\0');
  830. }
  831. return S_OK;
  832. }
  833. // =====================================================================================
  834. // HGetMenuFont
  835. // =====================================================================================
  836. HFONT HGetMenuFont (void)
  837. {
  838. #ifndef WIN16
  839. // Locals
  840. NONCLIENTMETRICS ncm;
  841. HFONT hFont = NULL;
  842. // Create the menu font
  843. ncm.cbSize = sizeof(NONCLIENTMETRICS);
  844. if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, (LPVOID)&ncm, 0))
  845. {
  846. // Create Font
  847. hFont = CreateFontIndirect(&ncm.lfMenuFont);
  848. }
  849. // Done
  850. return hFont;
  851. #else
  852. LOGFONT lfMenu;
  853. GetObject( GetStockObject( SYSTEM_FONT ), sizeof( lfMenu ), &lfMenu );
  854. return( CreateFontIndirect( &lfMenu ) );
  855. #endif
  856. }
  857. // =================================================================================
  858. // CreateHGlobalFromStream
  859. // =================================================================================
  860. BOOL CreateHGlobalFromStream(LPSTREAM pstm, HGLOBAL * phg)
  861. {
  862. HGLOBAL hret = NULL;
  863. HGLOBAL hret2;
  864. LPBYTE lpb;
  865. ULONG cbRead = 0, cbSize = 1024;
  866. if (!pstm || !phg)
  867. return FALSE;
  868. if (!(hret = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, cbSize)))
  869. return FALSE;
  870. while (TRUE)
  871. {
  872. ULONG cb;
  873. lpb = (LPBYTE)GlobalLock(hret);
  874. lpb += cbRead;
  875. if (pstm->Read((LPVOID)lpb, 1024, &cb) != S_OK || cb < 1024)
  876. {
  877. cbRead += cb;
  878. GlobalUnlock(hret);
  879. break;
  880. }
  881. cbRead += cb;
  882. cbSize += 1024;
  883. GlobalUnlock(hret);
  884. hret2 = GlobalReAlloc(hret, cbSize, GMEM_MOVEABLE|GMEM_ZEROINIT);
  885. if (!hret2)
  886. return FALSE;
  887. hret = hret2;
  888. }
  889. if (hret)
  890. {
  891. hret2 = GlobalReAlloc(hret, cbRead, GMEM_MOVEABLE|GMEM_ZEROINIT);
  892. *phg = hret2;
  893. return TRUE;
  894. }
  895. return FALSE;
  896. }
  897. // =================================================================================
  898. // HrDetailedError
  899. // =================================================================================
  900. VOID DetailedError (HWND hwndParent, LPDETERR lpDetErr)
  901. {
  902. // Check params
  903. AssertSz (lpDetErr, "Null Parameter");
  904. Assert (lpDetErr->lpszMessage && lpDetErr->lpszDetails);
  905. // Beep
  906. MessageBeep (MB_OK);
  907. // Display Dialog Box
  908. DialogBoxParam (g_hLocRes, MAKEINTRESOURCE (iddDetailedError), hwndParent, DetailedErrorDlgProc, (LPARAM)lpDetErr);
  909. // Done
  910. return;
  911. }
  912. // =====================================================================================
  913. // PasswordDlgProc
  914. // =====================================================================================
  915. INT_PTR CALLBACK DetailedErrorDlgProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  916. {
  917. switch (uMsg)
  918. {
  919. HANDLE_MSG (hwndDlg, WM_INITDIALOG, DetailedErrorDlgProc_OnInitDialog);
  920. HANDLE_MSG (hwndDlg, WM_COMMAND, DetailedErrorDlgProc_OnCommand);
  921. }
  922. return 0;
  923. }
  924. // =====================================================================================
  925. // DetailedErrorDlgProc_OnInitDialog
  926. // =====================================================================================
  927. BOOL DetailedErrorDlgProc_OnInitDialog (HWND hwndDlg, HWND hwndFocus, LPARAM lParam)
  928. {
  929. // Locals
  930. LPDETERR lpDetErr = NULL;
  931. TCHAR szTitle[255];
  932. RECT rcDetails;
  933. ULONG cyDetails;
  934. TCHAR szButton[40];
  935. // Center
  936. CenterDialog (hwndDlg);
  937. // Foreground
  938. SetForegroundWindow (hwndDlg);
  939. // Get Pass info struct
  940. lpDetErr = (LPDETERR)lParam;
  941. if (lpDetErr == NULL)
  942. {
  943. Assert (FALSE);
  944. return 0;
  945. }
  946. SetDlgThisPtr (hwndDlg, lpDetErr);
  947. // Set Window Title
  948. if (lpDetErr->idsTitle)
  949. if (AthLoadString (lpDetErr->idsTitle, szTitle, sizeof (szTitle)))
  950. SetWindowText (hwndDlg, szTitle);
  951. // Show message
  952. SetWindowText (GetDlgItem (hwndDlg, idcMessage), lpDetErr->lpszMessage);
  953. if (FIsStringEmpty (lpDetErr->lpszDetails) == FALSE)
  954. SetWindowText (GetDlgItem (hwndDlg, ideDetails), lpDetErr->lpszDetails);
  955. else
  956. ShowWindow (GetDlgItem (hwndDlg, idbDetails), SW_HIDE);
  957. // Save Original Size of the dialog
  958. GetWindowRect (hwndDlg, &lpDetErr->rc);
  959. // Hide Details box
  960. if (lpDetErr->fHideDetails)
  961. {
  962. // Size of details
  963. GetWindowRect (GetDlgItem (hwndDlg, idcSplit), &rcDetails);
  964. // Height of details
  965. cyDetails = lpDetErr->rc.bottom - rcDetails.top;
  966. // Re-size
  967. MoveWindow (hwndDlg, lpDetErr->rc.left,
  968. lpDetErr->rc.top,
  969. lpDetErr->rc.right - lpDetErr->rc.left,
  970. lpDetErr->rc.bottom - lpDetErr->rc.top - cyDetails - 1,
  971. FALSE);
  972. }
  973. else
  974. {
  975. // < Details
  976. AthLoadString (idsHideDetails, szButton, ARRAYSIZE (szButton));
  977. SetWindowText (GetDlgItem (hwndDlg, idbDetails), szButton);
  978. }
  979. // Done
  980. return FALSE;
  981. }
  982. // =====================================================================================
  983. // OnCommand
  984. // =====================================================================================
  985. void DetailedErrorDlgProc_OnCommand (HWND hwndDlg, int id, HWND hwndCtl, UINT codeNotify)
  986. {
  987. switch (id)
  988. {
  989. HANDLE_COMMAND(hwndDlg, idbDetails, hwndCtl, codeNotify, DetailedErrorDlgProc_OnDetails);
  990. HANDLE_COMMAND(hwndDlg, IDOK, hwndCtl, codeNotify, DetailedErrorDlgProc_OnOk);
  991. HANDLE_COMMAND(hwndDlg, IDCANCEL, hwndCtl, codeNotify, DetailedErrorDlgProc_OnCancel);
  992. }
  993. return;
  994. }
  995. // =====================================================================================
  996. // OnCancel
  997. // =====================================================================================
  998. void DetailedErrorDlgProc_OnCancel (HWND hwndDlg, HWND hwndCtl, UINT uNotifyCode)
  999. {
  1000. EndDialog (hwndDlg, IDCANCEL);
  1001. }
  1002. // =====================================================================================
  1003. // OnOk
  1004. // =====================================================================================
  1005. void DetailedErrorDlgProc_OnOk (HWND hwndDlg, HWND hwndCtl, UINT uNotifyCode)
  1006. {
  1007. EndDialog (hwndDlg, IDOK);
  1008. }
  1009. // =====================================================================================
  1010. // OnDetails
  1011. // =====================================================================================
  1012. void DetailedErrorDlgProc_OnDetails (HWND hwndDlg, HWND hwndCtl, UINT uNotifyCode)
  1013. {
  1014. // Locals
  1015. LPDETERR lpDetErr = NULL;
  1016. RECT rcDlg, rcDetails;
  1017. TCHAR szButton[40];
  1018. ULONG cyDetails;
  1019. // Get this
  1020. lpDetErr = (LPDETERR)GetDlgThisPtr (hwndDlg);
  1021. if (lpDetErr == NULL)
  1022. {
  1023. Assert (FALSE);
  1024. return;
  1025. }
  1026. // Get current location of the dialog
  1027. GetWindowRect (hwndDlg, &rcDlg);
  1028. // If currently hidden
  1029. if (lpDetErr->fHideDetails)
  1030. {
  1031. // Re-size
  1032. MoveWindow (hwndDlg, rcDlg.left,
  1033. rcDlg.top,
  1034. lpDetErr->rc.right - lpDetErr->rc.left,
  1035. lpDetErr->rc.bottom - lpDetErr->rc.top,
  1036. TRUE);
  1037. // < Details
  1038. AthLoadString (idsHideDetails, szButton, sizeof (szButton));
  1039. SetWindowText (GetDlgItem (hwndDlg, idbDetails), szButton);
  1040. // Not Hidden
  1041. lpDetErr->fHideDetails = FALSE;
  1042. }
  1043. else
  1044. {
  1045. // Size of details
  1046. GetWindowRect (GetDlgItem (hwndDlg, idcSplit), &rcDetails);
  1047. // Height of details
  1048. cyDetails = rcDlg.bottom - rcDetails.top;
  1049. // Re-size
  1050. MoveWindow (hwndDlg, rcDlg.left,
  1051. rcDlg.top,
  1052. lpDetErr->rc.right - lpDetErr->rc.left,
  1053. lpDetErr->rc.bottom - lpDetErr->rc.top - cyDetails - 1,
  1054. TRUE);
  1055. // Details >
  1056. AthLoadString (idsShowDetails, szButton, sizeof (szButton));
  1057. SetWindowText (GetDlgItem (hwndDlg, idbDetails), szButton);
  1058. // Hidden
  1059. lpDetErr->fHideDetails = TRUE;
  1060. }
  1061. }
  1062. // =====================================================================================
  1063. // FIsLeapYear
  1064. // =====================================================================================
  1065. BOOL FIsLeapYear (INT nYear)
  1066. {
  1067. if (nYear % 4 == 0)
  1068. {
  1069. if ((nYear % 100) == 0 && (nYear % 400) != 0)
  1070. return FALSE;
  1071. else
  1072. return TRUE;
  1073. }
  1074. return FALSE;
  1075. }
  1076. #ifdef DEBUG
  1077. VOID TestDateDiff (VOID)
  1078. {
  1079. SYSTEMTIME st;
  1080. FILETIME ft1, ft2;
  1081. GetSystemTime (&st);
  1082. SystemTimeToFileTime (&st, &ft2);
  1083. st.wDay+=3;
  1084. SystemTimeToFileTime (&st, &ft1);
  1085. UlDateDiff (&ft1, &ft2);
  1086. }
  1087. #endif
  1088. // =====================================================================================
  1089. // Returns number of seconds between lpft1 and lpft2
  1090. // A leap year is defined as all years divisible by 4, except for years
  1091. // divisible by 100 that are not also divisible by 400. Years divisible by 400
  1092. // are leap years. 2000 is a leap year. 1900 is not a leap year.
  1093. // =====================================================================================
  1094. #define MAKEDWORDLONG(a, b) ((DWORDLONG)(((DWORD)(a)) | ((DWORDLONG)((DWORD)(b))) << 32))
  1095. #define LODWORD(l) ((DWORD)(l))
  1096. #define HIDWORD(l) ((DWORD)(((DWORDLONG)(l) >> 32) & 0xFFFFFFFF))
  1097. #define NANOSECONDS_INA_SECOND 10000000
  1098. ULONG UlDateDiff (LPFILETIME lpft1, LPFILETIME lpft2)
  1099. {
  1100. DWORDLONG dwl1, dwl2, dwlDiff;
  1101. #ifndef WIN16
  1102. dwl1 = MAKEDWORDLONG(lpft1->dwLowDateTime, lpft1->dwHighDateTime);
  1103. dwl2 = MAKEDWORDLONG(lpft2->dwLowDateTime, lpft2->dwHighDateTime);
  1104. #else
  1105. dwl1 = ((__int64)(((DWORD)(lpft1->dwLowDateTime)) | ((__int64)((DWORD)(lpft1->dwHighDateTime))) << 32));
  1106. dwl2 = ((__int64)(((DWORD)(lpft2->dwLowDateTime)) | ((__int64)((DWORD)(lpft2->dwHighDateTime))) << 32));
  1107. #endif
  1108. // Make sure dwl1 is greater than dwl2
  1109. if (dwl2 > dwl1)
  1110. {
  1111. dwlDiff = dwl1;
  1112. dwl1 = dwl2;
  1113. dwl2 = dwlDiff;
  1114. }
  1115. dwlDiff = dwl1 - dwl2;
  1116. dwlDiff = dwlDiff / NANOSECONDS_INA_SECOND;
  1117. return ((ULONG) dwlDiff);
  1118. }
  1119. // =====================================================================================
  1120. // StripSpaces
  1121. // =====================================================================================
  1122. VOID StripSpaces(LPTSTR psz)
  1123. {
  1124. UINT ib = 0;
  1125. UINT cb = lstrlen(psz);
  1126. TCHAR chT;
  1127. while (ib < cb)
  1128. {
  1129. // Get Character
  1130. chT = psz[ib];
  1131. // If lead byte, skip it, its leagal
  1132. if (IsDBCSLeadByte(chT))
  1133. ib+=2;
  1134. // Illeagl file name character ?
  1135. else if (chT == _T('\r') || chT == _T('\n') || chT == _T('\t') || chT == _T(' '))
  1136. {
  1137. MoveMemory (psz + ib, psz + (ib + 1), cb - ib);
  1138. cb--;
  1139. }
  1140. else
  1141. ib++;
  1142. }
  1143. }
  1144. // =====================================================================================
  1145. // CProgress::CProgress
  1146. // =====================================================================================
  1147. CProgress::CProgress ()
  1148. {
  1149. DOUT ("CProgress::CProgress");
  1150. m_cRef = 1;
  1151. m_cMax = 0;
  1152. m_cPerCur = 0;
  1153. m_cCur = 0;
  1154. m_hwndProgress = NULL;
  1155. m_hwndDlg = NULL;
  1156. m_hwndOwner = NULL;
  1157. m_hwndDisable = NULL;
  1158. m_fCanCancel = FALSE;
  1159. m_fHasCancel = FALSE;
  1160. m_cLast = 0;
  1161. }
  1162. // =====================================================================================
  1163. // CProgress::~CProgress
  1164. // =====================================================================================
  1165. CProgress::~CProgress ()
  1166. {
  1167. DOUT ("CProgress::~CProgress");
  1168. Close();
  1169. }
  1170. // =====================================================================================
  1171. // CProgress::AddRef
  1172. // =====================================================================================
  1173. ULONG CProgress::AddRef ()
  1174. {
  1175. ++m_cRef;
  1176. DOUT ("CProgress::AddRef () Ref Count=%d", m_cRef);
  1177. return m_cRef;
  1178. }
  1179. // =====================================================================================
  1180. // CProgress::AddRef
  1181. // =====================================================================================
  1182. ULONG CProgress::Release ()
  1183. {
  1184. ULONG ulCount = --m_cRef;
  1185. DOUT ("CProgress::Release () Ref Count=%d", ulCount);
  1186. if (!ulCount)
  1187. delete this;
  1188. return ulCount;
  1189. }
  1190. // =====================================================================================
  1191. // CProgress::Init
  1192. // =====================================================================================
  1193. VOID CProgress::Init (HWND hwndParent,
  1194. LPTSTR lpszTitle,
  1195. LPTSTR lpszMsg,
  1196. ULONG cMax,
  1197. UINT idani,
  1198. BOOL fCanCancel,
  1199. BOOL fBacktrackParent /* =TRUE */)
  1200. {
  1201. // Set Max and cur
  1202. m_cMax = cMax;
  1203. m_cPerCur = 0;
  1204. m_fCanCancel = fCanCancel;
  1205. m_fHasCancel = FALSE;
  1206. // If dialog is not displayed yet
  1207. if (m_hwndDlg == NULL)
  1208. {
  1209. // Save Parent
  1210. m_hwndOwner = hwndParent;
  1211. // Find the topmost parent
  1212. m_hwndDisable = m_hwndOwner;
  1213. if (fBacktrackParent)
  1214. {
  1215. while(GetParent(m_hwndDisable))
  1216. m_hwndDisable = GetParent(m_hwndDisable);
  1217. }
  1218. // Create Dialog
  1219. m_hwndDlg = CreateDialogParam (g_hLocRes, MAKEINTRESOURCE (iddProgress),
  1220. hwndParent, ProgressDlgProc, (LPARAM)this);
  1221. }
  1222. // Otherwise, reset
  1223. else
  1224. {
  1225. // Stop and close animation
  1226. Animate_Close (GetDlgItem (m_hwndDlg, idcANI));
  1227. // Reset pos
  1228. Assert (m_hwndProgress);
  1229. SendMessage (m_hwndProgress, PBM_SETPOS, 0, 0);
  1230. }
  1231. // Set title
  1232. SetTitle(lpszTitle);
  1233. // Set Message
  1234. SetMsg(lpszMsg);
  1235. // Animation ?
  1236. if (idani)
  1237. {
  1238. // Open the animation
  1239. Animate_OpenEx (GetDlgItem (m_hwndDlg, idcANI), g_hLocRes, MAKEINTRESOURCE(idani));
  1240. }
  1241. // No Cancel
  1242. if (FALSE == m_fCanCancel)
  1243. {
  1244. RECT rcDialog, rcProgress, rcCancel;
  1245. ShowWindow(GetDlgItem(m_hwndDlg, IDCANCEL), SW_HIDE);
  1246. GetWindowRect(GetDlgItem(m_hwndDlg, IDCANCEL), &rcCancel);
  1247. GetWindowRect(m_hwndDlg, &rcDialog);
  1248. GetWindowRect(m_hwndProgress, &rcProgress);
  1249. SetWindowPos(m_hwndProgress, NULL, 0, 0, rcDialog.right - rcProgress.left - (rcDialog.right - rcCancel.right),
  1250. rcProgress.bottom - rcProgress.top, SWP_NOZORDER | SWP_NOMOVE);
  1251. }
  1252. }
  1253. // =====================================================================================
  1254. // CProgress::Close
  1255. // =====================================================================================
  1256. VOID CProgress::Close (VOID)
  1257. {
  1258. // If we have a window
  1259. if (m_hwndDlg)
  1260. {
  1261. // Close the animation
  1262. Animate_Close (GetDlgItem (m_hwndDlg, idcANI));
  1263. // Enable parent
  1264. if (m_hwndDisable)
  1265. {
  1266. EnableWindow (m_hwndDisable, TRUE);
  1267. SetActiveWindow(m_hwndDisable);
  1268. }
  1269. // Destroy it
  1270. DestroyWindow (m_hwndDlg);
  1271. // NULL
  1272. m_hwndDlg = NULL;
  1273. }
  1274. }
  1275. // =====================================================================================
  1276. // CProgress::Show
  1277. // =====================================================================================
  1278. VOID CProgress::Show (DWORD dwDelaySeconds)
  1279. {
  1280. // If we have a window
  1281. if (m_hwndDlg)
  1282. {
  1283. // Disable Parent
  1284. if (m_hwndDisable)
  1285. EnableWindow (m_hwndDisable, FALSE);
  1286. // Start the animation
  1287. Animate_Play (GetDlgItem (m_hwndDlg, idcANI), 0, -1, -1);
  1288. // Show the window if now delay
  1289. if (dwDelaySeconds == 0)
  1290. ShowWindow (m_hwndDlg, SW_SHOWNORMAL);
  1291. else
  1292. SetTimer(m_hwndDlg, IDT_PROGRESS_DELAY, dwDelaySeconds * 1000, NULL);
  1293. }
  1294. }
  1295. // =====================================================================================
  1296. // CProgress::Hide
  1297. // =====================================================================================
  1298. VOID CProgress::Hide (VOID)
  1299. {
  1300. // If we have a window
  1301. if (m_hwndDlg)
  1302. {
  1303. if (m_hwndDisable)
  1304. EnableWindow(m_hwndDisable, TRUE);
  1305. // Hide it
  1306. ShowWindow (m_hwndDlg, SW_HIDE);
  1307. // Stop the animation
  1308. Animate_Stop (GetDlgItem (m_hwndDlg, idcANI));
  1309. }
  1310. }
  1311. // =====================================================================================
  1312. // CProgress::SetMsg
  1313. // =====================================================================================
  1314. VOID CProgress::SetMsg(LPTSTR lpszMsg)
  1315. {
  1316. TCHAR sz[CCHMAX_STRINGRES];
  1317. if (m_hwndDlg && lpszMsg)
  1318. {
  1319. if (IS_INTRESOURCE(lpszMsg))
  1320. {
  1321. LoadString(g_hLocRes, PtrToUlong(lpszMsg), sz, sizeof(sz) / sizeof(TCHAR));
  1322. lpszMsg = sz;
  1323. }
  1324. SetWindowText (GetDlgItem (m_hwndDlg, idsMsg), lpszMsg);
  1325. }
  1326. }
  1327. // =====================================================================================
  1328. // CProgress::SetTitle
  1329. // =====================================================================================
  1330. VOID CProgress::SetTitle(LPTSTR lpszTitle)
  1331. {
  1332. TCHAR sz[CCHMAX_STRINGRES];
  1333. if (m_hwndDlg && lpszTitle)
  1334. {
  1335. if (IS_INTRESOURCE(lpszTitle))
  1336. {
  1337. LoadString(g_hLocRes, PtrToUlong(lpszTitle), sz, sizeof(sz) / sizeof(TCHAR));
  1338. lpszTitle = sz;
  1339. }
  1340. SetWindowText (m_hwndDlg, lpszTitle);
  1341. }
  1342. }
  1343. // =====================================================================================
  1344. // CProgress::AdjustMax
  1345. // =====================================================================================
  1346. VOID CProgress::AdjustMax(ULONG cNewMax)
  1347. {
  1348. // Set Max
  1349. m_cMax = cNewMax;
  1350. // If 0
  1351. if (m_cMax == 0)
  1352. {
  1353. SendMessage (m_hwndProgress, PBM_SETPOS, 0, 0);
  1354. ShowWindow(m_hwndProgress, SW_HIDE);
  1355. return;
  1356. }
  1357. else
  1358. ShowWindow(m_hwndProgress, SW_SHOWNORMAL);
  1359. // If cur is now larget than max ?
  1360. if (m_cCur > m_cMax)
  1361. m_cCur = m_cMax;
  1362. // Compute percent
  1363. m_cPerCur = (m_cCur * 100 / m_cMax);
  1364. // Update status
  1365. SendMessage (m_hwndProgress, PBM_SETPOS, m_cPerCur, 0);
  1366. // msgpump to process user moving window, or pressing cancel... :)
  1367. MSG msg;
  1368. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  1369. {
  1370. TranslateMessage(&msg);
  1371. DispatchMessage(&msg);
  1372. }
  1373. }
  1374. VOID CProgress::Reset()
  1375. {
  1376. m_cCur = 0;
  1377. m_cPerCur = 0;
  1378. // Update status
  1379. SendMessage (m_hwndProgress, PBM_SETPOS, 0, 0);
  1380. }
  1381. // =====================================================================================
  1382. // CProgress::HrUpdate
  1383. // =====================================================================================
  1384. HRESULT CProgress::HrUpdate (ULONG cInc)
  1385. {
  1386. // No max
  1387. if (m_cMax)
  1388. {
  1389. // Increment m_cCur
  1390. m_cCur += cInc;
  1391. // If cur is now larget than max ?
  1392. if (m_cCur > m_cMax)
  1393. m_cCur = m_cMax;
  1394. // Compute percent
  1395. ULONG cPer = (m_cCur * 100 / m_cMax);
  1396. // Step percent
  1397. if (cPer > m_cPerCur)
  1398. {
  1399. // Set percur
  1400. m_cPerCur = cPer;
  1401. // Update status
  1402. SendMessage (m_hwndProgress, PBM_SETPOS, m_cPerCur, 0);
  1403. // msgpump to process user moving window, or pressing cancel... :)
  1404. MSG msg;
  1405. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  1406. {
  1407. TranslateMessage(&msg);
  1408. DispatchMessage(&msg);
  1409. }
  1410. }
  1411. }
  1412. // Still pump some messages, call may not want to do this too often
  1413. else
  1414. {
  1415. // msgpump to process user moving window, or pressing cancel... :)
  1416. MSG msg;
  1417. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  1418. {
  1419. TranslateMessage(&msg);
  1420. DispatchMessage(&msg);
  1421. }
  1422. }
  1423. // Done
  1424. return m_fHasCancel ? hrUserCancel : S_OK;
  1425. }
  1426. // =====================================================================================
  1427. // CProgress::ProgressDlgProc
  1428. // =====================================================================================
  1429. INT_PTR CALLBACK CProgress::ProgressDlgProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1430. {
  1431. // Locals
  1432. CProgress *lpProgress = (CProgress *)GetDlgThisPtr(hwnd);
  1433. switch (uMsg)
  1434. {
  1435. case WM_INITDIALOG:
  1436. lpProgress = (CProgress *)lParam;
  1437. if (!lpProgress)
  1438. {
  1439. Assert (FALSE);
  1440. return 1;
  1441. }
  1442. CenterDialog (hwnd);
  1443. lpProgress->m_hwndProgress = GetDlgItem (hwnd, idcProgBar);
  1444. if (lpProgress->m_cMax == 0)
  1445. ShowWindow(lpProgress->m_hwndProgress, SW_HIDE);
  1446. SetDlgThisPtr (hwnd, lpProgress);
  1447. return 1;
  1448. case WM_TIMER:
  1449. if (wParam == IDT_PROGRESS_DELAY)
  1450. {
  1451. KillTimer(hwnd, IDT_PROGRESS_DELAY);
  1452. if (lpProgress->m_cPerCur < 80)
  1453. {
  1454. lpProgress->m_cMax -= lpProgress->m_cCur;
  1455. lpProgress->Reset();
  1456. ShowWindow(hwnd, SW_SHOWNORMAL);
  1457. }
  1458. }
  1459. break;
  1460. case WM_COMMAND:
  1461. switch(GET_WM_COMMAND_ID(wParam,lParam))
  1462. {
  1463. case IDCANCEL:
  1464. if (lpProgress)
  1465. {
  1466. EnableWindow ((HWND)lParam, FALSE);
  1467. lpProgress->m_fHasCancel = TRUE;
  1468. }
  1469. return 1;
  1470. }
  1471. break;
  1472. case WM_DESTROY:
  1473. KillTimer(hwnd, IDT_PROGRESS_DELAY);
  1474. SetDlgThisPtr (hwnd, NULL);
  1475. break;
  1476. }
  1477. // Done
  1478. return 0;
  1479. }
  1480. // =====================================================================================
  1481. // ResizeDialogComboEx
  1482. // =====================================================================================
  1483. VOID ResizeDialogComboEx (HWND hwndDlg, HWND hwndCombo, UINT idcBase, HIMAGELIST himl)
  1484. {
  1485. // Locals
  1486. HDC hdc = NULL;
  1487. HFONT hFont = NULL,
  1488. hFontOld = NULL;
  1489. TEXTMETRIC tm;
  1490. RECT rectCombo;
  1491. INT cxCombo = 0,
  1492. cyCombo = 0,
  1493. cxIcon = 0,
  1494. cyIcon = 0,
  1495. cyText;
  1496. POINT pt;
  1497. // Get current font of combo box
  1498. hFont = (HFONT)SendMessage (GetDlgItem (hwndDlg, idcBase), WM_GETFONT, 0, 0);
  1499. if (hFont == NULL)
  1500. goto exit;
  1501. // Get a dc for the dialog
  1502. hdc = GetDC (hwndDlg);
  1503. if (hdc == NULL)
  1504. goto exit;
  1505. // Select font into dc
  1506. hFontOld = (HFONT)SelectObject (hdc, hFont);
  1507. // Get Text Metrics
  1508. GetTextMetrics (hdc, &tm);
  1509. // Comput sizeof combobox ex
  1510. GetWindowRect (hwndCombo, &rectCombo);
  1511. // Size of icon image
  1512. if (himl)
  1513. ImageList_GetIconSize (himl, &cxIcon, &cyIcon);
  1514. // Sizeof combo
  1515. cxCombo = rectCombo.right - rectCombo.left;
  1516. cyText = tm.tmHeight + tm.tmExternalLeading;
  1517. cyCombo = max (cyIcon, cyText);
  1518. // Add a little extra
  1519. cyCombo += ((int)min (15, ComboBox_GetCount(hwndCombo)) * cyText);
  1520. // Map upper left of combo
  1521. pt.x = rectCombo.left;
  1522. pt.y = rectCombo.top;
  1523. MapWindowPoints(NULL, hwndDlg, (LPPOINT)&rectCombo, 2);
  1524. MoveWindow (hwndCombo, rectCombo.left, rectCombo.top, cxCombo, cyCombo, FALSE);
  1525. exit:
  1526. // Cleanup
  1527. if (hdc)
  1528. {
  1529. // Select Old font
  1530. if (hFontOld)
  1531. SelectObject (hdc, hFontOld);
  1532. // Delete DC
  1533. ReleaseDC (hwndDlg, hdc);
  1534. }
  1535. // Done
  1536. return;
  1537. }