home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap07 / patron / pages.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  19KB  |  868 lines

  1. /*
  2.  * PAGES.CPP
  3.  * Patron Chapter 7
  4.  *
  5.  * Implementation of the CPages class.  See PAGEWIN.CPP and PRINT.CPP
  6.  * for additional member functions.
  7.  *
  8.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Microsoft
  11.  * Internet  :  kraigb@microsoft.com
  12.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  13.  */
  14.  
  15.  
  16. #include "patron.h"
  17.  
  18.  
  19. /*
  20.  * CPages:CPages
  21.  * CPages::~CPages
  22.  *
  23.  * Constructor Parameters:
  24.  *  hInst           HINSTANCE of the application we're in.
  25.  */
  26.  
  27. CPages::CPages(HINSTANCE hInst)
  28.     : CWindow(hInst)
  29.     {
  30.     m_iPageCur=NOVALUE;  //Pages are 0 indexed, this is one before
  31.     m_cPages=0;
  32.     m_hWndPageList=NULL;
  33.     m_hFont=NULL;
  34.     m_fSystemFont=FALSE;
  35.  
  36.     //Initialize to 8.5*11 inch with .25 inch margins as a default.
  37.     m_cx=(LOMETRIC_PER_INCH*17)/2;
  38.     m_cy=LOMETRIC_PER_INCH*11;
  39.  
  40.     m_xMarginLeft=LOMETRIC_PER_INCH/4;
  41.     m_xMarginRight=LOMETRIC_PER_INCH/4;
  42.     m_yMarginTop=LOMETRIC_PER_INCH/4;
  43.     m_yMarginBottom=LOMETRIC_PER_INCH/4;
  44.  
  45.     m_xPos=0L;
  46.     m_yPos=0L;
  47.  
  48.     m_dwIDNext=0;
  49.  
  50.     //CHAPTER7MOD
  51.     //m_hDevMode removed
  52.  
  53.     m_pIStorage=NULL;
  54.     //End CHAPTER7MOD
  55.  
  56.     return;
  57.     }
  58.  
  59.  
  60. CPages::~CPages(void)
  61.     {
  62.     //CHAPTER7MOD
  63.     //Ensure memory cleaned up in list; do final IStorage::Release
  64.     StorageSet(NULL, FALSE, FALSE);
  65.     //End CHAPTER7MOD
  66.  
  67.     if (NULL!=m_hFont && !m_fSystemFont)
  68.         DeleteObject(m_hFont);
  69.  
  70.     if (NULL!=m_hWndPageList)
  71.         DestroyWindow(m_hWndPageList);
  72.  
  73.     return;
  74.     }
  75.  
  76.  
  77.  
  78.  
  79.  
  80. /*
  81.  * CPages::Init
  82.  *
  83.  * Purpose:
  84.  *  Instantiates a pages window within a given parent.  The
  85.  *  parent may be a main application window, could be an MDI child
  86.  *  window. We really do not care.
  87.  *
  88.  * Parameters:
  89.  *  hWndParent      HWND of the parent of this window
  90.  *  pRect           LPRECT that this window should occupy
  91.  *  dwStyle         DWORD containing the window's style flags.
  92.  *                  Should contain WS_CHILD | WS_VISIBLE in
  93.  *                  typical circumstances.
  94.  *  uID             UINT ID to associate with this window
  95.  *  pv              LPVOID unused for now.
  96.  *
  97.  * Return Value:
  98.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  99.  */
  100.  
  101. BOOL CPages::Init(HWND hWndParent, LPRECT pRect, DWORD dwStyle
  102.     , UINT uID, LPVOID pv)
  103.     {
  104.     int     cy;
  105.  
  106.     m_hWnd=CreateWindowEx(WS_EX_NOPARENTNOTIFY, SZCLASSPAGES
  107.         , SZCLASSPAGES, dwStyle, pRect->left, pRect->top
  108.         , pRect->right-pRect->left, pRect->bottom-pRect->top
  109.         , hWndParent, (HMENU)uID, m_hInst, this);
  110.  
  111.     if (NULL==m_hWnd)
  112.         return FALSE;
  113.  
  114.     /*
  115.      * Create the hidden listbox we'll use to track pages.  We give
  116.      * it the owner-draw style so we can just store pointers in it.
  117.      */
  118.     m_hWndPageList=CreateWindow(TEXT("listbox"), TEXT("Page List")
  119.         , WS_POPUP | LBS_OWNERDRAWFIXED, 0, 0, 100, 100
  120.         , HWND_DESKTOP, NULL, m_hInst, NULL);
  121.  
  122.     if (NULL==m_hWndPageList)
  123.         return FALSE;
  124.  
  125.     //Create a 14 point Arial font, or use the system variable font.
  126.     cy=MulDiv(-14, LOMETRIC_PER_INCH, 72);
  127.     m_hFont=CreateFont(cy, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE
  128.         , ANSI_CHARSET, OUT_TT_PRECIS, CLIP_TT_ALWAYS, PROOF_QUALITY
  129.         , VARIABLE_PITCH | FF_SWISS, TEXT("Arial"));
  130.  
  131.     if (NULL==m_hFont)
  132.         {
  133.         m_hFont=(HFONT)GetStockObject(ANSI_VAR_FONT);
  134.         m_fSystemFont=TRUE;
  135.         }
  136.  
  137.     return TRUE;
  138.     }
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145. //CHAPTER7MOD
  146.  
  147. /*
  148.  * CPages::StorageSet
  149.  *
  150.  * Purpose:
  151.  *  Provides the document's IStorage to the pages for its own use.
  152.  *  If this is a new storage, we initalize it with streams that we
  153.  *  want to always exists.  If this is an open, then we create
  154.  *  our page list from the PageList string we wrote before.
  155.  *
  156.  * Parameters:
  157.  *  pIStorage       LPSTORAGE to the new or opened storage.  If
  158.  *                  NULL, we just clean up and exit.
  159.  *  fChange         BOOL indicating is this was a Save As operation,
  160.  *                  meaning that we have the structure already and
  161.  *                  just need to change the value of m_pIStorage.
  162.  *  fInitNew        BOOL indicating if this is a new storage or one
  163.  *                  opened from a previous save.
  164.  *
  165.  * Return Value:
  166.  *  BOOL            TRUE if successful, FALSE otherwise.
  167.  */
  168.  
  169. BOOL CPages::StorageSet(LPSTORAGE pIStorage, BOOL fChange
  170.     , BOOL fInitNew)
  171.     {
  172.     DWORD           dwMode=STGM_DIRECT | STGM_READWRITE
  173.                         | STGM_SHARE_EXCLUSIVE;
  174.     HRESULT         hr;
  175.     PCPage          pPage;
  176.     BOOL            fRet=FALSE;
  177.     ULONG           cbRead;
  178.     PAGELIST        pgList;
  179.     LPSTREAM        pIStream;
  180.     LPMALLOC        pIMalloc;
  181.     LPDWORD         pdwID;
  182.     UINT            i;
  183.  
  184.     //If we're changing saved roots, simply open current page again
  185.     if (fChange)
  186.         {
  187.         if (NULL==pIStorage)
  188.             return FALSE;
  189.  
  190.         m_pIStorage->Release();
  191.         m_pIStorage=pIStorage;
  192.         m_pIStorage->AddRef();
  193.  
  194.         PageGet(m_iPageCur, &pPage, TRUE);
  195.         return TRUE;
  196.         }
  197.  
  198.     if (NULL!=m_hWndPageList)
  199.         {
  200.         //On new or open, clean out whatever it is we have.
  201.         for (i=0; i < m_cPages; i++)
  202.             {
  203.             if (PageGet(i, &pPage, FALSE))
  204.                 delete pPage;
  205.             }
  206.  
  207.         SendMessage(m_hWndPageList, LB_RESETCONTENT, 0, 0L);
  208.         }
  209.  
  210.     if (NULL!=m_pIStorage)
  211.         m_pIStorage->Release();
  212.  
  213.     m_pIStorage=NULL;
  214.  
  215.     //If we're just cleaning up, then we're done.
  216.     if (NULL==pIStorage)
  217.         return TRUE;
  218.  
  219.     m_pIStorage=pIStorage;
  220.     m_pIStorage->AddRef();
  221.  
  222.     //If this is a new storage, create the streams we require
  223.     if (fInitNew)
  224.         {
  225.         //Page list header.
  226.         hr=m_pIStorage->CreateStream(SZSTREAMPAGELIST, dwMode
  227.             | STGM_CREATE, 0, 0, &pIStream);
  228.  
  229.         if (FAILED(hr))
  230.             return FALSE;
  231.  
  232.         pIStream->Release();
  233.  
  234.         //Device Configuration
  235.         hr=m_pIStorage->CreateStream(SZSTREAMDEVICECONFIG, dwMode
  236.             | STGM_CREATE, 0, 0, &pIStream);
  237.  
  238.         if (FAILED(hr))
  239.             return FALSE;
  240.  
  241.         pIStream->Release();
  242.         return TRUE;
  243.         }
  244.  
  245.  
  246.     /*
  247.      * We're opening an existing file:
  248.      *  1)  Configure for the device we're on
  249.      *  2)  Read the Page List and create page entries for each.
  250.      */
  251.  
  252.     ConfigureForDevice();
  253.  
  254.     //Read the page list.
  255.     hr=m_pIStorage->OpenStream(SZSTREAMPAGELIST, NULL, dwMode, 0
  256.         , &pIStream);
  257.  
  258.     if (FAILED(hr))
  259.         return FALSE;
  260.  
  261.     if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
  262.         {
  263.         pIStream->Read(&pgList, sizeof(PAGELIST), &cbRead);
  264.         m_cPages  =(UINT)pgList.cPages;
  265.         m_iPageCur=(UINT)pgList.iPageCur;
  266.         m_dwIDNext=pgList.dwIDNext;
  267.  
  268.         fRet=TRUE;
  269.         cbRead=pgList.cPages*sizeof(DWORD);
  270.  
  271.         if (0!=cbRead)
  272.             {
  273.             pdwID=(LPDWORD)pIMalloc->Alloc(cbRead);
  274.  
  275.             if (NULL!=pdwID)
  276.                 {
  277.                 pIStream->Read(pdwID, cbRead, &cbRead);
  278.  
  279.                 for (i=0; i < m_cPages; i++)
  280.                     fRet &=PageAdd(NOVALUE, *(pdwID+i), FALSE);
  281.  
  282.                 pIMalloc->Free(pdwID);
  283.                 }
  284.             }
  285.  
  286.         pIMalloc->Release();
  287.         }
  288.  
  289.     pIStream->Release();
  290.  
  291.     if (!fRet)
  292.         return FALSE;
  293.  
  294.     PageGet(m_iPageCur, &pPage, TRUE);
  295.  
  296.     InvalidateRect(m_hWnd, NULL, FALSE);
  297.     UpdateWindow(m_hWnd);
  298.  
  299.     return TRUE;
  300.     }
  301.  
  302.  
  303.  
  304.  
  305.  
  306. /*
  307.  * CPages::StorageUpdate
  308.  *
  309.  * Purpose:
  310.  *  Insures that all pages are committed before a root save.
  311.  *
  312.  * Parameters:
  313.  *  fCloseAll       BOOL directing us to close all open storages
  314.  *                  and streams.
  315.  *
  316.  * Return Value:
  317.  *  BOOL            TRUE if successful, FALSE otherwise.
  318.  */
  319.  
  320. BOOL CPages::StorageUpdate(BOOL fCloseAll)
  321.     {
  322.     PCPage          pPage;
  323.     LPSTREAM        pIStream;
  324.     LPMALLOC        pIMalloc;
  325.     LPDWORD         pdwID;
  326.     ULONG           cb;
  327.     HRESULT         hr;
  328.     PAGELIST        pgList;
  329.     BOOL            fRet=FALSE;
  330.     UINT            i;
  331.  
  332.     //We only need to close the current page--nothing else is open.
  333.     if (PageGet(m_iPageCur, &pPage, FALSE))
  334.         {
  335.         pPage->Update();
  336.  
  337.         if (fCloseAll)
  338.             pPage->Close(FALSE);
  339.         }
  340.  
  341.     //We don't hold anything else open, so write the page list.
  342.     hr=m_pIStorage->OpenStream(SZSTREAMPAGELIST, NULL, STGM_DIRECT
  343.         | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pIStream);
  344.  
  345.     if (FAILED(hr))
  346.         return FALSE;
  347.  
  348.     if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
  349.         {
  350.         pgList.cPages=m_cPages;
  351.         pgList.iPageCur=m_iPageCur;
  352.         pgList.dwIDNext=m_dwIDNext;
  353.  
  354.         pIStream->Write(&pgList, sizeof(PAGELIST), &cb);
  355.  
  356.         cb=m_cPages*sizeof(DWORD);
  357.         pdwID=(LPDWORD)pIMalloc->Alloc(cb);
  358.  
  359.         if (NULL!=pdwID)
  360.             {
  361.             for (i=0; i < m_cPages; i++)
  362.                 {
  363.                 PageGet(i, &pPage, FALSE);
  364.                 *(pdwID+i)=pPage->GetID();
  365.                 }
  366.  
  367.             pIStream->Write(pdwID, cb, &cb);
  368.             pIMalloc->Free(pdwID);
  369.             fRet=TRUE;
  370.             }
  371.         pIMalloc->Release();
  372.         }
  373.  
  374.     pIStream->Release();
  375.     return fRet;
  376.     }
  377.  
  378.  
  379. //End CHAPTER7MOD
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386. /*
  387.  * CPages::RectGet
  388.  *
  389.  * Purpose:
  390.  *  Returns the rectangle of the Pages window in parent coordinates.
  391.  *
  392.  * Parameters:
  393.  *  pRect           LPRECT in which to return the rectangle.
  394.  *
  395.  * Return Value:
  396.  *  None
  397.  */
  398.  
  399. void CPages::RectGet(LPRECT pRect)
  400.     {
  401.     RECT        rc;
  402.     POINT       pt;
  403.  
  404.     //Retrieve the size of our rectangle in parent coordinates.
  405.     GetWindowRect(m_hWnd, &rc);
  406.     //CHAPTER7MOD
  407.     SETPOINT(pt, rc.left, rc.top);
  408.     //End CHAPTER7MOD
  409.     ScreenToClient(GetParent(m_hWnd), &pt);
  410.  
  411.     SetRect(pRect, pt.x, pt.y, pt.x+(rc.right-rc.left)
  412.         , pt.y+(rc.bottom-rc.top));
  413.  
  414.     return;
  415.     }
  416.  
  417.  
  418.  
  419.  
  420.  
  421.  
  422. /*
  423.  * CPages::RectSet
  424.  *
  425.  * Purpose:
  426.  *  Sets a new rectangle for the Pages window which sizes to fit.
  427.  *  Coordinates are given in parent terms.
  428.  *
  429.  * Parameters:
  430.  *  pRect           LPRECT containing the new rectangle.
  431.  *  fNotify         BOOL indicating if we're to notify anyone of
  432.  *                  the change.
  433.  *
  434.  * Return Value:
  435.  *  None
  436.  */
  437.  
  438. void CPages::RectSet(LPRECT pRect, BOOL fNotify)
  439.     {
  440.     UINT        cx, cy;
  441.  
  442.     if (NULL==pRect)
  443.         return;
  444.  
  445.     cx=pRect->right-pRect->left;
  446.     cy=pRect->bottom-pRect->top;
  447.  
  448.     SetWindowPos(m_hWnd, NULL, pRect->left, pRect->top
  449.         , (UINT)cx, (UINT)cy, SWP_NOZORDER);
  450.  
  451.     UpdateScrollRanges();
  452.     return;
  453.     }
  454.  
  455.  
  456.  
  457.  
  458. /*
  459.  * CPages::SizeGet
  460.  *
  461.  * Purpose:
  462.  *  Retrieves the size of the pages window in parent coordinates.
  463.  *
  464.  * Parameters:
  465.  *  pRect           LPRECT in which to return the size.  The right
  466.  *                  and bottom fields will contain the dimensions.
  467.  *
  468.  * Return Value:
  469.  *  None
  470.  */
  471.  
  472. void CPages::SizeGet(LPRECT pRect)
  473.     {
  474.     RectGet(pRect);
  475.     return;
  476.     }
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484. /*
  485.  * CPages::SizeSet
  486.  *
  487.  * Purpose:
  488.  *  Sets a new size in parent coordinates for the Pages window.
  489.  *
  490.  * Parameters:
  491.  *  pRect           LPRECT containing the new rectangle.
  492.  *  fNotify         BOOL indicating if we're to notify anyone of
  493.  *                  the change.
  494.  *
  495.  * Return Value:
  496.  *  None
  497.  */
  498.  
  499. void CPages::SizeSet(LPRECT pRect, BOOL fNotify)
  500.     {
  501.     UINT        cx, cy;
  502.  
  503.     if (NULL==pRect)
  504.         return;
  505.  
  506.     cx=pRect->right-pRect->left;
  507.     cy=pRect->bottom-pRect->top;
  508.  
  509.     SetWindowPos(m_hWnd, NULL, 0, 0, (UINT)cx, (UINT)cy
  510.         , SWP_NOMOVE | SWP_NOZORDER);
  511.  
  512.     UpdateScrollRanges();
  513.     return;
  514.     }
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521. /*
  522.  * CPages::ActivePage
  523.  *
  524.  * Purpose:
  525.  *  Returns a CPage pointer to the current page.
  526.  *
  527.  * Parameters:
  528.  *  None
  529.  *
  530.  * Return Value:
  531.  *  PCPage          Pointer to the current page.
  532.  */
  533.  
  534. PCPage CPages::ActivePage(void)
  535.     {
  536.     PCPage      pPage;
  537.     BOOL        fRet;
  538.  
  539.     fRet=PageGet(m_iPageCur, &pPage, FALSE);
  540.     return fRet ? pPage : NULL;
  541.     }
  542.  
  543.  
  544.  
  545.  
  546.  
  547. /*
  548.  * CPages::PageInsert
  549.  *
  550.  * Purpose:
  551.  *  Creates a new page immediately after the current page.  If
  552.  *  there are no pages then this creates page 1.
  553.  *
  554.  * Parameters:
  555.  *  uReserved       UINT unused
  556.  *
  557.  * Return Value:
  558.  *  UINT            Index of the new page, 0 on failure.
  559.  */
  560.  
  561. UINT CPages::PageInsert(UINT uReserved)
  562.     {
  563.     //CHAPTER7MOD
  564.     PCPage      pPage;
  565.  
  566.     if (0!=m_cPages)
  567.         {
  568.         //Close the current page, committing changes.
  569.         if (!PageGet(m_iPageCur, &pPage, FALSE))
  570.             return 0;
  571.  
  572.         pPage->Close(TRUE);
  573.         }
  574.     //End CHAPTER7MOD
  575.  
  576.     //Create and open the new page.
  577.     if (!PageAdd(m_iPageCur, m_dwIDNext, TRUE))
  578.         return 0;
  579.  
  580.     m_dwIDNext++;
  581.     m_iPageCur++;
  582.     m_cPages++;
  583.  
  584.     InvalidateRect(m_hWnd, NULL, FALSE);
  585.     UpdateWindow(m_hWnd);
  586.     return m_iPageCur;
  587.     }
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595. /*
  596.  * CPages::PageDelete
  597.  *
  598.  * Removes the current page from the page list.
  599.  *
  600.  * Parameters:
  601.  *  uReserved       UINT unused
  602.  *
  603.  * Return Value:
  604.  *  UINT            Index to the now current page from the page
  605.  *                  list, NOVALUE on error.
  606.  */
  607.  
  608. UINT CPages::PageDelete(UINT uReserved)
  609.     {
  610.     PCPage      pPage;
  611.  
  612.     if (!PageGet(m_iPageCur, &pPage, FALSE))
  613.         return NOVALUE;
  614.  
  615.     //Delete the page in storage, memory, and the listbox.
  616.     SendMessage(m_hWndPageList, LB_DELETESTRING, m_iPageCur, 0L);
  617.  
  618.     //CHAPTER7MOD
  619.     pPage->Destroy(m_pIStorage);
  620.     //End CHAPTER7MOD
  621.  
  622.     delete pPage;   //Does final pPage->Close
  623.  
  624.     /*
  625.      * If this is the last page then the current is one less.  If
  626.      * it's the only page the current is zero.  Otherwise the
  627.      * current is the next page.
  628.      */
  629.  
  630.     if (m_iPageCur==m_cPages-1)   //Covers last or only page.
  631.         m_iPageCur--;
  632.  
  633.     m_cPages--;
  634.  
  635.     //Insure the new visible page is open.
  636.     if (0!=m_cPages)
  637.         {
  638.         //CHAPTER7MOD
  639.         PageGet(m_iPageCur, &pPage, TRUE);
  640.         //End CHAPTER7MOD
  641.         InvalidateRect(m_hWnd, NULL, FALSE);
  642.         }
  643.     else
  644.         InvalidateRect(m_hWnd, NULL, TRUE);
  645.  
  646.     UpdateWindow(m_hWnd);
  647.     return m_iPageCur;
  648.     }
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655. /*
  656.  * CPages::CurPageGet
  657.  *
  658.  * Purpose:
  659.  *  Retrieves the index of the current page we're viewing.
  660.  *
  661.  * Parameters:
  662.  *  None
  663.  *
  664.  * Return Value:
  665.  *  UINT            Index of the current page.
  666.  */
  667.  
  668. UINT CPages::CurPageGet(void)
  669.     {
  670.     return m_iPageCur;
  671.     }
  672.  
  673.  
  674.  
  675.  
  676.  
  677. /*
  678.  * CPages::CurPageSet
  679.  *
  680.  * Purpose:
  681.  *  Sets the index of the current page to view.
  682.  *
  683.  * Parameters:
  684.  *  iPage           UINT index of the page to view. 0 means first
  685.  *                  page, NOVALUE means last page.
  686.  *
  687.  * Return Value:
  688.  *  UINT            Index of the previous current page, NOVALUE on
  689.  *                  error.
  690.  */
  691.  
  692. UINT CPages::CurPageSet(UINT iPage)
  693.     {
  694.     UINT    iPageNew;
  695.     UINT    iPagePrev=m_iPageCur;
  696.     //CHAPTER7MOD
  697.     PCPage  pPage;
  698.     //End CHAPTER7MOD
  699.  
  700.     switch (iPage)
  701.         {
  702.         case 0:
  703.             iPageNew=0;
  704.             break;
  705.  
  706.         case NOVALUE:
  707.             iPageNew=m_cPages-1;
  708.             break;
  709.  
  710.         default:
  711.             if (iPage >= m_cPages)
  712.                 iPage=0;
  713.  
  714.             iPageNew=iPage;
  715.             break;
  716.         }
  717.  
  718.     //No reason to switch to the same page.
  719.     if (iPagePrev==iPageNew)
  720.         return iPage;
  721.  
  722.     //CHAPTER7MOD
  723.     //Close the old page committing changes.
  724.     if (!PageGet(iPagePrev, &pPage, FALSE))
  725.         return NOVALUE;
  726.  
  727.     pPage->Close(TRUE);
  728.     //End CHAPTER7MOD
  729.  
  730.     m_iPageCur=iPageNew;
  731.  
  732.     //CHAPTER7MOD
  733.     //Open the new page.
  734.     PageGet(m_iPageCur, &pPage, TRUE);
  735.     //End CHAPTER7MOD
  736.  
  737.     InvalidateRect(m_hWnd, NULL, FALSE);
  738.     UpdateWindow(m_hWnd);
  739.     return iPagePrev;
  740.     }
  741.  
  742.  
  743.  
  744.  
  745.  
  746. /*
  747.  * CPages::NumPagesGet
  748.  *
  749.  * Purpose:
  750.  *  Returns the number of pages this object current contains.
  751.  *
  752.  * Parameters:
  753.  *  None
  754.  *
  755.  * Return Value:
  756.  *  UINT            Number of pages we contain.
  757.  */
  758.  
  759. UINT CPages::NumPagesGet(void)
  760.     {
  761.     return m_cPages;
  762.     }
  763.  
  764.  
  765.  
  766.  
  767.  
  768. /*
  769.  * CPages::PageGet
  770.  * (Protected)
  771.  *
  772.  * Purpose:
  773.  *  Returns a page of a given index returning a BOOL so it's simple
  774.  *  to use this function inside if statements.
  775.  *
  776.  * Parameters:
  777.  *  iPage           UINT page to retrieve 0 based.
  778.  *  ppPage          PCPage * in which to return the page pointer
  779.  *  fOpen           BOOL indicating if we should open this page as
  780.  *                  well.
  781.  *
  782.  * Return Value:
  783.  *  BOOL            TRUE if successful, FALSE otherwise.
  784.  */
  785.  
  786. //CHAPTER7MOD
  787. BOOL CPages::PageGet(UINT iPage, PCPage *ppPage, BOOL fOpen)
  788.     {
  789.     if (NULL==ppPage)
  790.         return FALSE;
  791.  
  792.     if (LB_ERR!=SendMessage(m_hWndPageList, LB_GETTEXT
  793.         , iPage, (LONG)ppPage))
  794.         {
  795.         if (fOpen)
  796.             (*ppPage)->Open(m_pIStorage);
  797.  
  798.         return TRUE;
  799.         }
  800.  
  801.     return FALSE;
  802.     }
  803. //End CHAPTER7MOD
  804.  
  805.  
  806.  
  807.  
  808.  
  809. /*
  810.  * CPages::PageAdd
  811.  * (Protected)
  812.  *
  813.  * Purpose:
  814.  *  Creates a new page initialized to the given values.  The new
  815.  *  page's storage is created if it does not already exist.  If
  816.  *  fOpenStorage is set the page's storage is opened and left
  817.  *  opened.
  818.  *
  819.  * Parameters:
  820.  *  iPage           UINT Location at which to insert page; new page
  821.  *                  is inserted after this position.  NOVALUE for
  822.  *                  the end.
  823.  *  dwID            DWORD ID for this page.
  824.  *  fOpenStorage    BOOL indicating if we're to leave the storage
  825.  *                  open.
  826.  *
  827.  * Return Value:
  828.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  829.  */
  830.  
  831. //CHAPTER7MOD
  832. BOOL CPages::PageAdd(UINT iPage, DWORD dwID, BOOL fOpenStorage)
  833.     {
  834. //End CHAPTER7MOD
  835.     PCPage      pPage;
  836.     LRESULT     lr;
  837.  
  838.     pPage=new CPage(dwID);
  839.  
  840.     if (NULL==pPage)
  841.         return FALSE;
  842.  
  843.     //CHAPTER7MOD
  844.     if (fOpenStorage)
  845.         pPage->Open(m_pIStorage);
  846.     //End CHAPTER7MOD
  847.  
  848.     if (NOVALUE==iPage)
  849.         iPage--;
  850.  
  851.     //Now try to add to the listbox.
  852.     lr=SendMessage(m_hWndPageList, LB_INSERTSTRING, iPage+1
  853.         , (LONG)pPage);
  854.  
  855.     if (LB_ERRSPACE==lr)
  856.         {
  857.         //CHAPTER7MOD
  858.         if (fOpenStorage)
  859.             pPage->Close(FALSE);
  860.         //End CHAPTER7MOD
  861.  
  862.         delete pPage;
  863.         return FALSE;
  864.         }
  865.  
  866.     return TRUE;
  867.     }
  868.