TVNODE.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:11k
源码类别:

Windows编程

开发平台:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////
  2. //
  3. //  TVNODE.CPP
  4. //
  5. //
  6. //  Copyright 1986-1996 Microsoft Corporation. All Rights Reserved.
  7. ///////////////////////////////////////////////////////////////////////
  8. #define STRICT
  9. #include <windows.h>
  10. #include <commctrl.h>
  11. #include <mapix.h>
  12. #include <mapiutil.h>
  13. #include <mapidbg.h>
  14. #include "lasterr.h"
  15. #include "tvdlg.h"
  16. LPSTR g_szNoFolderName = "<No Name>";
  17. //
  18. //  CTVNode::CTVNode
  19. //
  20. CTVNode::CTVNode(LPSPropValue pval, ULONG cProps, LPMDB pmdb)
  21. {
  22.     Assert(cProps == nhtProps);
  23.     Assert(pval);
  24.     m_pval = pval;
  25.     m_htiMe = NULL;
  26.         
  27.     m_fKidsLoaded = FALSE;
  28.     m_pfld = NULL;
  29.     m_pNext = NULL;
  30.     m_pmdb = pmdb;
  31.     if(pmdb)
  32.         pmdb->AddRef();
  33. }
  34. //
  35. //  CTVNode::~CTVNode
  36. //
  37. CTVNode::~CTVNode()
  38. {
  39.     MAPIFreeBuffer(m_pval);
  40.     UlRelease(m_pfld);
  41.     UlRelease(m_pmdb);
  42. }
  43. //
  44. //  CTVNode::HrExpand
  45. //
  46. //  Put all kids of the given folder in the tree control
  47. //
  48. HRESULT CTVNode::HrExpand(CChsFldDlg * pCFDlg)
  49. {
  50.     HRESULT hr;
  51.     LPMAPITABLE ptblHier = NULL;
  52.     LPSRowSet pRowSet = NULL;
  53.     UINT ind;
  54.     
  55.     static SSortOrderSet sosName;
  56.     sosName.cSorts = 1;
  57.     sosName.cCategories = 0;
  58.     sosName.cExpanded = 0;
  59.     sosName.aSort[0].ulPropTag = PR_DISPLAY_NAME;
  60.     sosName.aSort[0].ulOrder = TABLE_SORT_ASCEND;
  61.     Assert(m_htiMe);
  62.     
  63.     if(m_fKidsLoaded || !m_pval[iSubfldrs].Value.b)
  64.         return hrSuccess;
  65.     if(!m_pmdb)
  66.     {
  67.     // this node corresponds to the top level of a message store which has
  68.     // not been opend yet.
  69.     // m_pval[iEID] contains entry ID of the message store
  70.     // 
  71.         hr = HrOpenMDB(pCFDlg);
  72.         if(FAILED(hr))
  73.             goto err;
  74.     }
  75.     
  76.     Assert(m_pmdb);     
  77.     
  78.     if(!m_pfld)
  79.     {
  80.         hr = HrOpenFolder(pCFDlg);
  81.         if(FAILED(hr))
  82.             goto err;
  83.     }
  84.     Assert(m_pfld); 
  85.     
  86.     hr = m_pfld->GetHierarchyTable(MAPI_DEFERRED_ERRORS, &ptblHier);
  87.     if(HR_FAILED(hr))
  88.     {
  89.         pCFDlg->m_lsterr.HrSetLastError(hr, m_pfld);
  90.         pCFDlg->m_lsterr.ShowError(pCFDlg->hwDialog());
  91.         
  92.         goto err;
  93.     }
  94.     hr = HrQueryAllRows(ptblHier, (LPSPropTagArray)&spthtProps, NULL, &sosName,
  95.                         0, &pRowSet);
  96.     if(HR_FAILED(hr))
  97.         goto err;
  98.     if(0 == pRowSet->cRows)
  99.     {
  100.         m_pval[iSubfldrs].Value.b = FALSE;
  101.         goto err;
  102.     }
  103.     for(ind = 0; ind < pRowSet->cRows; ++ind)
  104.     {
  105.         LPSPropValue pval = pRowSet->aRow[ind].lpProps;
  106.         
  107.         Assert(pRowSet->aRow[ind].cValues == nhtProps);
  108.         Assert(pval[iEID].ulPropTag == PR_ENTRYID);
  109.         Assert(pval[iDispName].ulPropTag == PR_DISPLAY_NAME);
  110.         Assert(pval[iSubfldrs].ulPropTag == PR_SUBFOLDERS);
  111.         LPTVNODE pNode = NULL;
  112.         hr = pCFDlg->HrCreateNode(pval, nhtProps, m_pmdb, &pNode);
  113.         if(hr)
  114.             goto err;
  115.     
  116.         //this row will be freed in ~CTVNode
  117.         pRowSet->aRow[ind].cValues = 0;
  118.         pRowSet->aRow[ind].lpProps = NULL;
  119.         HTREEITEM hItem;
  120.         
  121.         hItem = AddOneItem(m_htiMe,  TVI_LAST, pCFDlg->IndClsdFld(),
  122.                             pCFDlg->IndOpenFld(), pCFDlg->hwTreeCtl(), pNode,
  123.                             pval[iSubfldrs].Value.b? 1: 0);
  124.         if(!hItem)
  125.         {
  126.             hr = ResultFromScode(MAPI_E_NOT_ENOUGH_MEMORY);
  127.             goto err;
  128.         }
  129.             
  130.     }
  131.     m_fKidsLoaded = TRUE;
  132. err:
  133.     UlRelease(ptblHier);
  134.     FreeProws(pRowSet);
  135.     DebugTraceResult(CTVNode::HrExpand, hr);
  136.     return hr;
  137. }
  138. //
  139. //  CTVNode::HrOpenMDB
  140. //
  141. HRESULT CTVNode::HrOpenMDB(CChsFldDlg * pCFDlg)
  142. {
  143.     HRESULT hr;
  144.     LPMDB pmdb = NULL;
  145.     LPSPropValue pvalIPM = NULL;
  146.     ULONG ulObjType;
  147.     
  148.     Assert(m_pval[iEID].ulPropTag == PR_ENTRYID);
  149.     DebugTrace("ChsFld: Openning Msg Store: %sn", GetName());
  150.     
  151.     hr = pCFDlg->Session()->OpenMsgStore(0L, m_pval[iEID].Value.bin.cb,
  152.                                 (LPENTRYID)m_pval[iEID].Value.bin.lpb,
  153.                                 NULL, MAPI_BEST_ACCESS, &pmdb);
  154.     if(hr) //Display warning messages too
  155.     {
  156.         pCFDlg->m_lsterr.HrSetLastError(hr, pCFDlg->Session());
  157.         pCFDlg->m_lsterr.ShowError(pCFDlg->hwDialog());
  158.     }
  159.     if(HR_FAILED(hr))
  160.         goto err;
  161.     hr = HrGetOneProp(pmdb, PR_IPM_SUBTREE_ENTRYID, &pvalIPM);
  162.     if(hr)
  163.     {
  164.         pCFDlg->m_lsterr.HrSetLastError(hr, pmdb);
  165.         pCFDlg->m_lsterr.ShowError(pCFDlg->hwDialog());
  166.         goto err;
  167.     }
  168.     hr = pmdb->OpenEntry(pvalIPM->Value.bin.cb,
  169.                 (LPENTRYID)pvalIPM->Value.bin.lpb,
  170.                 NULL, MAPI_BEST_ACCESS | MAPI_DEFERRED_ERRORS,
  171.                  &ulObjType, (LPUNKNOWN *) &m_pfld);
  172.     if(HR_FAILED(hr))
  173.     {
  174.         pCFDlg->m_lsterr.HrSetLastError(hr, pmdb);
  175.         pCFDlg->m_lsterr.ShowError(pCFDlg->hwDialog());
  176.         
  177.         goto err;
  178.     }
  179.     
  180.     Assert(MAPI_FOLDER == ulObjType);
  181. /*  if(pvalIPM->Value.bin.cb > m_pval[iEID].Value.bin.cb)
  182.     {
  183.         if(hr = MAPIAllocateMore(pvalIPM->Value.bin.cb,
  184.                         m_pval, (LPVOID *)&m_pval[iEID].Value.bin.lpb))
  185.             goto err;
  186.                 
  187.     }
  188.     CopyMemory(m_pval[iEID].Value.bin.lpb, pvalIPM->Value.bin.lpb,
  189.                                         pvalIPM->Value.bin.cb);
  190.     m_pval[iEID].Value.bin.cb = pvalIPM->Value.bin.cb;*/
  191. err:
  192.     if(HR_FAILED(hr))
  193.     {
  194.         UlRelease(pmdb);
  195.         UlRelease(m_pfld);
  196.         m_pfld = NULL;
  197.     }
  198.     else
  199.     {
  200.         m_pmdb = pmdb;
  201.         hr = hrSuccess; //don't return warnings
  202.     }
  203.     MAPIFreeBuffer(pvalIPM);
  204.     DebugTraceResult(CTVNode::HrOpenMDB, hr);
  205.     return hr;
  206. }
  207. //
  208. //  CTVNode::HrOpenFolder
  209. //
  210. HRESULT CTVNode::HrOpenFolder(CChsFldDlg * pCFDlg)
  211. {
  212.     HRESULT hr;
  213.     ULONG ulObjType;
  214.     Assert(m_pval[iEID].ulPropTag == PR_ENTRYID);
  215.     Assert(m_pmdb);
  216.     
  217.     // MAPI_MODIFY flag affects only IMAPIProp interface of the object.
  218.     // It does not guarantee permission to create subfolders.
  219.     hr = m_pmdb->OpenEntry(m_pval[iEID].Value.bin.cb,
  220.                 (LPENTRYID)m_pval[iEID].Value.bin.lpb,
  221.                 NULL, MAPI_BEST_ACCESS | MAPI_DEFERRED_ERRORS,
  222.                  &ulObjType, (LPUNKNOWN *) &m_pfld);
  223.     if(HR_FAILED(hr))
  224.     {
  225.         pCFDlg->m_lsterr.HrSetLastError(hr, m_pmdb);
  226.         pCFDlg->m_lsterr.ShowError(pCFDlg->hwDialog());
  227.         
  228.         goto err;
  229.     }
  230.     
  231.     Assert(MAPI_FOLDER == ulObjType);
  232. err:
  233.     DebugTraceResult(CTVNode::HrOpenFolder, hr);
  234.     return hr;
  235. }
  236. //
  237. //  CTVNode::HrGetFolder
  238. //
  239. //  return folder interface for the node
  240. HRESULT CTVNode::HrGetFolder(CChsFldDlg * pCFDlg,
  241.                             LPMAPIFOLDER * ppfld, LPMDB *ppmdb)
  242. {
  243.     HRESULT hr = hrSuccess;
  244.     
  245.     Assert(pCFDlg);
  246.     Assert(ppfld);
  247.     Assert(ppmdb);
  248.     if(!m_pmdb)
  249.     {
  250.         hr = HrOpenMDB(pCFDlg);
  251.         if(FAILED(hr))
  252.             goto err;
  253.     }
  254.     Assert(m_pmdb);
  255.     
  256.     if(!m_pfld)
  257.     {
  258.         Assert(!m_fKidsLoaded);
  259.         
  260.         hr = HrOpenFolder(pCFDlg);
  261.         if(FAILED(hr))
  262.             goto err;
  263.     }
  264.     Assert(m_pfld);
  265.     *ppfld = m_pfld;
  266.     m_pfld->AddRef();
  267.     m_pmdb->AddRef();
  268.     *ppmdb = m_pmdb;            
  269. err:
  270.     DebugTraceResult(CTVNode::HrGetFolder, hr);
  271.     return hr;
  272. }
  273. //
  274. //  CTVNode::HrNewFolder
  275. //
  276. // Create subfolder szFldName
  277. //
  278. HRESULT CTVNode::HrNewFolder(CChsFldDlg * pCFDlg,
  279.                                      LPSTR szFldName)
  280. {
  281.     HRESULT hr;
  282.     LPMAPIFOLDER pfldNew = NULL;
  283.     LPTVNODE pNode = NULL;
  284.     LPSPropValue pval = NULL;
  285.     HTREEITEM hItem;
  286.     Assert(szFldName);
  287.     Assert(pCFDlg);
  288.     
  289.     if(!m_pmdb)
  290.     {
  291.         hr = HrOpenMDB(pCFDlg);
  292.         if(FAILED(hr))
  293.             goto err;
  294.     }
  295.     Assert(m_pmdb);
  296.     
  297.     if(!m_pfld)
  298.     {
  299.         hr = HrOpenFolder(pCFDlg);
  300.         if(FAILED(hr))
  301.             goto err;
  302.     }
  303.     Assert(m_pmdb);
  304.     
  305.     hr = m_pfld->CreateFolder(FOLDER_GENERIC, szFldName, NULL,
  306.                                 NULL, 0, &pfldNew);
  307.     if(HR_FAILED(hr))
  308.     {
  309.         pCFDlg->m_lsterr.HrSetLastError(hr, m_pfld);
  310.         pCFDlg->m_lsterr.ShowError(pCFDlg->hwDialog());
  311.         goto err;
  312.     }
  313.     if(!m_pval[iSubfldrs].Value.b)
  314.     {
  315.         m_pval[iSubfldrs].Value.b = TRUE;
  316.         TV_ITEM tvI;
  317.         tvI.hItem           = m_htiMe;
  318.         tvI.mask            = TVIF_CHILDREN;
  319.         tvI.cChildren       = 1;
  320.         TreeView_SetItem(pCFDlg->hwTreeCtl(), &tvI);
  321.     }
  322.     if(m_fKidsLoaded)
  323.     {
  324.         hr = MAPIAllocateBuffer(sizeof(SPropValue)* nhtProps, (LPVOID *)&pval);
  325.         if(hr)
  326.             goto err;
  327.         ZeroMemory(pval, sizeof(SPropValue) * nhtProps );
  328.         pval[iEID].ulPropTag = PR_ENTRYID;
  329.         pval[iDispName].ulPropTag = PR_DISPLAY_NAME;
  330.         pval[iSubfldrs].ulPropTag = PR_SUBFOLDERS;
  331.         pval[iSubfldrs].Value.b = FALSE;
  332.         int cb = lstrlen(szFldName) + 1;
  333.         hr = MAPIAllocateMore(cb, pval, (LPVOID *)&pval[iDispName].Value.lpszA);
  334.         if(hr) 
  335.             goto err;
  336.         lstrcpy(pval[iDispName].Value.lpszA, szFldName);
  337.         hr = pCFDlg->HrCreateNode(pval, nhtProps, m_pmdb, &pNode);
  338.         if(HR_FAILED(hr))
  339.             goto err;
  340.         pval = NULL;
  341.         hItem = AddOneItem(m_htiMe,  TVI_SORT, pCFDlg->IndClsdFld(),
  342.                         pCFDlg->IndOpenFld(), pCFDlg->hwTreeCtl(), pNode, 0);
  343.         if(!hItem)
  344.         {
  345.             hr = ResultFromScode(MAPI_E_NOT_ENOUGH_MEMORY);
  346.             goto err;
  347.         }
  348.             
  349.         pNode->m_pfld = pfldNew;
  350.         pfldNew = NULL;
  351.         
  352.     }
  353. err:
  354.     MAPIFreeBuffer(pval);
  355.     UlRelease(pfldNew);
  356.     DebugTraceResult(CTVNode::HrNewFolder, hr);
  357.     return hr;
  358. }
  359. //
  360. //  CTVNode::Write
  361. //
  362. // Used in CChsFldDlg::HrSaveTreeState
  363. void CTVNode::Write(BOOL fWrite, LONG iLevel, LPBYTE * ppb)
  364. {
  365.     if(fWrite)
  366.         *((LONG *)*ppb) = iLevel;
  367.     *ppb += sizeof(LONG);
  368.     if(iLevel != 0)
  369.     {
  370.         ULONG cb = m_pval[iEID].Value.bin.cb;
  371.         
  372.         if(fWrite)
  373.             *((ULONG *)*ppb) = cb;
  374.         *ppb += sizeof(ULONG);
  375.         if(fWrite)
  376.             CopyMemory(*ppb, m_pval[iEID].Value.bin.lpb, cb);
  377.         *ppb += Align4(cb);
  378.     }
  379.     else
  380.     {
  381.         Assert(m_pval[iDispName].Value.lpszA == g_szAllStores);
  382.     }
  383. }
  384. LPVOID CTVNode::operator new( size_t cb )
  385. {
  386.     LPVOID pv;
  387.     if ( MAPIAllocateBuffer( (ULONG)cb, &pv ) )
  388.         pv = NULL;
  389.     return pv; 
  390. }
  391. void CTVNode::operator delete( LPVOID pv )
  392. {
  393.     MAPIFreeBuffer( pv );
  394. }