home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / mapi / chsfld.cli / tvnode.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-11  |  10.6 KB  |  477 lines

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