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.

794 lines
23 KiB

  1. #include "pch.hxx"
  2. #include <mapi.h>
  3. #include <mapix.h>
  4. #include <newimp.h>
  5. #include <impapi.h>
  6. #include "import.h"
  7. #include <imnapi.h>
  8. #include <mapiconv.h>
  9. #include "strconst.h"
  10. ASSERTDATA
  11. static IMAPISession *s_pmapiExp = NULL;
  12. PFNEXPGETFIRSTIMSG g_pExpGetFirstImsg = 0;
  13. PFNEXPGETNEXTIMSG g_pExpGetNextImsg = 0;
  14. PFNEXPGETIMSGCLOSE g_pExpGetImsgClose = 0;
  15. PFNEXPGETFOLDERLIST g_pExpGetFolderList = 0;
  16. PFNEXPFREEFOLDERLIST g_pExpFreeFolderList = 0;
  17. PFNFREEIMSG g_pFreeImsg = 0;
  18. #undef ExpGetFirstImsg
  19. #undef ExpGetNextImsg
  20. #undef ExpGetImsgClose
  21. #undef ExpGetFolderList
  22. #undef ExpFreeFolderList
  23. #undef FreeImsg
  24. #define ExpGetFirstImsg (*g_pExpGetFirstImsg)
  25. #define ExpGetNextImsg (*g_pExpGetNextImsg)
  26. #define ExpGetImsgClose (*g_pExpGetImsgClose)
  27. #define ExpGetFolderList (*g_pExpGetFolderList)
  28. #define ExpFreeFolderList (*g_pExpFreeFolderList)
  29. #define FreeImsg (*g_pFreeImsg)
  30. INT_PTR CALLBACK ExportDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  31. BOOL PerformExport(HWND hwnd, IMPFOLDERNODE **ppnode, int cnode, IMPFOLDERNODE *plist);
  32. HRESULT ExportFolder(TCHAR *szName, LPMAPIFOLDER pfldr, HANDLE hfolder, ULONG cMsg, CImpProgress *pProg);
  33. HRESULT GetExportFolders(HWND hwndList, BOOL fSel, IMPFOLDERNODE ***pplist, int *pcnode);
  34. HRESULT HrGetFolder(LPMAPIFOLDER lpParent, LPSTR szName, LPMAPIFOLDER *lplpFldr, BOOL *pfDidCreate);
  35. INT_PTR CALLBACK ExportProgressDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  36. HRESULT ExportMessages(HWND hwnd)
  37. {
  38. HRESULT hr;
  39. int iret;
  40. BOOL fInit;
  41. HMODULE hinst;
  42. IMPFOLDERNODE *plist;
  43. hr = E_FAIL;
  44. fInit = FALSE;
  45. hinst = LoadLibrary(c_szMainDll);
  46. if (hinst != NULL)
  47. {
  48. g_pExpGetFirstImsg = (PFNEXPGETFIRSTIMSG)GetProcAddress(hinst, MAKEINTRESOURCE(9));
  49. g_pExpGetNextImsg = (PFNEXPGETNEXTIMSG)GetProcAddress(hinst, MAKEINTRESOURCE(10));
  50. g_pExpGetImsgClose = (PFNEXPGETIMSGCLOSE)GetProcAddress(hinst, MAKEINTRESOURCE(11));
  51. g_pExpGetFolderList = (PFNEXPGETFOLDERLIST)GetProcAddress(hinst, MAKEINTRESOURCE(12));
  52. g_pExpFreeFolderList = (PFNEXPFREEFOLDERLIST)GetProcAddress(hinst, MAKEINTRESOURCE(13));
  53. g_pFreeImsg = (PFNFREEIMSG)GetProcAddress(hinst, MAKEINTRESOURCE(14));
  54. if (g_pExpGetFirstImsg != NULL &&
  55. g_pExpGetNextImsg != NULL &&
  56. g_pExpGetImsgClose != NULL &&
  57. g_pExpGetFolderList != NULL &&
  58. g_pExpFreeFolderList != NULL &&
  59. g_pFreeImsg != NULL)
  60. {
  61. fInit = TRUE;
  62. iret = (int) ImpMessageBox(hwnd, MAKEINTRESOURCE(idsExportTitle),
  63. MAKEINTRESOURCE(idsPerformExport), NULL, MB_OKCANCEL | MB_ICONINFORMATION);
  64. if (iret == IDOK)
  65. {
  66. hr = ExchInit();
  67. if (SUCCEEDED(hr))
  68. {
  69. Assert(s_pmapiExp == NULL);
  70. hr = MapiLogon(hwnd, &s_pmapiExp);
  71. if (hr == S_OK)
  72. {
  73. Assert(s_pmapiExp != NULL);
  74. hr = ExpGetFolderList(&plist);
  75. if (SUCCEEDED(hr))
  76. {
  77. iret = (int) DialogBoxParam(g_hInstImp, MAKEINTRESOURCE(iddExport), hwnd,
  78. ExportDlgProc, (LPARAM)plist);
  79. ExpFreeFolderList(plist);
  80. }
  81. s_pmapiExp->Logoff(NULL, 0, 0);
  82. s_pmapiExp = NULL;
  83. }
  84. ExchDeinit();
  85. }
  86. else if (hr == MAPI_E_USER_CANCEL)
  87. {
  88. hr = S_OK;
  89. }
  90. else
  91. {
  92. ImpMessageBox(hwnd, MAKEINTRESOURCE(idsExportTitle),
  93. MAKEINTRESOURCE(idsExportError), MAKEINTRESOURCE(idsMAPIInitError),
  94. MB_OK | MB_ICONSTOP);
  95. }
  96. }
  97. else if (iret == IDCANCEL)
  98. {
  99. hr = S_OK;
  100. }
  101. }
  102. FreeLibrary(hinst);
  103. }
  104. if (!fInit)
  105. {
  106. ImpMessageBox(hwnd, MAKEINTRESOURCE(idsExportTitle),
  107. MAKEINTRESOURCE(idsExportError), MAKEINTRESOURCE(idsMapiInitError),
  108. MB_OK | MB_ICONSTOP);
  109. }
  110. return(hr);
  111. }
  112. INT_PTR CALLBACK ExportDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  113. {
  114. int id, cnode;
  115. BOOL fRet;
  116. HWND hwndList;
  117. HRESULT hr;
  118. IMPFOLDERNODE *plist, **ppnode;
  119. TCHAR sz[256];
  120. HCURSOR hcur = 0;
  121. fRet = TRUE;
  122. hwndList = GetDlgItem(hwnd, IDC_IMPFOLDER_LISTVIEW);
  123. plist = (IMPFOLDERNODE *)GetWindowLongPtr(hwnd, DWLP_USER);
  124. switch (msg)
  125. {
  126. case WM_INITDIALOG:
  127. plist = (IMPFOLDERNODE *)lParam;
  128. Assert(plist != NULL);
  129. SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)plist);
  130. InitListViewImages(hwndList);
  131. FillFolderListview(hwndList, plist, NULL);
  132. SendDlgItemMessage(hwnd, IDC_IMPORTALL_RADIO, BM_SETCHECK, BST_CHECKED, 0);
  133. EnableWindow(GetDlgItem(hwnd, IDC_IMPFOLDER_LISTVIEW), FALSE);
  134. break;
  135. case WM_COMMAND:
  136. id = LOWORD(wParam);
  137. switch (id)
  138. {
  139. case IDOK:
  140. fRet = (BST_CHECKED == SendDlgItemMessage(hwnd, IDC_SELECT_RADIO, BM_GETCHECK, 0, 0));
  141. plist = (IMPFOLDERNODE *)GetWindowLongPtr(hwnd, DWLP_USER);
  142. Assert(plist != NULL);
  143. hr = GetExportFolders(hwndList, fRet, &ppnode, &cnode);
  144. if (SUCCEEDED(hr) && cnode > 0)
  145. {
  146. hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  147. fRet = PerformExport(hwnd, ppnode, cnode, plist);
  148. if (ppnode != NULL)
  149. MemFree(ppnode);
  150. SetCursor(hcur);
  151. }
  152. // fall through...
  153. case IDCANCEL:
  154. EndDialog(hwnd, 0);
  155. break;
  156. case IDC_IMPORTALL_RADIO:
  157. case IDC_SELECT_RADIO:
  158. if (HIWORD(wParam) == BN_CLICKED)
  159. EnableWindow(hwndList, id == IDC_SELECT_RADIO);
  160. break;
  161. }
  162. break;
  163. default:
  164. fRet = FALSE;
  165. break;
  166. }
  167. return(fRet);
  168. }
  169. void ReleaseMapiFolders(IMPFOLDERNODE *plist)
  170. {
  171. while (plist != NULL)
  172. {
  173. if (plist->dwReserved != NULL)
  174. {
  175. ((LPMAPIFOLDER)plist->dwReserved)->Release();
  176. plist->dwReserved = NULL;
  177. }
  178. if (plist->pchild != NULL)
  179. ReleaseMapiFolders(plist->pchild);
  180. plist = plist->pnext;
  181. }
  182. }
  183. BOOL PerformExport(HWND hwnd, IMPFOLDERNODE **ppnode, int cnode, IMPFOLDERNODE *plist)
  184. {
  185. CImpProgress *pProg;
  186. IMPFOLDERNODE *pnode, *pnodeT;
  187. int inode;
  188. LPMAPICONTAINER pcont;
  189. LPMAPIFOLDER pfldrRoot, pfldrParent, pfldr;
  190. HRESULT hr;
  191. Assert(cnode > 0);
  192. Assert(ppnode != NULL);
  193. Assert(plist != NULL);
  194. pProg = new CImpProgress;
  195. if (pProg == NULL)
  196. {
  197. ImpMessageBox(hwnd, MAKEINTRESOURCE(idsExportTitle),
  198. MAKEINTRESOURCE(idsExportError), MAKEINTRESOURCE(idsMemory),
  199. MB_OK | MB_ICONSTOP);
  200. return(FALSE);
  201. }
  202. Assert(s_pmapiExp != NULL);
  203. pcont = OpenDefaultStoreContainer(hwnd, s_pmapiExp);
  204. if (pcont == NULL)
  205. {
  206. hr = E_OUTOFMEMORY;
  207. }
  208. else
  209. {
  210. hr = pcont->QueryInterface(IID_IMAPIFolder, (void **)&pfldrRoot);
  211. pcont->Release();
  212. }
  213. if (FAILED(hr))
  214. {
  215. ImpMessageBox(hwnd, MAKEINTRESOURCE(idsExportTitle),
  216. MAKEINTRESOURCE(idsExportError), MAKEINTRESOURCE(idsMAPIStoreOpenError),
  217. MB_OK | MB_ICONSTOP);
  218. return(FALSE);
  219. }
  220. pProg->Init(hwnd, TRUE);
  221. pProg->SetTitle(MAKEINTRESOURCE(idsExportTitle));
  222. for (inode = 0; inode < cnode; inode++)
  223. {
  224. pnode = ppnode[inode];
  225. Assert(pnode != NULL);
  226. pfldrParent = NULL;
  227. pnodeT = pnode->pparent;
  228. while (pnodeT != NULL)
  229. {
  230. if (pnodeT->dwReserved != NULL)
  231. {
  232. pfldrParent = (LPMAPIFOLDER)pnodeT->dwReserved;
  233. break;
  234. }
  235. pnodeT = pnodeT->pparent;
  236. }
  237. if (pfldrParent == NULL)
  238. {
  239. pfldrParent = pfldrRoot;
  240. ReleaseMapiFolders(plist);
  241. }
  242. hr = HrGetFolder(pfldrParent, pnode->szName, &pfldr, NULL);
  243. if (!FAILED(hr))
  244. hr = ExportFolder(pnode->szName, pfldr, (HANDLE)pnode->lparam, pnode->cMsg, pProg);
  245. if(hr == hrUserCancel)
  246. break;
  247. Assert(pnode->dwReserved == NULL);
  248. pnode->dwReserved = (DWORD_PTR)pfldr;
  249. }
  250. pProg->Release();
  251. ReleaseMapiFolders(plist);
  252. pfldrRoot->Release();
  253. return(TRUE);
  254. }
  255. HRESULT GetExportFolders(HWND hwndList, BOOL fSel, IMPFOLDERNODE ***pplist, int *pcnode)
  256. {
  257. int cSel, ili;
  258. IMPFOLDERNODE **ppnode, **ppnodeT;
  259. LV_ITEM lvi;
  260. Assert(pplist != NULL);
  261. Assert(pcnode != NULL);
  262. *pplist = NULL;
  263. *pcnode = 0;
  264. cSel = (int) SendMessage(hwndList, (fSel ? LVM_GETSELECTEDCOUNT : LVM_GETITEMCOUNT), 0, 0);
  265. if (cSel == 0)
  266. return(S_OK);
  267. if (!MemAlloc((void **)&ppnode, sizeof(IMPFOLDERNODE *) * cSel))
  268. return(E_OUTOFMEMORY);
  269. ppnodeT = ppnode;
  270. lvi.mask = LVIF_PARAM;
  271. lvi.iSubItem = 0;
  272. cSel = 0;
  273. ili = -1;
  274. while (-1 != (ili = ListView_GetNextItem(hwndList, ili, fSel ? LVNI_SELECTED : 0)))
  275. {
  276. lvi.iItem = ili;
  277. if (ListView_GetItem(hwndList, &lvi))
  278. {
  279. Assert(lvi.lParam != 0);
  280. *ppnodeT = (IMPFOLDERNODE *)lvi.lParam;
  281. cSel++;
  282. ppnodeT++;
  283. }
  284. }
  285. *pplist = ppnode;
  286. *pcnode = cSel;
  287. return(S_OK);
  288. }
  289. HRESULT HrGetFolder(LPMAPIFOLDER lpParent, LPSTR szName, LPMAPIFOLDER *lplpFldr, BOOL *pfDidCreate)
  290. {
  291. SPropValue pv;
  292. HRESULT hr;
  293. SRestriction sr;
  294. LPMAPITABLE lpTable = NULL;
  295. SizedSPropTagArray(3, ptaFindFldr) =
  296. { 3, { PR_ENTRYID,
  297. PR_DISPLAY_NAME,
  298. PR_STATUS} };
  299. pv.ulPropTag = PR_DISPLAY_NAME;
  300. pv.Value.lpszA = szName;
  301. *lplpFldr = NULL; // in case we fail
  302. if (FAILED(hr = lpParent->GetHierarchyTable(0, &lpTable)))
  303. goto cleanup;
  304. // Set the table's columns to include PR_MODULE_CLASS so FindRow will work.
  305. if (HR_FAILED(hr=lpTable->SetColumns((LPSPropTagArray)&ptaFindFldr, 0)))
  306. {
  307. // Fn might (?) fail if container is an address book
  308. // so this might need to change...
  309. DOUTL(2, "HrGetContainer: SetColumns failed.");
  310. goto cleanup;
  311. }
  312. // Find the container. If it's not there, then we need to create it
  313. if (pfDidCreate)
  314. *pfDidCreate = FALSE; // default value
  315. sr.rt = RES_PROPERTY;
  316. sr.res.resProperty.relop = RELOP_EQ;
  317. sr.res.resProperty.ulPropTag = pv.ulPropTag;
  318. sr.res.resProperty.lpProp = &pv;
  319. if (FAILED(hr = lpTable->FindRow(&sr, BOOKMARK_BEGINNING, 0)))
  320. { // folder needs to be created
  321. hr = lpParent->CreateFolder(FOLDER_GENERIC, szName, NULL, NULL, 0, lplpFldr);
  322. if (pfDidCreate && SUCCEEDED(hr))
  323. *pfDidCreate = TRUE; // a new folder was created
  324. }
  325. else
  326. {
  327. LPSRowSet lpRowSet = NULL;
  328. LPSPropValue lpProp;
  329. ULONG ulObjType;
  330. if (!FAILED(hr = lpTable->QueryRows(1, TBL_NOADVANCE, &lpRowSet)) && lpRowSet->cRows)
  331. {
  332. if (lpProp = PvalFind(lpRowSet->aRow, PR_ENTRYID))
  333. hr = lpParent->OpenEntry(lpProp->Value.bin.cb,
  334. (LPENTRYID)lpProp->Value.bin.lpb,
  335. NULL,
  336. MAPI_MODIFY,
  337. &ulObjType,
  338. (LPUNKNOWN FAR *)lplpFldr);
  339. }
  340. FreeSRowSet(lpRowSet);
  341. }
  342. cleanup:
  343. if (lpTable)
  344. lpTable->Release();
  345. return hr;
  346. }
  347. HRESULT ExportFolder(TCHAR *szName, LPMAPIFOLDER pfldr, HANDLE hfolder, ULONG cMsg, CImpProgress *pProg)
  348. {
  349. HRESULT hr;
  350. HANDLE hnd;
  351. IMSG imsg;
  352. LPMESSAGE pmsg;
  353. ULONG iMsg;
  354. TCHAR sz[128], szT[256];
  355. LoadString(g_hInstImp, idsExportingFolderFmt, sz, ARRAYSIZE(sz));
  356. wnsprintf(szT, ARRAYSIZE(szT), sz, szName);
  357. LoadString(g_hInstImp, idsImportingMessageFmt, sz, ARRAYSIZE(sz));
  358. iMsg = 0;
  359. hr = ExpGetFirstImsg(hfolder, &imsg, &hnd);
  360. while (hr == S_OK)
  361. {
  362. if (iMsg == 0)
  363. {
  364. pProg->SetMsg(szT, IDC_FOLDER_STATIC);
  365. pProg->Show(0);
  366. pProg->Reset();
  367. pProg->AdjustMax(cMsg);
  368. }
  369. wnsprintf(szT, ARRAYSIZE(szT), sz, iMsg + 1, cMsg);
  370. pProg->SetMsg(szT, IDC_MESSAGE_STATIC);
  371. hr = pfldr->CreateMessage(NULL, 0, &pmsg);
  372. if (!FAILED(hr))
  373. {
  374. hr = HrImsgToMapi(&imsg, pmsg);
  375. pmsg->Release();
  376. }
  377. FreeImsg(&imsg);
  378. hr = ExpGetNextImsg(&imsg, hnd);
  379. if (hr != S_OK)
  380. break;
  381. iMsg++;
  382. hr = pProg->HrUpdate(1);
  383. }
  384. ExpGetImsgClose(hnd);
  385. if (hr == S_FALSE)
  386. hr = S_OK;
  387. return(hr);
  388. }
  389. #define IDT_PROGRESS_DELAY (WM_USER + 1)
  390. CImpProgress::CImpProgress ()
  391. {
  392. DOUT ("CImpProgress::CImpProgress");
  393. m_cRef = 1;
  394. m_cMax = 0;
  395. m_cPerCur = 0;
  396. m_hwndProgress = NULL;
  397. m_hwndDlg = NULL;
  398. m_hwndOwner = NULL;
  399. m_fCanCancel = FALSE;
  400. m_fHasCancel = FALSE;
  401. }
  402. // =====================================================================================
  403. // CImpProgress::~CImpProgress
  404. // =====================================================================================
  405. CImpProgress::~CImpProgress ()
  406. {
  407. DOUT ("CImpProgress::~CImpProgress");
  408. Close();
  409. }
  410. // =====================================================================================
  411. // CImpProgress::AddRef
  412. // =====================================================================================
  413. ULONG CImpProgress::AddRef ()
  414. {
  415. ++m_cRef;
  416. DOUT ("CImpProgress::AddRef () Ref Count=%d", m_cRef);
  417. return m_cRef;
  418. }
  419. // =====================================================================================
  420. // CImpProgress::AddRef
  421. // =====================================================================================
  422. ULONG CImpProgress::Release ()
  423. {
  424. ULONG ulCount = --m_cRef;
  425. DOUT ("CImpProgress::Release () Ref Count=%d", ulCount);
  426. if (!ulCount)
  427. delete this;
  428. return ulCount;
  429. }
  430. // =====================================================================================
  431. // CImpProgress::Init
  432. // =====================================================================================
  433. VOID CImpProgress::Init (HWND hwndParent, BOOL fCanCancel)
  434. {
  435. Assert(m_hwndDlg == NULL);
  436. // Set Max and cur
  437. m_fCanCancel = fCanCancel;
  438. // Save Parent
  439. m_hwndOwner = hwndParent;
  440. // Disable Parent
  441. EnableWindow (m_hwndOwner, FALSE);
  442. // Create Dialog
  443. m_hwndDlg = CreateDialogParam (g_hInstImp, MAKEINTRESOURCE (iddImpProgress),
  444. hwndParent, ProgressDlgProc, (LPARAM)this);
  445. }
  446. // =====================================================================================
  447. // CImpProgress::Close
  448. // =====================================================================================
  449. VOID CImpProgress::Close (VOID)
  450. {
  451. // If we have a window
  452. if (m_hwndDlg)
  453. {
  454. // Enable parent
  455. if (m_hwndOwner)
  456. EnableWindow (m_hwndOwner, TRUE);
  457. // Destroy it
  458. DestroyWindow (m_hwndDlg);
  459. // NULL
  460. m_hwndDlg = NULL;
  461. }
  462. }
  463. // =====================================================================================
  464. // CImpProgress::Show
  465. // =====================================================================================
  466. VOID CImpProgress::Show (DWORD dwDelaySeconds)
  467. {
  468. // If we have a window
  469. if (m_hwndDlg)
  470. {
  471. // Show the window if now delay
  472. if (dwDelaySeconds == 0)
  473. ShowWindow (m_hwndDlg, SW_SHOWNORMAL);
  474. else
  475. SetTimer(m_hwndDlg, IDT_PROGRESS_DELAY, dwDelaySeconds * 1000, NULL);
  476. }
  477. }
  478. // =====================================================================================
  479. // CImpProgress::Hide
  480. // =====================================================================================
  481. VOID CImpProgress::Hide (VOID)
  482. {
  483. // If we have a window
  484. if (m_hwndDlg)
  485. {
  486. // Hide it
  487. ShowWindow (m_hwndDlg, SW_HIDE);
  488. }
  489. }
  490. // =====================================================================================
  491. // CImpProgress::SetMsg
  492. // =====================================================================================
  493. VOID CImpProgress::SetMsg(LPTSTR lpszMsg, int id)
  494. {
  495. TCHAR sz[CCHMAX_STRINGRES];
  496. if (m_hwndDlg && lpszMsg)
  497. {
  498. if (IS_INTRESOURCE(lpszMsg))
  499. {
  500. LoadString(g_hInstImp, PtrToUlong(lpszMsg), sz, sizeof(sz) / sizeof(TCHAR));
  501. lpszMsg = sz;
  502. }
  503. SetWindowText (GetDlgItem (m_hwndDlg, id), lpszMsg);
  504. }
  505. }
  506. // =====================================================================================
  507. // CImpProgress::SetTitle
  508. // =====================================================================================
  509. VOID CImpProgress::SetTitle(LPTSTR lpszTitle)
  510. {
  511. TCHAR sz[CCHMAX_STRINGRES];
  512. if (m_hwndDlg && lpszTitle)
  513. {
  514. if (IS_INTRESOURCE(lpszTitle))
  515. {
  516. LoadString(g_hInstImp, PtrToUlong(lpszTitle), sz, sizeof(sz) / sizeof(TCHAR));
  517. lpszTitle = sz;
  518. }
  519. SetWindowText (m_hwndDlg, lpszTitle);
  520. }
  521. }
  522. // =====================================================================================
  523. // CImpProgress::AdjustMax
  524. // =====================================================================================
  525. VOID CImpProgress::AdjustMax(ULONG cNewMax)
  526. {
  527. // Set Max
  528. m_cMax = cNewMax;
  529. // If 0
  530. if (m_cMax == 0)
  531. {
  532. SendMessage (m_hwndProgress, PBM_SETPOS, 0, 0);
  533. ShowWindow(m_hwndProgress, SW_HIDE);
  534. return;
  535. }
  536. else
  537. ShowWindow(m_hwndProgress, SW_SHOWNORMAL);
  538. // If cur is now larget than max ?
  539. if (m_cCur > m_cMax)
  540. m_cCur = m_cMax;
  541. // Compute percent
  542. m_cPerCur = (m_cCur * 100 / m_cMax);
  543. // Update status
  544. SendMessage (m_hwndProgress, PBM_SETPOS, m_cPerCur, 0);
  545. // msgpump to process user moving window, or pressing cancel... :)
  546. MSG msg;
  547. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  548. {
  549. TranslateMessage(&msg);
  550. DispatchMessage(&msg);
  551. }
  552. }
  553. VOID CImpProgress::Reset()
  554. {
  555. m_cCur = 0;
  556. m_cPerCur = 0;
  557. // Update status
  558. SendMessage (m_hwndProgress, PBM_SETPOS, 0, 0);
  559. }
  560. // =====================================================================================
  561. // CImpProgress::HrUpdate
  562. // =====================================================================================
  563. HRESULT CImpProgress::HrUpdate (ULONG cInc)
  564. {
  565. // No max
  566. if (m_cMax)
  567. {
  568. // Increment m_cCur
  569. m_cCur += cInc;
  570. // If cur is now larget than max ?
  571. if (m_cCur > m_cMax)
  572. m_cCur = m_cMax;
  573. // Compute percent
  574. ULONG cPer = (m_cCur * 100 / m_cMax);
  575. // Step percent
  576. if (cPer > m_cPerCur)
  577. {
  578. // Set percur
  579. m_cPerCur = cPer;
  580. // Update status
  581. SendMessage (m_hwndProgress, PBM_SETPOS, m_cPerCur, 0);
  582. // msgpump to process user moving window, or pressing cancel... :)
  583. MSG msg;
  584. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  585. {
  586. TranslateMessage(&msg);
  587. DispatchMessage(&msg);
  588. }
  589. }
  590. }
  591. // Still pump some messages, call may not want to do this too often
  592. else
  593. {
  594. // msgpump to process user moving window, or pressing cancel... :)
  595. MSG msg;
  596. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  597. {
  598. TranslateMessage(&msg);
  599. DispatchMessage(&msg);
  600. }
  601. }
  602. // Done
  603. return m_fHasCancel ? hrUserCancel : S_OK;
  604. }
  605. // =====================================================================================
  606. // CImpProgress::ProgressDlgProc
  607. // =====================================================================================
  608. INT_PTR CALLBACK CImpProgress::ProgressDlgProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  609. {
  610. // Locals
  611. CImpProgress *lpProgress = (CImpProgress *)GetWndThisPtr(hwnd);
  612. switch (uMsg)
  613. {
  614. case WM_INITDIALOG:
  615. lpProgress = (CImpProgress *)lParam;
  616. if (!lpProgress)
  617. {
  618. Assert (FALSE);
  619. return 1;
  620. }
  621. lpProgress->m_hwndProgress = GetDlgItem (hwnd, IDC_IMPORT_PROGRESS);
  622. if (lpProgress->m_cMax == 0)
  623. ShowWindow(lpProgress->m_hwndProgress, SW_HIDE);
  624. // Show the cancel button if m_fCanCancel is true.
  625. if(lpProgress->m_fCanCancel)
  626. ShowWindow(GetDlgItem(hwnd, IDCANCEL), SW_SHOWNORMAL);
  627. SetWndThisPtr (hwnd, lpProgress);
  628. return 1;
  629. case WM_TIMER:
  630. if (wParam == IDT_PROGRESS_DELAY)
  631. {
  632. KillTimer(hwnd, IDT_PROGRESS_DELAY);
  633. if (lpProgress->m_cPerCur < 80)
  634. {
  635. lpProgress->m_cMax -= lpProgress->m_cCur;
  636. lpProgress->Reset();
  637. ShowWindow(hwnd, SW_SHOWNORMAL);
  638. }
  639. }
  640. break;
  641. case WM_COMMAND:
  642. switch(GET_WM_COMMAND_ID(wParam,lParam))
  643. {
  644. case IDCANCEL:
  645. if (lpProgress)
  646. {
  647. EnableWindow ((HWND)lParam, FALSE);
  648. lpProgress->m_fHasCancel = TRUE;
  649. }
  650. return 1;
  651. }
  652. break;
  653. case WM_DESTROY:
  654. KillTimer(hwnd, IDT_PROGRESS_DELAY);
  655. SetWndThisPtr (hwnd, NULL);
  656. break;
  657. }
  658. // Done
  659. return 0;
  660. }