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.

1388 lines
42 KiB

  1. /*****************************************************************************\
  2. FILE: MailBox.cpp
  3. DESCRIPTION:
  4. This file implements the logic of the MailBox feature.
  5. BryanSt 2/26/2000
  6. Copyright (C) Microsoft Corp 2000-2000. All rights reserved.
  7. \*****************************************************************************/
  8. #include "priv.h"
  9. #include <atlbase.h> // USES_CONVERSION
  10. #include "util.h"
  11. #include "objctors.h"
  12. #include <comdef.h>
  13. #include <limits.h> // INT_MAX
  14. #include <commctrl.h> // Str_SetPtr
  15. #include "wizard.h"
  16. #include "MailBox.h"
  17. #include "emailassoc.h"
  18. #ifdef FEATURE_MAILBOX
  19. #define WM_AUTODISCOVERY_FINISHED (WM_USER + 1)
  20. // These are the wizard control IDs for the Back, Next, and Finished buttons.
  21. #define IDD_WIZARD_BACK_BUTTON 0x3023
  22. #define IDD_WIZARD_NEXT_BUTTON 0x3024
  23. #define IDD_WIZARD_FINISH_BUTTON 0x3025
  24. /**************************************************************************
  25. CLASS: CMailBoxProcess
  26. **************************************************************************/
  27. class CMailBoxProcess : public IUnknown
  28. {
  29. public:
  30. //IUnknown methods
  31. STDMETHODIMP QueryInterface(REFIID, LPVOID*);
  32. STDMETHODIMP_(DWORD) AddRef();
  33. STDMETHODIMP_(DWORD) Release();
  34. HRESULT ParseCmdLine(LPTSTR lpCmdLine);
  35. HRESULT Run(void);
  36. CMailBoxProcess();
  37. ~CMailBoxProcess();
  38. private:
  39. // Private Member Variables
  40. DWORD m_cRef;
  41. TCHAR m_szEmailAddress[MAX_EMAIL_ADDRESSS];
  42. TCHAR m_szNextText[MAX_PATH];
  43. BOOL m_fAutoDiscoveryFailed; // Did the AutoDiscovery process fail?
  44. LPTSTR m_pszMailApp; // Which app was chosen?
  45. LPTSTR m_pszURL; // Which URL should be used to read mail?
  46. HWND m_hwndDialog;
  47. HRESULT m_hr;
  48. IMailAutoDiscovery * m_pMailAutoDiscovery;
  49. BOOL m_fGetDefaultAccount; // If yes, open to wizard page asking for email address.
  50. BOOL m_fShowGetEmailAddressPage; // Do we want to show the get email address wizard page?
  51. BOOL m_fCreateNewEmailAccount; // Does the user want to create a new email account (like on one of the free email servers: hotmail, yahoo, etc.)
  52. // Private Member Functions
  53. HRESULT _DisplayDialogAndAutoDiscover(void);
  54. HRESULT _OpenWebBasedEmail(HKEY hkey);
  55. HRESULT _OpenExeBasedEmailApp(IN LPCWSTR pszMailApp);
  56. HRESULT _OpenProprietaryEmailApp(IN BSTR bstrProtocol, IN IMailProtocolADEntry * pMailProtocol);
  57. HRESULT _OpenEmailApp(void);
  58. HRESULT _RestoreNextButton(void);
  59. HRESULT _FillListWithApps(HWND hwndList);
  60. HRESULT _OnGetDispInfo(LV_DISPINFO * pDispInfo, bool fUnicode);
  61. HRESULT _OnChooseAppListFocus(void);
  62. HRESULT _OnChooseAppURLFocus(void);
  63. HRESULT _OnAppListSelection(LPNMLISTVIEW pListview);
  64. INT_PTR _MailBoxProgressDialogProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
  65. INT_PTR _ChooseAppDialogProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
  66. INT_PTR _GetEmailAddressDialogProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
  67. INT_PTR _OnInit(HWND hDlg);
  68. INT_PTR _OnInitChooseApp(HWND hDlg);
  69. INT_PTR _OnUserCancelled(void);
  70. INT_PTR _OnFinished(HRESULT hr, BSTR bstrXML);
  71. INT_PTR _OnGetEmailAddressNext(void);
  72. INT_PTR _OnCommand(WPARAM wParam, LPARAM lParam);
  73. INT_PTR _OnFinishedManualAssociate(void);
  74. friend INT_PTR CALLBACK MailBoxProgressDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  75. friend INT_PTR CALLBACK ChooseAppDialogProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
  76. friend INT_PTR CALLBACK GetEmailAddressDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  77. };
  78. typedef struct tagEMAILCLIENT
  79. {
  80. LPTSTR pszFriendlyName;
  81. LPTSTR pszPath;
  82. LPTSTR pszCmdLine;
  83. LPTSTR pszIconPath;
  84. LPTSTR pszEmailApp;
  85. } EMAILCLIENT;
  86. //===========================
  87. // *** Class Internals & Helpers ***
  88. //===========================
  89. BOOL IsWhitespace(TCHAR Char)
  90. {
  91. return ((Char == TEXT(' ')) || (Char == TEXT('\t')));
  92. }
  93. LPTSTR APIENTRY SkipWhite(LPTSTR pszString)
  94. {
  95. while (pszString[0] && IsWhitespace(pszString[0]))
  96. {
  97. pszString = CharNext(pszString);
  98. }
  99. return pszString;
  100. }
  101. BOOL IsFlagSpecified(IN LPCTSTR pwzFlag, IN LPCTSTR pszArg)
  102. {
  103. BOOL fIsFlagSpecified = FALSE;
  104. if ((TEXT('/') == pszArg[0]) ||
  105. (TEXT('-') == pszArg[0]))
  106. {
  107. if ((0 == StrCmpI(pwzFlag, &pszArg[1])) ||
  108. ((0 == StrCmpNI(pwzFlag, &pszArg[1], lstrlen(pwzFlag))) &&
  109. (IsWhitespace(pszArg[lstrlen(pwzFlag) + 1])) ) )
  110. {
  111. fIsFlagSpecified = TRUE;
  112. }
  113. }
  114. return fIsFlagSpecified;
  115. }
  116. LPTSTR GetNextArgument(LPTSTR pszCmdLine)
  117. {
  118. pszCmdLine = StrChr(pszCmdLine, TEXT(' '));
  119. if (pszCmdLine)
  120. {
  121. pszCmdLine = SkipWhite(pszCmdLine);
  122. }
  123. return pszCmdLine;
  124. }
  125. void FreeEmailClient(EMAILCLIENT * pEmailClient)
  126. {
  127. if (pEmailClient)
  128. {
  129. Str_SetPtr(&pEmailClient->pszFriendlyName, NULL);
  130. Str_SetPtr(&pEmailClient->pszPath, NULL);
  131. Str_SetPtr(&pEmailClient->pszCmdLine, NULL);
  132. Str_SetPtr(&pEmailClient->pszIconPath, NULL);
  133. Str_SetPtr(&pEmailClient->pszEmailApp, NULL);
  134. LocalFree(pEmailClient);
  135. }
  136. }
  137. HRESULT CMailBoxProcess::_DisplayDialogAndAutoDiscover(void)
  138. {
  139. HWND hwndParent = NULL; // Do we need a parent?
  140. ATOMICRELEASE(m_pMailAutoDiscovery);
  141. m_fShowGetEmailAddressPage = (m_szEmailAddress[0] ? FALSE : TRUE);
  142. DisplayMailBoxWizard((LPARAM)this, m_fShowGetEmailAddressPage);
  143. HRESULT hr = m_hr;
  144. if (SUCCEEDED(hr))
  145. {
  146. // Create account.
  147. hr = E_FAIL;
  148. long nSize;
  149. // Loop thru the list looking for the first instance of a protocol
  150. // that we support.
  151. if (m_pMailAutoDiscovery)
  152. {
  153. hr = m_pMailAutoDiscovery->get_length(&nSize);
  154. if (SUCCEEDED(hr))
  155. {
  156. VARIANT varIndex;
  157. IMailProtocolADEntry * pMailProtocol = NULL;
  158. hr = E_FAIL;
  159. varIndex.vt = VT_I4;
  160. for (long nIndex = 0; (nIndex < nSize); nIndex++)
  161. {
  162. varIndex.lVal = nIndex;
  163. if (SUCCEEDED(m_pMailAutoDiscovery->get_item(varIndex, &pMailProtocol)))
  164. {
  165. BSTR bstrProtocol;
  166. hr = pMailProtocol->get_Protocol(&bstrProtocol);
  167. if (SUCCEEDED(hr))
  168. {
  169. // Is this protocol one of the ones we support?
  170. if (!StrCmpIW(bstrProtocol, STR_PT_WEBBASED))
  171. {
  172. SysFreeString(bstrProtocol);
  173. hr = EmailAssoc_CreateWebAssociation(m_szEmailAddress, pMailProtocol);
  174. break;
  175. }
  176. // Is this protocol one of the ones we support?
  177. if (!StrCmpIW(bstrProtocol, STR_PT_POP) ||
  178. !StrCmpIW(bstrProtocol, STR_PT_IMAP) ||
  179. !StrCmpIW(bstrProtocol, STR_PT_DAVMAIL))
  180. {
  181. hr = EmailAssoc_CreateStandardsBaseAssociation(m_szEmailAddress, bstrProtocol);
  182. if (SUCCEEDED(hr))
  183. {
  184. SysFreeString(bstrProtocol);
  185. break;
  186. }
  187. }
  188. hr = _OpenProprietaryEmailApp(bstrProtocol, pMailProtocol);
  189. SysFreeString(bstrProtocol);
  190. if (SUCCEEDED(hr))
  191. {
  192. break;
  193. }
  194. }
  195. ATOMICRELEASE(pMailProtocol);
  196. }
  197. }
  198. ATOMICRELEASE(pMailProtocol);
  199. }
  200. }
  201. // We may have failed up until now because AutoDiscovery failed or was skipped,
  202. // but the user may have selected an app from the list.
  203. if (FAILED(hr))
  204. {
  205. if (m_pszMailApp)
  206. {
  207. HKEY hkey;
  208. hr = EmailAssoc_CreateEmailAccount(m_szEmailAddress, &hkey);
  209. if (SUCCEEDED(hr))
  210. {
  211. hr = EmailAssoc_SetEmailAccountPreferredApp(hkey, m_pszMailApp);
  212. RegCloseKey(hkey);
  213. }
  214. }
  215. else if (m_pszURL && m_pszURL[0])
  216. {
  217. HKEY hkey;
  218. hr = EmailAssoc_CreateEmailAccount(m_szEmailAddress, &hkey);
  219. if (SUCCEEDED(hr))
  220. {
  221. hr = EmailAssoc_SetEmailAccountProtocol(hkey, SZ_REGDATA_WEB);
  222. if (SUCCEEDED(hr))
  223. {
  224. hr = EmailAssoc_SetEmailAccountWebURL(hkey, m_pszURL);
  225. }
  226. RegCloseKey(hkey);
  227. }
  228. }
  229. }
  230. }
  231. return hr;
  232. }
  233. INT_PTR CALLBACK MailBoxProgressDialogProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  234. {
  235. CMailBoxProcess * pMBProgress = (CMailBoxProcess *)GetWindowLongPtr(hDlg, DWLP_USER);
  236. if (WM_INITDIALOG == wMsg)
  237. {
  238. PROPSHEETPAGE * pPropSheetPage = (PROPSHEETPAGE *) lParam;
  239. if (pPropSheetPage)
  240. {
  241. SetWindowLongPtr(hDlg, DWLP_USER, pPropSheetPage->lParam);
  242. pMBProgress = (CMailBoxProcess *)pPropSheetPage->lParam;
  243. }
  244. }
  245. if (pMBProgress)
  246. return pMBProgress->_MailBoxProgressDialogProc(hDlg, wMsg, wParam, lParam);
  247. return DefWindowProc(hDlg, wMsg, wParam, lParam);
  248. }
  249. INT_PTR CMailBoxProcess::_MailBoxProgressDialogProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  250. {
  251. INT_PTR fHandled = TRUE; // handled
  252. switch (wMsg)
  253. {
  254. case WM_INITDIALOG:
  255. fHandled = _OnInit(hDlg);
  256. break;
  257. case WM_AUTODISCOVERY_FINISHED:
  258. fHandled = _OnFinished((HRESULT)wParam, (BSTR)lParam);
  259. break;
  260. case WM_NOTIFY:
  261. {
  262. LPNMHDR pnmh = (LPNMHDR)lParam;
  263. switch (pnmh->code)
  264. {
  265. case LVN_GETDISPINFO:
  266. wMsg++;
  267. break;
  268. case PSN_SETACTIVE:
  269. PropSheet_SetWizButtons(GetParent(hDlg), ((TRUE == m_fShowGetEmailAddressPage) ? PSWIZB_NEXT | PSWIZB_BACK : PSWIZB_NEXT));
  270. fHandled = TRUE; // Return zero to accept the activation.
  271. break;
  272. case PSN_WIZBACK:
  273. fHandled = TRUE; // Return zero to allow the user to go to the next page.
  274. break;
  275. case PSN_WIZNEXT:
  276. m_hr = S_FALSE;
  277. _RestoreNextButton();
  278. fHandled = 0; // Return zero to allow the user to go to the next page.
  279. break;
  280. case PSN_QUERYCANCEL:
  281. _OnUserCancelled();
  282. fHandled = FALSE;
  283. break;
  284. default:
  285. //TraceMsg(TF_ALWAYS, "CMailBoxProcess::_MailBoxProgressDialogProc(wMsg = %d, pnmh->code = %d) WM_NOTIFY", wMsg, pnmh->code);
  286. break;
  287. }
  288. }
  289. default:
  290. //TraceMsg(TF_ALWAYS, "CMailBoxProcess::_MailBoxProgressDialogProc(wMsg = %d) WM_NOTIFY", wMsg);
  291. fHandled = FALSE; // Not handled
  292. break;
  293. }
  294. return fHandled;
  295. }
  296. INT_PTR CALLBACK ChooseAppDialogProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  297. {
  298. CMailBoxProcess * pMBProgress = (CMailBoxProcess *)GetWindowLongPtr(hDlg, DWLP_USER);
  299. if (WM_INITDIALOG == wMsg)
  300. {
  301. PROPSHEETPAGE * pPropSheetPage = (PROPSHEETPAGE *) lParam;
  302. if (pPropSheetPage)
  303. {
  304. SetWindowLongPtr(hDlg, DWLP_USER, pPropSheetPage->lParam);
  305. pMBProgress = (CMailBoxProcess *)pPropSheetPage->lParam;
  306. }
  307. }
  308. if (pMBProgress)
  309. return pMBProgress->_ChooseAppDialogProc(hDlg, wMsg, wParam, lParam);
  310. return DefWindowProc(hDlg, wMsg, wParam, lParam);
  311. }
  312. HRESULT CMailBoxProcess::_OnChooseAppURLFocus(void)
  313. {
  314. HWND hwndURLEditbox = GetDlgItem(m_hwndDialog, IDC_CHOOSEAPP_WEBURL_EDIT);
  315. // Something happened to cause to have us shift into the "Other:" case.
  316. CheckDlgButton(m_hwndDialog, IDC_CHOOSEAPP_WEB_RADIO, BST_CHECKED); // Uncheck the Web radio button
  317. CheckDlgButton(m_hwndDialog, IDC_CHOOSEAPP_OTHERAPP_RADIO, BST_UNCHECKED); // Uncheck the Web radio button
  318. SetFocus(hwndURLEditbox);
  319. return S_OK;
  320. }
  321. INT_PTR CMailBoxProcess::_OnFinishedManualAssociate(void)
  322. {
  323. // TODO: Only succeed the finished part if something is selected in the app list.
  324. // Also gray out the button.
  325. m_hr = S_OK;
  326. // Did the user manually configure via "Web" or an app?
  327. if (IsDlgButtonChecked(m_hwndDialog, IDC_CHOOSEAPP_WEB_RADIO))
  328. {
  329. // Web. So save the URL.
  330. TCHAR szURL[MAX_URL_STRING];
  331. GetWindowText(GetDlgItem(m_hwndDialog, IDC_CHOOSEAPP_WEBURL_EDIT), szURL, ARRAYSIZE(szURL));
  332. Str_SetPtr(&m_pszURL, szURL);
  333. Str_SetPtr(&m_pszMailApp, NULL);
  334. }
  335. return FALSE; // FALSE mean means allow it to close. TRUE means keep it open.
  336. }
  337. HRESULT CMailBoxProcess::_OnAppListSelection(LPNMLISTVIEW pListview)
  338. {
  339. LPTSTR pszNewApp = NULL; // None selected.
  340. // The user choose from the list. So store the name of the app
  341. if (pListview && (-1 != pListview->iItem))
  342. {
  343. HWND hwndList = GetDlgItem(m_hwndDialog, IDC_CHOOSEAPP_APPLIST);
  344. LVITEM pItem = {0};
  345. pItem.iItem = pListview->iItem;
  346. pItem.iSubItem = pListview->iSubItem;
  347. pItem.mask = LVIF_PARAM;
  348. if (ListView_GetItem(hwndList, &pItem))
  349. {
  350. EMAILCLIENT * pEmailClient = (EMAILCLIENT *) pItem.lParam;
  351. if (pEmailClient)
  352. {
  353. pszNewApp = pEmailClient->pszEmailApp;
  354. }
  355. }
  356. }
  357. Str_SetPtr(&m_pszMailApp, pszNewApp);
  358. return S_OK;
  359. }
  360. HRESULT CMailBoxProcess::_OnChooseAppListFocus(void)
  361. {
  362. HWND hwndAppList = GetDlgItem(m_hwndDialog, IDC_CHOOSEAPP_APPLIST);
  363. // Something happened to cause to have us shift into the "Other:" case.
  364. CheckDlgButton(m_hwndDialog, IDC_CHOOSEAPP_WEB_RADIO, BST_UNCHECKED); // Uncheck the Web radio button
  365. CheckDlgButton(m_hwndDialog, IDC_CHOOSEAPP_OTHERAPP_RADIO, BST_CHECKED); // Uncheck the Web radio button
  366. SetFocus(hwndAppList);
  367. return S_OK;
  368. }
  369. INT_PTR CMailBoxProcess::_ChooseAppDialogProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  370. {
  371. INT_PTR fHandled = TRUE; // handled
  372. switch (wMsg)
  373. {
  374. case WM_INITDIALOG:
  375. fHandled = _OnInitChooseApp(hDlg);
  376. PropSheet_SetWizButtons(GetParent(hDlg), ((TRUE == m_fShowGetEmailAddressPage) ? (PSWIZB_BACK | PSWIZB_FINISH) : PSWIZB_FINISH));
  377. break;
  378. case WM_COMMAND:
  379. fHandled = _OnCommand(wParam, lParam);
  380. break;
  381. case WM_NOTIFY:
  382. {
  383. LPNMHDR pnmh = (LPNMHDR)lParam;
  384. int idEvent = pnmh->code;
  385. switch (idEvent)
  386. {
  387. case LVN_GETDISPINFOA:
  388. _OnGetDispInfo((LV_DISPINFO *)lParam, false);
  389. break;
  390. case LVN_GETDISPINFOW:
  391. _OnGetDispInfo((LV_DISPINFO *)lParam, true);
  392. break;
  393. case LVN_DELETEITEM:
  394. if (lParam)
  395. {
  396. FreeEmailClient((EMAILCLIENT *) ((NM_LISTVIEW *)lParam)->lParam);
  397. }
  398. break;
  399. case LVN_ITEMCHANGED:
  400. _OnChooseAppListFocus();
  401. _OnAppListSelection((LPNMLISTVIEW) lParam); // Keep track of the last selected item.
  402. break;
  403. case LVN_ITEMACTIVATE:
  404. break;
  405. case PSN_SETACTIVE:
  406. PropSheet_SetWizButtons(GetParent(hDlg), (PSWIZB_BACK | PSWIZB_FINISH));
  407. fHandled = TRUE; // Return zero to accept the activation.
  408. break;
  409. case PSN_WIZBACK:
  410. // Set the prev. page to show
  411. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, (LONG_PTR) 0);
  412. fHandled = -1;
  413. break;
  414. case PSN_WIZFINISH:
  415. fHandled = _OnFinishedManualAssociate();
  416. break;
  417. case PSN_QUERYCANCEL:
  418. m_hr = HRESULT_FROM_WIN32(ERROR_CANCELLED);
  419. // TODO:
  420. fHandled = FALSE;
  421. break;
  422. default:
  423. //TraceMsg(TF_ALWAYS, "CMailBoxProcess::_ChooseAppDialogProc(wMsg = %d, pnmh->code = %d) WM_NOTIFY", wMsg, pnmh->code);
  424. break;
  425. }
  426. break;
  427. }
  428. default:
  429. fHandled = FALSE; // Not handled
  430. //TraceMsg(TF_ALWAYS, "CMailBoxProcess::_ChooseAppDialogProc(wMsg = %d)", wMsg);
  431. break;
  432. }
  433. return fHandled;
  434. }
  435. HRESULT CMailBoxProcess::_RestoreNextButton(void)
  436. {
  437. HWND hwndNextButton = GetDlgItem(GetParent(m_hwndDialog), IDD_WIZARD_NEXT_BUTTON);
  438. if (hwndNextButton && m_szNextText[0])
  439. {
  440. SetWindowText(hwndNextButton, m_szNextText);
  441. }
  442. return S_OK;
  443. }
  444. INT_PTR CMailBoxProcess::_OnInit(HWND hDlg)
  445. {
  446. BOOL fHandled = FALSE; // Not handled
  447. HWND hwndWizard = GetParent(hDlg);
  448. TCHAR szSkipButton[MAX_PATH];
  449. HWND hwndNextButton = GetDlgItem(GetParent(hDlg), IDD_WIZARD_NEXT_BUTTON);
  450. m_hwndDialog = hDlg;
  451. if (hwndNextButton &&
  452. GetWindowText(hwndNextButton, m_szNextText, ARRAYSIZE(m_szNextText)))
  453. {
  454. // First, change the "Next" button into "Skip"
  455. // Save the text on the next button before we rename it.
  456. LoadString(HINST_THISDLL, IDS_SKIP_BUTTON, szSkipButton, ARRAYSIZE(szSkipButton));
  457. // Set the next text.
  458. SetWindowText(hwndNextButton, szSkipButton);
  459. }
  460. // Set Animation.
  461. HWND hwndAnimation = GetDlgItem(hDlg, IDC_AUTODISCOVERY_ANIMATION);
  462. if (hwndAnimation)
  463. {
  464. Animate_OpenEx(hwndAnimation, HINST_THISDLL, IDA_DOWNLOADINGSETTINGS);
  465. }
  466. // Start the background task.
  467. m_hr = CMailAccountDiscovery_CreateInstance(NULL, IID_PPV_ARG(IMailAutoDiscovery, &m_pMailAutoDiscovery));
  468. if (SUCCEEDED(m_hr))
  469. {
  470. m_hr = m_pMailAutoDiscovery->WorkAsync(hDlg, WM_AUTODISCOVERY_FINISHED);
  471. if (SUCCEEDED(m_hr))
  472. {
  473. m_hr = m_pMailAutoDiscovery->DiscoverMail(m_szEmailAddress);
  474. }
  475. }
  476. if (FAILED(m_hr))
  477. {
  478. PropSheet_PressButton(GetParent(hDlg), PSBTN_NEXT);
  479. }
  480. return fHandled;
  481. }
  482. INT_PTR CMailBoxProcess::_OnCommand(WPARAM wParam, LPARAM lParam)
  483. {
  484. BOOL fHandled = 1; // Not handled (WM_COMMAND seems to be different)
  485. WORD wMsg = HIWORD(wParam);
  486. WORD idCtrl = LOWORD(wParam);
  487. switch (idCtrl)
  488. {
  489. case IDC_CHOOSEAPP_WEBURL_EDIT:
  490. switch (wMsg)
  491. {
  492. case EN_SETFOCUS:
  493. case STN_CLICKED:
  494. _OnChooseAppURLFocus();
  495. break;
  496. default:
  497. //TraceMsg(TF_ALWAYS, "in CMailBoxProcess::_OnCommand() wMsg=%#08lx, idCtrl=%#08lx", wMsg, idCtrl);
  498. break;
  499. }
  500. break;
  501. case IDC_CHOOSEAPP_WEB_RADIO:
  502. switch (wMsg)
  503. {
  504. case BN_CLICKED:
  505. _OnChooseAppURLFocus();
  506. break;
  507. default:
  508. //TraceMsg(TF_ALWAYS, "in CMailBoxProcess::_OnCommand() wMsg=%#08lx, idCtrl=%#08lx", wMsg, idCtrl);
  509. break;
  510. }
  511. break;
  512. case IDC_CHOOSEAPP_OTHERAPP_RADIO:
  513. switch (wMsg)
  514. {
  515. case BN_CLICKED:
  516. _OnChooseAppListFocus();
  517. break;
  518. default:
  519. //TraceMsg(TF_ALWAYS, "in CMailBoxProcess::_OnCommand() wMsg=%#08lx, idCtrl=%#08lx", wMsg, idCtrl);
  520. break;
  521. }
  522. break;
  523. default:
  524. //TraceMsg(TF_ALWAYS, "in CMailBoxProcess::_OnCommand() wMsg=%#08lx, idCtrl=%#08lx", wMsg, idCtrl);
  525. break;
  526. }
  527. return fHandled;
  528. }
  529. INT_PTR CMailBoxProcess::_OnInitChooseApp(HWND hDlg)
  530. {
  531. BOOL fHandled = FALSE; // Not handled
  532. HWND hwndWizard = GetParent(hDlg);
  533. HWND hwndURLEditbox = GetDlgItem(hDlg, IDC_CHOOSEAPP_WEBURL_EDIT);
  534. m_hwndDialog = hDlg;
  535. // TODO: 2) Handle someone changing the combox box.
  536. LPCTSTR pszDomain = StrChr(m_szEmailAddress, CH_EMAIL_AT);
  537. if (pszDomain)
  538. {
  539. TCHAR szDesc[MAX_URL_STRING];
  540. pszDomain = CharNext(pszDomain); // Skip past the "@"
  541. // Update the description on the dialog if the download failed.
  542. if (m_fAutoDiscoveryFailed)
  543. {
  544. TCHAR szTemplate[MAX_URL_STRING];
  545. LoadString(HINST_THISDLL, IDS_CHOOSEAPP_FAILED_RESULTS, szTemplate, ARRAYSIZE(szTemplate));
  546. wnsprintf(szDesc, ARRAYSIZE(szDesc), szTemplate, pszDomain);
  547. SetWindowText(GetDlgItem(hDlg, IDC_CHOOSEAPP_DESC), szDesc);
  548. }
  549. wnsprintf(szDesc, ARRAYSIZE(szDesc), TEXT("http://www.%s/"), pszDomain);
  550. SetWindowText(hwndURLEditbox, szDesc);
  551. }
  552. // Populate the List of Apps
  553. HWND hwndList = GetDlgItem(hDlg, IDC_CHOOSEAPP_APPLIST);
  554. if (hwndList)
  555. {
  556. HIMAGELIST himlLarge;
  557. HIMAGELIST himlSmall;
  558. if (Shell_GetImageLists(&himlLarge, &himlSmall))
  559. {
  560. RECT rc;
  561. LV_COLUMN col = {LVCF_FMT | LVCF_WIDTH, LVCFMT_LEFT};
  562. ListView_SetImageList(hwndList, himlLarge, LVSIL_NORMAL);
  563. ListView_SetImageList(hwndList, himlSmall, LVSIL_SMALL);
  564. GetWindowRect(hwndList, &rc);
  565. col.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL) - (4 * GetSystemMetrics(SM_CXEDGE));
  566. ListView_InsertColumn(hwndList, 0, &col);
  567. _FillListWithApps(hwndList);
  568. // TODO: 1) On select in the list, force "Other:" to be checked. 2) If editbox changes, set "Web:"
  569. }
  570. }
  571. // Choose the Web Radio button because that will be the default.
  572. // (Most email systems tend to use web based)
  573. _OnChooseAppURLFocus();
  574. Edit_SetSel(hwndURLEditbox, 0, -1);
  575. return fHandled;
  576. }
  577. HRESULT _AddEmailClientToList(HWND hwndList, HKEY hkey, LPCTSTR pszMailApp, LPCTSTR pszFriendlyName)
  578. {
  579. TCHAR szPath[MAX_PATH];
  580. HRESULT hr = EmailAssoc_GetAppPath(hkey, szPath, ARRAYSIZE(szPath));
  581. if (SUCCEEDED(hr))
  582. {
  583. TCHAR szCmdLine[MAX_PATH];
  584. hr = EmailAssoc_GetAppCmdLine(hkey, szCmdLine, ARRAYSIZE(szCmdLine));
  585. if (SUCCEEDED(hr))
  586. {
  587. // Get the path we will use for the icon.
  588. TCHAR szIconPath[MAX_PATH];
  589. hr = EmailAssoc_GetIconPath(hkey, szIconPath, ARRAYSIZE(szIconPath));
  590. if (SUCCEEDED(hr))
  591. {
  592. EMAILCLIENT * pEmailClient = (EMAILCLIENT *) LocalAlloc(LPTR, sizeof(*pEmailClient));
  593. if (pEmailClient)
  594. {
  595. if (PathFileExists(szIconPath))
  596. {
  597. // TODO: Add a separate reg value for icon in the new case.
  598. Str_SetPtr(&pEmailClient->pszIconPath, szIconPath);
  599. }
  600. // TODO: We may want to use the dll's version resource because it
  601. // has a product description which may be localized.
  602. Str_SetPtr(&pEmailClient->pszFriendlyName, pszFriendlyName);
  603. Str_SetPtr(&pEmailClient->pszEmailApp, pszMailApp);
  604. if (pEmailClient->pszFriendlyName)
  605. {
  606. Str_SetPtr(&pEmailClient->pszPath, szPath);
  607. if (pEmailClient->pszPath)
  608. {
  609. if (szCmdLine[0])
  610. {
  611. Str_SetPtr(&pEmailClient->pszCmdLine, szCmdLine);
  612. }
  613. LV_ITEM item = {0};
  614. item.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
  615. item.iItem = INT_MAX;
  616. item.iSubItem = 0;
  617. item.state = 0;
  618. item.iImage = I_IMAGECALLBACK;
  619. item.pszText = pEmailClient->pszFriendlyName;
  620. item.lParam = (LPARAM)pEmailClient;
  621. if (-1 == ListView_InsertItem(hwndList, &item))
  622. {
  623. hr = E_FAIL;
  624. }
  625. }
  626. }
  627. else
  628. {
  629. hr = E_OUTOFMEMORY;
  630. }
  631. if (FAILED(hr))
  632. {
  633. FreeEmailClient(pEmailClient);
  634. }
  635. }
  636. else
  637. {
  638. hr = E_OUTOFMEMORY;
  639. }
  640. }
  641. }
  642. }
  643. return hr;
  644. }
  645. HRESULT CMailBoxProcess::_FillListWithApps(HWND hwndList)
  646. {
  647. HRESULT hr = S_OK;
  648. HKEY hkey;
  649. DWORD dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SZ_REGKEY_MAILCLIENTS, 0, KEY_READ, &hkey);
  650. hr = HRESULT_FROM_WIN32(dwError);
  651. if (SUCCEEDED(hr))
  652. {
  653. TCHAR szFriendlyName[MAX_PATH];
  654. TCHAR szKeyName[MAX_PATH];
  655. TCHAR szCurrent[MAX_PATH]; // Nuke?
  656. TCHAR szFriendlyCurrent[MAX_PATH];
  657. FILETIME ftLastWriteTime;
  658. DWORD nIndex; // Index counter
  659. DWORD cb;
  660. DWORD nSelected = 0;
  661. // find the currently selected client
  662. cb = sizeof(szCurrent);
  663. dwError = RegQueryValueEx(hkey, NULL, NULL, NULL, (LPBYTE)szCurrent, &cb);
  664. hr = HRESULT_FROM_WIN32(dwError);
  665. if (FAILED(hr))
  666. {
  667. // if not found then blank the friendly name and keyname.
  668. szCurrent[0] = 0;
  669. szFriendlyCurrent[0] = 0;
  670. }
  671. // populate the list
  672. for(nIndex = 0;
  673. cb = ARRAYSIZE(szKeyName), dwError = RegEnumKeyEx(hkey, nIndex, szKeyName, &cb, NULL, NULL, NULL, &ftLastWriteTime), hr = HRESULT_FROM_WIN32(dwError), SUCCEEDED(hr);
  674. nIndex++)
  675. {
  676. HKEY hkeyClient;
  677. // get the friendly name of the client
  678. dwError = RegOpenKeyEx(hkey, szKeyName, 0, KEY_READ, &hkeyClient);
  679. hr = HRESULT_FROM_WIN32(dwError);
  680. if (SUCCEEDED(hr))
  681. {
  682. cb = sizeof(szFriendlyName);
  683. dwError = RegQueryValueEx(hkeyClient, NULL, NULL, NULL, (LPBYTE)szFriendlyName, &cb);
  684. hr = HRESULT_FROM_WIN32(dwError);
  685. if (SUCCEEDED(hr))
  686. {
  687. hr = _AddEmailClientToList(hwndList, hkeyClient, szKeyName, szFriendlyName);
  688. // check to see if it's the current default
  689. if (!StrCmp(szKeyName, szCurrent))
  690. {
  691. // save its the friendly name which we'll use later to
  692. // select the current client and what index it is.
  693. StrCpyN(szFriendlyCurrent, szFriendlyName, ARRAYSIZE(szFriendlyCurrent));
  694. nSelected = nIndex;
  695. }
  696. }
  697. // close key
  698. RegCloseKey(hkeyClient);
  699. }
  700. } // for
  701. // use a custom sort to delay the friendly names being used
  702. // ListView_SortItems(hwndList, _CompareApps, 0);
  703. // Lets select the appropriate entre.
  704. ListView_SetItemState(hwndList, nSelected, LVNI_FOCUSED, LVNI_SELECTED);
  705. // close the keys
  706. RegCloseKey(hkey);
  707. }
  708. return hr;
  709. }
  710. HRESULT CMailBoxProcess::_OnGetDispInfo(LV_DISPINFO * pDispInfo, bool fUnicode)
  711. {
  712. HRESULT hr = S_OK;
  713. if (pDispInfo && pDispInfo->item.mask & LVIF_IMAGE)
  714. {
  715. EMAILCLIENT * pEmailClient = (EMAILCLIENT *) pDispInfo->item.lParam;
  716. if (pEmailClient)
  717. {
  718. pDispInfo->item.iImage = -1;
  719. if (pEmailClient->pszIconPath)
  720. {
  721. pDispInfo->item.iImage = Shell_GetCachedImageIndex(pEmailClient->pszIconPath, 0, 0);
  722. }
  723. if (-1 == pDispInfo->item.iImage)
  724. {
  725. pDispInfo->item.iImage = Shell_GetCachedImageIndex(TEXT("shell32.dll"), II_APPLICATION, 0);
  726. }
  727. if (-1 != pDispInfo->item.iImage)
  728. {
  729. pDispInfo->item.mask = LVIF_IMAGE;
  730. }
  731. }
  732. }
  733. return hr;
  734. }
  735. INT_PTR CMailBoxProcess::_OnUserCancelled(void)
  736. {
  737. m_hr = HRESULT_FROM_WIN32(ERROR_CANCELLED); // Means user cancelled
  738. _RestoreNextButton();
  739. return FALSE; // Not handled
  740. }
  741. INT_PTR CMailBoxProcess::_OnFinished(HRESULT hr, BSTR bstrXML)
  742. {
  743. SysFreeString(bstrXML);
  744. _RestoreNextButton();
  745. m_hr = hr; // whatever the success value was...
  746. if (S_OK == m_hr)
  747. {
  748. // We succeeded so we can end the dialog
  749. PropSheet_PressButton(GetParent(m_hwndDialog), PSBTN_FINISH);
  750. }
  751. else
  752. {
  753. // The results came back but we can't continue. So advance
  754. // to the Choose App page.
  755. m_fAutoDiscoveryFailed = TRUE;
  756. PropSheet_PressButton(GetParent(m_hwndDialog), PSBTN_NEXT);
  757. }
  758. return TRUE; // handled
  759. }
  760. INT_PTR CALLBACK GetEmailAddressDialogProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  761. {
  762. CMailBoxProcess * pMBProgress = (CMailBoxProcess *)GetWindowLongPtr(hDlg, DWLP_USER);
  763. if (WM_INITDIALOG == wMsg)
  764. {
  765. PROPSHEETPAGE * pPropSheetPage = (PROPSHEETPAGE *) lParam;
  766. if (pPropSheetPage)
  767. {
  768. SetWindowLongPtr(hDlg, DWLP_USER, pPropSheetPage->lParam);
  769. pMBProgress = (CMailBoxProcess *)pPropSheetPage->lParam;
  770. }
  771. }
  772. if (pMBProgress)
  773. return pMBProgress->_GetEmailAddressDialogProc(hDlg, wMsg, wParam, lParam);
  774. return DefWindowProc(hDlg, wMsg, wParam, lParam);
  775. }
  776. INT_PTR CMailBoxProcess::_GetEmailAddressDialogProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  777. {
  778. INT_PTR fHandled = TRUE; // handled
  779. switch (wMsg)
  780. {
  781. case WM_INITDIALOG:
  782. m_hwndDialog = hDlg;
  783. break;
  784. case WM_NOTIFY:
  785. {
  786. LPNMHDR pnmh = (LPNMHDR)lParam;
  787. switch (pnmh->code)
  788. {
  789. case PSN_SETACTIVE:
  790. PropSheet_SetWizButtons(GetParent(hDlg), PSWIZB_NEXT);
  791. fHandled = TRUE; // Return zero to accept the activation.
  792. break;
  793. case PSN_WIZNEXT:
  794. fHandled = _OnGetEmailAddressNext();
  795. break;
  796. case PSN_QUERYCANCEL:
  797. m_hr = HRESULT_FROM_WIN32(ERROR_CANCELLED); // Means user cancelled
  798. fHandled = FALSE;
  799. break;
  800. default:
  801. //TraceMsg(TF_ALWAYS, "CMailBoxProcess::_MailBoxProgressDialogProc(wMsg = %d, pnmh->code = %d) WM_NOTIFY", wMsg, pnmh->code);
  802. break;
  803. }
  804. }
  805. default:
  806. //TraceMsg(TF_ALWAYS, "CMailBoxProcess::_MailBoxProgressDialogProc(wMsg = %d) WM_NOTIFY", wMsg);
  807. fHandled = FALSE; // Not handled
  808. break;
  809. }
  810. return fHandled;
  811. }
  812. INT_PTR CMailBoxProcess::_OnGetEmailAddressNext(void)
  813. {
  814. BOOL fCancel = TRUE;
  815. GetWindowText(GetDlgItem(m_hwndDialog, IDC_GETEMAILADDRESS_EDIT), m_szEmailAddress, ARRAYSIZE(m_szEmailAddress));
  816. if (m_szEmailAddress[0] && StrChr(m_szEmailAddress, CH_EMAIL_AT))
  817. {
  818. // Looks valid to me.
  819. fCancel = 0;
  820. // TODO: Add more verification code
  821. }
  822. return fCancel; // 0 mean means allow it to close. TRUE means keep it open.
  823. }
  824. HRESULT CMailBoxProcess::_OpenEmailApp(void)
  825. {
  826. HKEY hkey;
  827. HRESULT hr = EmailAssoc_OpenEmailAccount(m_szEmailAddress, &hkey);
  828. if (SUCCEEDED(hr))
  829. {
  830. WCHAR wzPreferredApp[MAX_PATH];
  831. // Did the user customize the app for this Email address? (Default is no)
  832. hr = EmailAssoc_GetEmailAccountPreferredApp(hkey, wzPreferredApp, ARRAYSIZE(wzPreferredApp));
  833. if (SUCCEEDED(hr))
  834. {
  835. // Yes, so let's launch that app.
  836. hr = _OpenExeBasedEmailApp(wzPreferredApp);
  837. }
  838. else
  839. {
  840. WCHAR wzProtocol[MAX_PATH];
  841. hr = EmailAssoc_GetEmailAccountProtocol(hkey, wzProtocol, ARRAYSIZE(wzProtocol));
  842. if (SUCCEEDED(hr))
  843. {
  844. // No, but that's fine because it's the default.
  845. if (!StrCmpIW(wzProtocol, SZ_REGDATA_WEB))
  846. {
  847. hr = _OpenWebBasedEmail(hkey);
  848. }
  849. else
  850. {
  851. hr = EmailAssoc_GetEmailAccountGetAppFromProtocol(wzProtocol, wzPreferredApp, ARRAYSIZE(wzPreferredApp));
  852. if (SUCCEEDED(hr))
  853. {
  854. hr = _OpenExeBasedEmailApp(wzPreferredApp);
  855. }
  856. }
  857. }
  858. }
  859. RegCloseKey(hkey);
  860. }
  861. return hr;
  862. }
  863. HRESULT CMailBoxProcess::_OpenWebBasedEmail(HKEY hkey)
  864. {
  865. WCHAR wzURL[MAX_URL_STRING];
  866. HRESULT hr = EmailAssoc_GetEmailAccountWebURL(hkey, wzURL, ARRAYSIZE(wzURL));
  867. if (0 == wzURL[0])
  868. {
  869. hr = E_FAIL;
  870. }
  871. if (SUCCEEDED(hr))
  872. {
  873. // TODO: In the future, we can get more information from get_PostHTML(). With
  874. // that information, we can either:
  875. // 1. Do an HTTP POST with header data that will simmulate logging into the server.
  876. // This is good except that we need the password.
  877. // 2. We can put form value/data pair information into an pidl created from the URL.
  878. // We can then have the browser pull this information out and pre-populate form
  879. // items. This will pre-populate the "User:" form item. This way the user
  880. // only needs to enter their password.
  881. hr = HrShellExecute(NULL, NULL, wzURL, NULL, NULL, SW_SHOW);
  882. if (SUCCEEDED(hr))
  883. {
  884. AddEmailToAutoComplete(m_szEmailAddress);
  885. }
  886. }
  887. return hr;
  888. }
  889. HRESULT CMailBoxProcess::_OpenExeBasedEmailApp(IN LPCWSTR pszMailApp)
  890. {
  891. HKEY hkey;
  892. HRESULT hr = EmailAssoc_OpenMailApp(pszMailApp, &hkey);
  893. // TODO: Call _InstallLegacyAssociations() to make sure the associations are correct.
  894. if (SUCCEEDED(hr))
  895. {
  896. TCHAR szPath[MAX_URL_STRING];
  897. hr = EmailAssoc_GetAppPath(hkey, szPath, ARRAYSIZE(szPath));
  898. if (SUCCEEDED(hr))
  899. {
  900. TCHAR szCmdLine[MAX_URL_STRING];
  901. szCmdLine[0] = 0;
  902. if (SUCCEEDED(EmailAssoc_GetAppCmdLine(hkey, szCmdLine, ARRAYSIZE(szCmdLine))) && // optional
  903. !StrStrI(SZ_TOKEN_EMAILADDRESS, szCmdLine))
  904. {
  905. // They have a cmdline and they want us to replace a token.
  906. StrReplaceToken(SZ_TOKEN_EMAILADDRESS, m_szEmailAddress, szCmdLine, ARRAYSIZE(szCmdLine));
  907. }
  908. hr = HrShellExecute(NULL, NULL, szPath, (szCmdLine[0] ? szCmdLine : NULL), NULL, SW_SHOW);
  909. if (SUCCEEDED(hr))
  910. {
  911. AddEmailToAutoComplete(m_szEmailAddress);
  912. }
  913. }
  914. RegCloseKey(hkey);
  915. }
  916. return hr;
  917. }
  918. HRESULT CMailBoxProcess::_OpenProprietaryEmailApp(BSTR bstrProtocol, IMailProtocolADEntry * pMailProtocol)
  919. {
  920. HRESULT hr = E_FAIL;
  921. // TODO:
  922. MessageBox(NULL, TEXT("Open Proprietary Email App here. We look up in the registry for these types of apps. AOL, MSN, Compuserv are examples."), TEXT("Looser"), MB_OK);
  923. return hr;
  924. }
  925. //===========================
  926. // *** Public Methods ***
  927. //===========================
  928. HRESULT CMailBoxProcess::ParseCmdLine(LPTSTR pszCmdLine)
  929. {
  930. // We don't treat quote sections as blocks.
  931. PathUnquoteSpaces(pszCmdLine);
  932. while (pszCmdLine && pszCmdLine[0])
  933. {
  934. if (IsFlagSpecified(TEXT("email"), pszCmdLine))
  935. {
  936. pszCmdLine = GetNextArgument(pszCmdLine);
  937. if (pszCmdLine)
  938. {
  939. if ((TEXT('/') == pszCmdLine[0]) || (TEXT('-') == pszCmdLine[0]))
  940. {
  941. }
  942. else
  943. {
  944. LPTSTR pszEndOfEmailAddress = StrChr(pszCmdLine, TEXT(' '));
  945. SIZE_T cchSizeToCopy = ARRAYSIZE(m_szEmailAddress);
  946. if (pszEndOfEmailAddress && (cchSizeToCopy > (SIZE_T)(pszEndOfEmailAddress - pszCmdLine)))
  947. {
  948. cchSizeToCopy = (pszEndOfEmailAddress - pszCmdLine) + 1;
  949. }
  950. StrCpyN(m_szEmailAddress, pszCmdLine, (int)cchSizeToCopy);
  951. pszCmdLine = GetNextArgument(pszCmdLine);
  952. }
  953. }
  954. continue;
  955. }
  956. if (IsFlagSpecified(TEXT("GetDefaultAccount"), pszCmdLine))
  957. {
  958. pszCmdLine = GetNextArgument(pszCmdLine);
  959. m_fGetDefaultAccount = TRUE;
  960. continue;
  961. }
  962. if (IsFlagSpecified(TEXT("CreateNewEmailAccount"), pszCmdLine))
  963. {
  964. pszCmdLine = GetNextArgument(pszCmdLine);
  965. m_fCreateNewEmailAccount = TRUE;
  966. continue;
  967. }
  968. pszCmdLine = GetNextArgument(pszCmdLine);
  969. }
  970. return S_OK;
  971. }
  972. HRESULT CMailBoxProcess::Run(void)
  973. {
  974. HRESULT hr = CoInitialize(0);
  975. if (SUCCEEDED(hr))
  976. {
  977. if (TRUE == m_fCreateNewEmailAccount)
  978. {
  979. // TODO: look in the registry for the default email account and
  980. // copy it into m_szEmailAddress.
  981. MessageBox(NULL, TEXT("Create New Email Account"), TEXT("TODO: Add code here."), MB_OK);
  982. }
  983. else
  984. {
  985. if (TRUE == m_fGetDefaultAccount)
  986. {
  987. // If the caller wants to use the default email address, then look in the registry
  988. // for it and use that address.
  989. if (FAILED(EmailAssoc_GetDefaultEmailAccount(m_szEmailAddress, ARRAYSIZE(m_szEmailAddress))))
  990. {
  991. m_szEmailAddress[0] = 0;
  992. }
  993. }
  994. // Legacy email applications didn't install email associations, so we
  995. // do that for them now.
  996. EmailAssoc_InstallLegacyMailAppAssociations();
  997. if (m_szEmailAddress[0])
  998. {
  999. // Since we know the email address, try to open it now.
  1000. // (We will see if the associations are installed)
  1001. hr = _OpenEmailApp();
  1002. }
  1003. else
  1004. {
  1005. hr = E_FAIL;
  1006. }
  1007. if (FAILED(hr))
  1008. {
  1009. hr = _DisplayDialogAndAutoDiscover();
  1010. if (SUCCEEDED(hr)) // If we got the protocol, then open the app
  1011. {
  1012. hr = _OpenEmailApp();
  1013. }
  1014. ATOMICRELEASE(m_pMailAutoDiscovery);
  1015. }
  1016. }
  1017. }
  1018. else
  1019. {
  1020. CoUninitialize();
  1021. }
  1022. return hr;
  1023. }
  1024. //===========================
  1025. // *** IUnknown Interface ***
  1026. //===========================
  1027. STDMETHODIMP CMailBoxProcess::QueryInterface(REFIID riid, LPVOID *ppvObj)
  1028. {
  1029. static const QITAB qit[] =
  1030. {
  1031. QITABENT(CMailBoxProcess, IUnknown),
  1032. { 0 },
  1033. };
  1034. return QISearch(this, qit, riid, ppvObj);
  1035. }
  1036. STDMETHODIMP_(DWORD) CMailBoxProcess::AddRef()
  1037. {
  1038. return ++m_cRef;
  1039. }
  1040. STDMETHODIMP_(DWORD) CMailBoxProcess::Release()
  1041. {
  1042. if (--m_cRef == 0)
  1043. {
  1044. delete this;
  1045. return 0;
  1046. }
  1047. return m_cRef;
  1048. }
  1049. //===========================
  1050. // *** Class Methods ***
  1051. //===========================
  1052. CMailBoxProcess::CMailBoxProcess()
  1053. {
  1054. DllAddRef();
  1055. m_szNextText[0] = 0;
  1056. m_szEmailAddress[0] = 0;
  1057. m_fAutoDiscoveryFailed = FALSE;
  1058. m_hwndDialog = NULL;
  1059. m_pMailAutoDiscovery = NULL;
  1060. m_pszMailApp = NULL;
  1061. m_pszURL = NULL;
  1062. m_fGetDefaultAccount = FALSE;
  1063. m_fShowGetEmailAddressPage = FALSE;
  1064. m_fCreateNewEmailAccount = FALSE;
  1065. _InitComCtl32(); // So we can use the ICC_ANIMATE_CLASS common controls.
  1066. m_cRef = 1;
  1067. }
  1068. CMailBoxProcess::~CMailBoxProcess()
  1069. {
  1070. ATOMICRELEASE(m_pMailAutoDiscovery);
  1071. Str_SetPtr(&m_pszMailApp, NULL);
  1072. Str_SetPtr(&m_pszURL, NULL);
  1073. DllRelease();
  1074. }
  1075. //===========================
  1076. // *** Non-Class Functons ***
  1077. //===========================
  1078. int AutoDiscoverAndOpenEmail(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
  1079. {
  1080. TCHAR szCmdLine[MAX_EMAIL_ADDRESSS];
  1081. szCmdLine[0] = 0;
  1082. if (lpCmdLine)
  1083. {
  1084. // TODO: Either support Unicode or tounel thru UTF8
  1085. SHAnsiToTChar((LPCSTR)lpCmdLine, szCmdLine, ARRAYSIZE(szCmdLine));
  1086. }
  1087. CMailBoxProcess mailboxProcess;
  1088. if (SUCCEEDED(mailboxProcess.ParseCmdLine(szCmdLine)))
  1089. {
  1090. mailboxProcess.Run();
  1091. }
  1092. return 0;
  1093. }
  1094. #else // FEATURE_MAILBOX
  1095. int AutoDiscoverAndOpenEmail(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
  1096. {
  1097. return 0;
  1098. }
  1099. #endif // FEATURE_MAILBOX