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 / chap24 / patron / pages.cpp < prev    next >
C/C++ Source or Header  |  1995-05-04  |  29KB  |  1,365 lines

  1. /*
  2.  * PAGES.CPP
  3.  * Patron Chapter 24
  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.  *  cf              UINT application clipboard format.
  26.  */
  27.  
  28. CPages::CPages(HINSTANCE hInst, UINT cf)
  29.     : CWindow(hInst)
  30.     {
  31.     m_pPageCur=NULL;
  32.     m_iPageCur=NOVALUE;  //Pages are 0 indexed, this is one before
  33.     m_cPages=0;
  34.     m_hWndPageList=NULL;
  35.     m_hFont=NULL;
  36.     m_fSystemFont=FALSE;
  37.  
  38.     //Initialize to 8.5*11 inch with .25 inch margins as a default.
  39.     m_cx=(LOMETRIC_PER_INCH*17)/2;
  40.     m_cy=LOMETRIC_PER_INCH*11;
  41.  
  42.     m_xMarginLeft=LOMETRIC_PER_INCH/4;
  43.     m_xMarginRight=LOMETRIC_PER_INCH/4;
  44.     m_yMarginTop=LOMETRIC_PER_INCH/4;
  45.     m_yMarginBottom=LOMETRIC_PER_INCH/4;
  46.  
  47.     m_xPos=0L;
  48.     m_yPos=0L;
  49.  
  50.     m_dwIDNext=0;
  51.     m_pIStorage=NULL;
  52.  
  53.     m_fDirty=FALSE;
  54.     m_cf=cf;
  55.  
  56.     m_fDragSource=FALSE;
  57.     m_fMoveInPage=FALSE;
  58.     m_fLinkAllowed=FALSE;
  59.  
  60.     m_fDragRectShown=FALSE;
  61.  
  62.     m_uScrollInset=GetProfileInt(TEXT("windows")
  63.         , TEXT("DragScrollInset"), DD_DEFSCROLLINSET);
  64.  
  65.     m_uScrollDelay=GetProfileInt(TEXT("windows")
  66.         , TEXT("DragScrollDelay"), DD_DEFSCROLLDELAY);
  67.  
  68.     m_uHScrollCode=0;
  69.     m_uVScrollCode=0;
  70.     m_fShowTypes=FALSE;
  71.     m_pmkFile=NULL;
  72.  
  73.     m_fAddUI=FALSE;
  74.     //CHAPTER24MOD
  75.     m_fDesignMode=FALSE;
  76.     m_fUIDead=FALSE;
  77.     m_fHatchHandles=TRUE;
  78.     m_pIFont=NULL;
  79.     //End CHAPTER24MOD
  80.     return;
  81.     }
  82.  
  83.  
  84. CPages::~CPages(void)
  85.     {
  86.     //Ensure memory cleaned up in list; do final IStorage::Release
  87.     StorageSet(NULL, FALSE, FALSE);
  88.  
  89.     ReleaseInterface(m_pmkFile);
  90.  
  91.     //CHAPTER24MOD
  92.     ReleaseInterface(m_pIFont);
  93.     //End CHAPTER24MOD
  94.  
  95.     if (NULL!=m_hFont && !m_fSystemFont)
  96.         DeleteObject(m_hFont);
  97.  
  98.     if (NULL!=m_hWndPageList)
  99.         DestroyWindow(m_hWndPageList);
  100.  
  101.     //m_hWnd destroyed with the document.
  102.     return;
  103.     }
  104.  
  105.  
  106.  
  107. /*
  108.  * CPages::FIsDirty
  109.  *
  110.  * Purpose:
  111.  *  Tells the caller (document) if anything's happened to dirty us.
  112.  *
  113.  * Parameters:
  114.  *  None
  115.  *
  116.  * Return Value:
  117.  *  None
  118.  */
  119.  
  120. BOOL CPages::FIsDirty(void)
  121.     {
  122.     return m_fDirty;
  123.     }
  124.  
  125.  
  126.  
  127. /*
  128.  * CPages::Init
  129.  *
  130.  * Purpose:
  131.  *  Instantiates a pages window within a given parent.  The
  132.  *  parent may be a main application window, could be an MDI child
  133.  *  window. We really do not care.
  134.  *
  135.  * Parameters:
  136.  *  hWndParent      HWND of the parent of this window
  137.  *  pRect           LPRECT that this window should occupy
  138.  *  dwStyle         DWORD containing the window's style flags.
  139.  *                  Should contain WS_CHILD | WS_VISIBLE in
  140.  *                  typical circumstances.
  141.  *  uID             UINT ID to associate with this window
  142.  *  pv              LPVOID unused for now.
  143.  *
  144.  * Return Value:
  145.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  146.  */
  147.  
  148. BOOL CPages::Init(HWND hWndParent, LPRECT pRect, DWORD dwStyle
  149.     , UINT uID, LPVOID pv)
  150.     {
  151.     int         cy;
  152.     //CHAPTER24MOD
  153.     FONTDESC    fd={sizeof(FONTDESC), OLETEXT("Arial")
  154.                     , FONTSIZE(14), FW_NORMAL, DEFAULT_CHARSET
  155.                     , FALSE, FALSE, FALSE};
  156.     //End CHAPTER24MOD
  157.  
  158.     m_hWnd=CreateWindowEx(WS_EX_NOPARENTNOTIFY, SZCLASSPAGES
  159.         , SZCLASSPAGES, dwStyle, pRect->left, pRect->top
  160.         , pRect->right-pRect->left, pRect->bottom-pRect->top
  161.         , hWndParent, (HMENU)uID, m_hInst, this);
  162.  
  163.     if (NULL==m_hWnd)
  164.         return FALSE;
  165.  
  166.     /*
  167.      * Create the hidden listbox we'll use to track pages.  We give
  168.      * it the owner-draw style so we can just store pointers in it.
  169.      */
  170.     m_hWndPageList=CreateWindow(TEXT("listbox"), TEXT("Page List")
  171.         , WS_POPUP | LBS_OWNERDRAWFIXED, 0, 0, 100, 100
  172.         , HWND_DESKTOP, NULL, m_hInst, NULL);
  173.  
  174.     if (NULL==m_hWndPageList)
  175.         return FALSE;
  176.  
  177.     cy=MulDiv(-14, LOMETRIC_PER_INCH, 72);
  178.     m_hFont=CreateFont(cy, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE
  179.         , ANSI_CHARSET, OUT_TT_PRECIS, CLIP_TT_ALWAYS, PROOF_QUALITY
  180.         , VARIABLE_PITCH | FF_SWISS, TEXT("Arial"));
  181.  
  182.     if (NULL==m_hFont)
  183.         {
  184.         m_hFont=(HFONT)GetStockObject(ANSI_VAR_FONT);
  185.         m_fSystemFont=TRUE;
  186.         }
  187.  
  188.     //CHAPTER24MOD
  189.     //Need a standard font object for ambient properties
  190.     OleCreateFontIndirect(&fd, IID_IFontDisp, (void **)&m_pIFont);
  191.     //End CHAPTER24MOD
  192.  
  193.     return TRUE;
  194.     }
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201. /*
  202.  * CPages::StorageSet
  203.  *
  204.  * Purpose:
  205.  *  Provides the document's IStorage to the pages for its own use.
  206.  *  If this is a new storage, we initalize it with streams that we
  207.  *  want to always exists.  If this is an open, then we create
  208.  *  our page list from the PageList string we wrote before.
  209.  *
  210.  * Parameters:
  211.  *  pIStorage       LPSTORAGE to the new or opened storage.  If
  212.  *                  NULL, we just clean up and exit.
  213.  *  fChange         BOOL indicating is this was a Save As operation,
  214.  *                  meaning that we have the structure already and
  215.  *                  just need to change the value of m_pIStorage.
  216.  *  fInitNew        BOOL indicating if this is a new storage or one
  217.  *                  opened from a previous save.
  218.  *
  219.  * Return Value:
  220.  *  BOOL            TRUE if successful, FALSE otherwise.
  221.  */
  222.  
  223. BOOL CPages::StorageSet(LPSTORAGE pIStorage, BOOL fChange
  224.     , BOOL fInitNew)
  225.     {
  226.     DWORD           dwMode=STGM_DIRECT | STGM_READWRITE
  227.                         | STGM_SHARE_EXCLUSIVE;
  228.     HRESULT         hr;
  229.     PCPage          pPage;
  230.     BOOL            fRet=FALSE;
  231.     ULONG           cbRead;
  232.     PAGELIST        pgList;
  233.     LPSTREAM        pIStream;
  234.     LPMALLOC        pIMalloc;
  235.     LPDWORD         pdwID;
  236.     UINT            i;
  237.  
  238.     //If we're changing saved roots, simply open current page again
  239.     if (fChange)
  240.         {
  241.         if (NULL==pIStorage)
  242.             return FALSE;
  243.  
  244.         m_pIStorage->Release();
  245.         m_pIStorage=pIStorage;
  246.         m_pIStorage->AddRef();
  247.  
  248.         PageGet(m_iPageCur, &m_pPageCur, TRUE);
  249.         m_fDirty=FALSE;
  250.         return TRUE;
  251.         }
  252.  
  253.     if (NULL!=m_hWndPageList)
  254.         {
  255.         //On new or open, clean out whatever it is we have.
  256.         for (i=0; i < m_cPages; i++)
  257.             {
  258.             if (PageGet(i, &pPage, FALSE))
  259.                 pPage->Release();
  260.             }
  261.  
  262.         SendMessage(m_hWndPageList, LB_RESETCONTENT, 0, 0L);
  263.         }
  264.  
  265.     if (NULL!=m_pIStorage)
  266.         m_pIStorage->Release();
  267.  
  268.     m_pIStorage=NULL;
  269.  
  270.     //If we're just cleaning up, then we're done.
  271.     if (NULL==pIStorage)
  272.         return TRUE;
  273.  
  274.     m_pIStorage=pIStorage;
  275.     m_pIStorage->AddRef();
  276.  
  277.     //If this is a new storage, create the streams we require
  278.     if (fInitNew)
  279.         {
  280.         //Page list header.
  281.         hr=m_pIStorage->CreateStream(SZSTREAMPAGELIST, dwMode
  282.             | STGM_CREATE, 0, 0, &pIStream);
  283.  
  284.         if (FAILED(hr))
  285.             return FALSE;
  286.  
  287.         pIStream->Release();
  288.  
  289.         //Device Configuration
  290.         hr=m_pIStorage->CreateStream(SZSTREAMDEVICECONFIG, dwMode
  291.             | STGM_CREATE, 0, 0, &pIStream);
  292.  
  293.         if (FAILED(hr))
  294.             return FALSE;
  295.  
  296.         pIStream->Release();
  297.         return TRUE;
  298.         }
  299.  
  300.  
  301.     /*
  302.      * We're opening an existing file:
  303.      *  1)  Configure for the device we're on
  304.      *  2)  Read the Page List and create page entries for each.
  305.      */
  306.  
  307.     ConfigureForDevice();
  308.  
  309.     //Read the page list.
  310.     hr=m_pIStorage->OpenStream(SZSTREAMPAGELIST, NULL, dwMode, 0
  311.         , &pIStream);
  312.  
  313.     if (FAILED(hr))
  314.         return FALSE;
  315.  
  316.     if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
  317.         {
  318.         pIStream->Read(&pgList, sizeof(PAGELIST), &cbRead);
  319.         m_cPages  =(UINT)pgList.cPages;
  320.         m_iPageCur=(UINT)pgList.iPageCur;
  321.         m_dwIDNext=pgList.dwIDNext;
  322.  
  323.         fRet=TRUE;
  324.         cbRead=pgList.cPages*sizeof(DWORD);
  325.  
  326.         if (0!=cbRead)
  327.             {
  328.             pdwID=(LPDWORD)pIMalloc->Alloc(cbRead);
  329.  
  330.             if (NULL!=pdwID)
  331.                 {
  332.                 pIStream->Read(pdwID, cbRead, &cbRead);
  333.  
  334.                 for (i=0; i < m_cPages; i++)
  335.                     fRet &=PageAdd(NOVALUE, *(pdwID+i), FALSE);
  336.  
  337.                 pIMalloc->Free(pdwID);
  338.                 }
  339.             }
  340.  
  341.         pIMalloc->Release();
  342.         }
  343.  
  344.     pIStream->Release();
  345.  
  346.     if (!fRet)
  347.         return FALSE;
  348.  
  349.     PageGet(m_iPageCur, &m_pPageCur, TRUE);
  350.     m_fDirty=FALSE;
  351.  
  352.     InvalidateRect(m_hWnd, NULL, FALSE);
  353.     UpdateWindow(m_hWnd);
  354.  
  355.     return TRUE;
  356.     }
  357.  
  358.  
  359.  
  360.  
  361.  
  362. /*
  363.  * CPages::StorageUpdate
  364.  *
  365.  * Purpose:
  366.  *  Insures that all pages are committed before a root save.
  367.  *
  368.  * Parameters:
  369.  *  fCloseAll       BOOL directing us to close all open storages
  370.  *                  and streams.
  371.  *
  372.  * Return Value:
  373.  *  BOOL            TRUE if successful, FALSE otherwise.
  374.  */
  375.  
  376. BOOL CPages::StorageUpdate(BOOL fCloseAll)
  377.     {
  378.     PCPage          pPage;
  379.     LPSTREAM        pIStream;
  380.     LPMALLOC        pIMalloc;
  381.     LPDWORD         pdwID;
  382.     ULONG           cb;
  383.     HRESULT         hr;
  384.     PAGELIST        pgList;
  385.     BOOL            fRet=FALSE;
  386.     UINT            i;
  387.  
  388.     //We only need to close the current page--nothing else is open.
  389.     if (NULL!=m_pPageCur)
  390.         {
  391.         m_pPageCur->Update();
  392.  
  393.         if (fCloseAll)
  394.             m_pPageCur->Close(FALSE);
  395.         }
  396.  
  397.     //We don't hold anything else open, so write the page list.
  398.     hr=m_pIStorage->OpenStream(SZSTREAMPAGELIST, NULL, STGM_DIRECT
  399.         | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pIStream);
  400.  
  401.     if (FAILED(hr))
  402.         return FALSE;
  403.  
  404.     if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pIMalloc)))
  405.         {
  406.         pgList.cPages=m_cPages;
  407.         pgList.iPageCur=m_iPageCur;
  408.         pgList.dwIDNext=m_dwIDNext;
  409.  
  410.         pIStream->Write(&pgList, sizeof(PAGELIST), &cb);
  411.  
  412.         cb=m_cPages*sizeof(DWORD);
  413.         pdwID=(LPDWORD)pIMalloc->Alloc(cb);
  414.  
  415.         if (NULL!=pdwID)
  416.             {
  417.             for (i=0; i < m_cPages; i++)
  418.                 {
  419.                 PageGet(i, &pPage, FALSE);
  420.                 *(pdwID+i)=pPage->GetID();
  421.                 }
  422.  
  423.             pIStream->Write(pdwID, cb, &cb);
  424.             pIMalloc->Free(pdwID);
  425.             fRet=TRUE;
  426.             }
  427.         pIMalloc->Release();
  428.         }
  429.  
  430.     pIStream->Release();
  431.  
  432.     //Clean up the dirty flag when we do an update.
  433.     m_fDirty=!fRet;
  434.     return fRet;
  435.     }
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443. /*
  444.  * CPages::RectGet
  445.  *
  446.  * Purpose:
  447.  *  Returns the rectangle of the Pages window in parent coordinates.
  448.  *
  449.  * Parameters:
  450.  *  pRect           LPRECT in which to return the rectangle.
  451.  *
  452.  * Return Value:
  453.  *  None
  454.  */
  455.  
  456. void CPages::RectGet(LPRECT pRect)
  457.     {
  458.     RECT        rc;
  459.     POINT       pt;
  460.  
  461.     //Retrieve the size of our rectangle in parent coordinates.
  462.     GetWindowRect(m_hWnd, &rc);
  463.     SETPOINT(pt, rc.left, rc.top);
  464.     ScreenToClient(GetParent(m_hWnd), &pt);
  465.  
  466.     SetRect(pRect, pt.x, pt.y, pt.x+(rc.right-rc.left)
  467.         , pt.y+(rc.bottom-rc.top));
  468.  
  469.     return;
  470.     }
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477. /*
  478.  * CPages::RectSet
  479.  *
  480.  * Purpose:
  481.  *  Sets a new rectangle for the Pages window which sizes to fit.
  482.  *  Coordinates are given in parent terms.
  483.  *
  484.  * Parameters:
  485.  *  pRect           LPRECT containing the new rectangle.
  486.  *  fNotify         BOOL indicating if we're to notify anyone of
  487.  *                  the change.
  488.  *
  489.  * Return Value:
  490.  *  None
  491.  */
  492.  
  493. void CPages::RectSet(LPRECT pRect, BOOL fNotify)
  494.     {
  495.     UINT        cx, cy;
  496.  
  497.     if (NULL==pRect)
  498.         return;
  499.  
  500.     cx=pRect->right-pRect->left;
  501.     cy=pRect->bottom-pRect->top;
  502.  
  503.     SetWindowPos(m_hWnd, NULL, pRect->left, pRect->top
  504.         , (UINT)cx, (UINT)cy, SWP_NOZORDER);
  505.  
  506.     UpdateScrollRanges();
  507.     return;
  508.     }
  509.  
  510.  
  511.  
  512.  
  513. /*
  514.  * CPages::SizeGet
  515.  *
  516.  * Purpose:
  517.  *  Retrieves the size of the pages window in parent coordinates.
  518.  *
  519.  * Parameters:
  520.  *  pRect           LPRECT in which to return the size.  The right
  521.  *                  and bottom fields will contain the dimensions.
  522.  *
  523.  * Return Value:
  524.  *  None
  525.  */
  526.  
  527. void CPages::SizeGet(LPRECT pRect)
  528.     {
  529.     RectGet(pRect);
  530.     return;
  531.     }
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539. /*
  540.  * CPages::SizeSet
  541.  *
  542.  * Purpose:
  543.  *  Sets a new size in parent coordinates for the Pages window.
  544.  *
  545.  * Parameters:
  546.  *  pRect           LPRECT containing the new rectangle.
  547.  *  fNotify         BOOL indicating if we're to notify anyone of
  548.  *                  the change.
  549.  *
  550.  * Return Value:
  551.  *  None
  552.  */
  553.  
  554. void CPages::SizeSet(LPRECT pRect, BOOL fNotify)
  555.     {
  556.     UINT        cx, cy;
  557.  
  558.     if (NULL==pRect)
  559.         return;
  560.  
  561.     cx=pRect->right-pRect->left;
  562.     cy=pRect->bottom-pRect->top;
  563.  
  564.     SetWindowPos(m_hWnd, NULL, 0, 0, (UINT)cx, (UINT)cy
  565.         , SWP_NOMOVE | SWP_NOZORDER);
  566.  
  567.     UpdateScrollRanges();
  568.     return;
  569.     }
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576. /*
  577.  * CPages::ActivePage
  578.  *
  579.  * Purpose:
  580.  *  Returns a CPage pointer to the current page.
  581.  *
  582.  * Parameters:
  583.  *  None
  584.  *
  585.  * Return Value:
  586.  *  PCPage          Pointer to the current page.
  587.  */
  588.  
  589. PCPage CPages::ActivePage(void)
  590.     {
  591.     PCPage      pPage;
  592.     BOOL        fRet;
  593.  
  594.     fRet=PageGet(m_iPageCur, &pPage, FALSE);
  595.     return fRet ? pPage : NULL;
  596.     }
  597.  
  598.  
  599.  
  600.  
  601.  
  602. /*
  603.  * CPages::PageInsert
  604.  *
  605.  * Purpose:
  606.  *  Creates a new page immediately after the current page.  If
  607.  *  there are no pages then this creates page 1.
  608.  *
  609.  * Parameters:
  610.  *  uReserved       UINT unused
  611.  *
  612.  * Return Value:
  613.  *  UINT            Index of the new page, 0 on failure.
  614.  */
  615.  
  616. UINT CPages::PageInsert(UINT uReserved)
  617.     {
  618.     if (0!=m_cPages && NULL!=m_pPageCur)
  619.         {
  620.         //Close the current page, committing changes.
  621.         m_pPageCur->Close(TRUE);
  622.         }
  623.  
  624.     //Create and open the new page.
  625.     if (!PageAdd(m_iPageCur, m_dwIDNext, TRUE))
  626.         return 0;
  627.  
  628.     m_dwIDNext++;
  629.     m_iPageCur++;
  630.     m_cPages++;
  631.  
  632.     InvalidateRect(m_hWnd, NULL, FALSE);
  633.     UpdateWindow(m_hWnd);
  634.  
  635.     PageGet(m_iPageCur, &m_pPageCur, FALSE);
  636.     return m_iPageCur;
  637.     }
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645. /*
  646.  * CPages::PageDelete
  647.  *
  648.  * Removes the current page from the page list.
  649.  *
  650.  * Parameters:
  651.  *  uReserved       UINT unused
  652.  *
  653.  * Return Value:
  654.  *  UINT            Index to the now current page from the page
  655.  *                  list, NOVALUE on error.
  656.  */
  657.  
  658. UINT CPages::PageDelete(UINT uReserved)
  659.     {
  660.     PCPage      pPage;
  661.  
  662.     if (!PageGet(m_iPageCur, &pPage, FALSE))
  663.         return NOVALUE;
  664.  
  665.     //Delete the page in both the storage and in memory.
  666.     SendMessage(m_hWndPageList, LB_DELETESTRING, m_iPageCur, 0L);
  667.  
  668.     m_pPageCur->Destroy(m_pIStorage);
  669.  
  670.     m_pPageCur->Release();   //Does final pPage->Close
  671.     m_pPageCur=NULL;
  672.  
  673.     /*
  674.      * If this is the last page then the current is one less.  If
  675.      * it's the only page the current is zero.  Otherwise the
  676.      * current is the next page.
  677.      */
  678.  
  679.     if (m_iPageCur==m_cPages-1)   //Covers last or only page.
  680.         m_iPageCur--;
  681.  
  682.     m_cPages--;
  683.  
  684.     //Insure the new visible page is open.
  685.     if (0!=m_cPages)
  686.         {
  687.         PageGet(m_iPageCur, &m_pPageCur, TRUE);
  688.         InvalidateRect(m_hWnd, NULL, FALSE);
  689.         }
  690.     else
  691.         InvalidateRect(m_hWnd, NULL, TRUE);
  692.  
  693.     UpdateWindow(m_hWnd);
  694.     return m_iPageCur;
  695.     }
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702. /*
  703.  * CPages::CurPageGet
  704.  *
  705.  * Purpose:
  706.  *  Retrieves the index of the current page we're viewing.
  707.  *
  708.  * Parameters:
  709.  *  None
  710.  *
  711.  * Return Value:
  712.  *  UINT            Index of the current page.
  713.  */
  714.  
  715. UINT CPages::CurPageGet(void)
  716.     {
  717.     return m_iPageCur;
  718.     }
  719.  
  720.  
  721.  
  722.  
  723.  
  724. /*
  725.  * CPages::CurPageSet
  726.  *
  727.  * Purpose:
  728.  *  Sets the index of the current page to view.
  729.  *
  730.  * Parameters:
  731.  *  iPage           UINT index of the page to view. 0 means first
  732.  *                  page, NOVALUE means last page.
  733.  *
  734.  * Return Value:
  735.  *  UINT            Index of the previous current page, NOVALUE on
  736.  *                  error.
  737.  */
  738.  
  739. UINT CPages::CurPageSet(UINT iPage)
  740.     {
  741.     UINT    iPageNew;
  742.     UINT    iPagePrev=m_iPageCur;
  743.     PCPage  pPage;
  744.  
  745.     switch (iPage)
  746.         {
  747.         case 0:
  748.             iPageNew=0;
  749.             break;
  750.  
  751.         case NOVALUE:
  752.             iPageNew=m_cPages-1;
  753.             break;
  754.  
  755.         default:
  756.             if (iPage >= m_cPages)
  757.                 iPage=0;
  758.  
  759.             iPageNew=iPage;
  760.             break;
  761.         }
  762.  
  763.     //No reason to switch to the same page.
  764.     if (iPagePrev==iPageNew)
  765.         return iPage;
  766.  
  767.     //Close the old page committing changes.
  768.     if (!PageGet(iPagePrev, &pPage, FALSE))
  769.         return NOVALUE;
  770.  
  771.     pPage->Close(TRUE);
  772.  
  773.     m_iPageCur=iPageNew;
  774.  
  775.     //Open the new page.
  776.     PageGet(m_iPageCur, &m_pPageCur, TRUE);
  777.  
  778.     InvalidateRect(m_hWnd, NULL, FALSE);
  779.     UpdateWindow(m_hWnd);
  780.     return iPagePrev;
  781.     }
  782.  
  783.  
  784.  
  785.  
  786.  
  787. /*
  788.  * CPages::NumPagesGet
  789.  *
  790.  * Purpose:
  791.  *  Returns the number of pages this object current contains.
  792.  *
  793.  * Parameters:
  794.  *  None
  795.  *
  796.  * Return Value:
  797.  *  UINT            Number of pages we contain.
  798.  */
  799.  
  800. UINT CPages::NumPagesGet(void)
  801.     {
  802.     return m_cPages;
  803.     }
  804.  
  805.  
  806.  
  807.  
  808.  
  809. /*
  810.  * CPages::TenantCreate
  811.  * CPages::TenantDestroy
  812.  *
  813.  * Purpose:
  814.  *  Pass-throughs for CPage members on the current page.
  815.  */
  816.  
  817. BOOL CPages::TenantCreate(TENANTTYPE tType, LPVOID pv
  818.     , LPFORMATETC pFE, PPATRONOBJECT ppo, DWORD dwData)
  819.     {
  820.     BOOL    fRet;
  821.  
  822.     if (NULL==m_pPageCur)
  823.         return FALSE;
  824.  
  825.     fRet=m_pPageCur->TenantCreate(tType, pv, pFE, ppo, dwData);
  826.     m_fDirty |= fRet;
  827.     return fRet;
  828.     }
  829.  
  830.  
  831. BOOL CPages::TenantDestroy(void)
  832.     {
  833.     BOOL    fRet;
  834.  
  835.     if (NULL==m_pPageCur)
  836.         return FALSE;
  837.  
  838.     fRet=m_pPageCur->TenantDestroy();
  839.     m_fDirty |= fRet;
  840.     return fRet;
  841.     }
  842.  
  843.  
  844.  
  845. /*
  846.  * CPages::TenantClip
  847.  *
  848.  * Purpose:
  849.  *  Copies or cuts the currently selected tenant to the clipoard.
  850.  *
  851.  * Parameters:
  852.  *  fCut            BOOL TRUE to cut the object, FALSE to copy.
  853.  *
  854.  * Return Value:
  855.  *  BOOL            TRUE if successful, FALSE otherwise.
  856.  */
  857.  
  858. BOOL CPages::TenantClip(BOOL fCut)
  859.     {
  860.     BOOL    fRet;
  861.  
  862.     if (NULL==m_pPageCur)
  863.         return FALSE;
  864.  
  865.     fRet=m_pPageCur->TenantClip(fCut);
  866.     m_fDirty |= (fRet && fCut);
  867.     return fRet;
  868.     }
  869.  
  870.  
  871.  
  872.  
  873.  
  874.  
  875. /*
  876.  * CPages::FQueryObjectSelected
  877.  *
  878.  * Purpose:
  879.  *  Returns whether or not there is an object selected on this
  880.  *  page for Cut, Copy, Delete functions.
  881.  *
  882.  * Parameters:
  883.  *  hMenu           HMENU on which object related items live.
  884.  *
  885.  * Return Value:
  886.  *  BOOL            TRUE if we have an object, FALSE otherwise.
  887.  */
  888.  
  889. BOOL CPages::FQueryObjectSelected(HMENU hMenu)
  890.     {
  891.     if (NULL==m_pPageCur)
  892.         return FALSE;
  893.  
  894.     return m_pPageCur->FQueryObjectSelected(hMenu);
  895.     }
  896.  
  897.  
  898.  
  899. /*
  900.  * CPages::ActivateObject
  901.  *
  902.  * Purpose:
  903.  *  Executes a verb on the currently selected object.
  904.  *
  905.  * Parameters:
  906.  *  iVerb           LONG of the selected verb.
  907.  *  pMSG            LPMSG to whatever invoked the verb.
  908.  *
  909.  * Return Value:
  910.  *  None
  911.  */
  912.  
  913. void CPages::ActivateObject(LONG iVerb, LPMSG pMSG)
  914.     {
  915.     if (NULL==m_pPageCur)
  916.         return;
  917.  
  918.     m_pPageCur->ActivateObject(iVerb, pMSG);
  919.     return;
  920.     }
  921.  
  922.  
  923.  
  924.  
  925. //CHAPTER24MOD
  926. /*
  927.  * CPages::ToggleDesignMode
  928.  * CPages::ToggleUIDead
  929.  * CPages::ToggleHatchHandles
  930.  *
  931.  * Purpose:
  932.  *  Pass-through to CPage toggles.
  933.  */
  934.  
  935. void CPages::ToggleDesignMode(BOOL fDesign)
  936.     {
  937.     if (NULL==m_pPageCur)
  938.         return;
  939.  
  940.     m_fDesignMode=fDesign;
  941.     m_pPageCur->ToggleDesignMode(fDesign);
  942.     return;
  943.     }
  944.  
  945. void CPages::ToggleUIDead(BOOL fUIDead)
  946.     {
  947.     if (NULL==m_pPageCur)
  948.         return;
  949.  
  950.     m_fUIDead=fUIDead;
  951.     m_pPageCur->ToggleUIDead(fUIDead);
  952.     return;
  953.     }
  954.  
  955.  
  956. void CPages::ToggleHatchHandles(BOOL fHatchHandles)
  957.     {
  958.     if (NULL==m_pPageCur)
  959.         return;
  960.  
  961.     m_fHatchHandles=fHatchHandles;
  962.     m_pPageCur->ToggleHatchHandles(fHatchHandles);
  963.     return;
  964.     }
  965.  
  966.  
  967.  
  968. /*
  969.  * CPages::FQueryEnableEvents
  970.  * CPages::AssignEvents
  971.  * CPages::TryMnemonic
  972.  * CPages::FIsButton
  973.  * CPages::MarkButton
  974.  *
  975.  * Purpose:
  976.  *  Pass-throughs
  977.  */
  978.  
  979. BOOL CPages::FQueryEnableEvents(void)
  980.     {
  981.     if (NULL==m_pPageCur)
  982.         return FALSE;
  983.  
  984.     return m_pPageCur->FQueryEnableEvents();
  985.     }
  986.  
  987.  
  988. void CPages::AssignEvents(HWND hWndParent)
  989.     {
  990.     if (NULL!=m_pPageCur)
  991.         m_pPageCur->AssignEvents(hWndParent);
  992.  
  993.     return;
  994.     }
  995.  
  996.  
  997. BOOL CPages::TryMnemonic(LPMSG pMsg)
  998.     {
  999.     if (NULL!=m_pPageCur)
  1000.         return m_pPageCur->TryMnemonic(pMsg);
  1001.  
  1002.     return FALSE;
  1003.     }
  1004. //End CHAPTER24MOD
  1005.  
  1006.  
  1007.  
  1008.  
  1009. /*
  1010.  * CPages::ShowObjectTypes
  1011.  *
  1012.  * Purpose:
  1013.  *  Pass-through to CPage::ShowObjectTypes
  1014.  *
  1015.  * Parameters:
  1016.  *  fShow           BOOL indicating to show the type or not.
  1017.  *
  1018.  * Return Value:
  1019.  *  None
  1020.  */
  1021.  
  1022. void CPages::ShowObjectTypes(BOOL fShow)
  1023.     {
  1024.     if (NULL==m_pPageCur)
  1025.         return;
  1026.  
  1027.     m_fShowTypes=fShow;
  1028.     m_pPageCur->ShowObjectTypes(fShow);
  1029.     return;
  1030.     }
  1031.  
  1032.  
  1033.  
  1034.  
  1035. /*
  1036.  * CPages::NotifyTenantsOfRename
  1037.  *
  1038.  * Purpose:
  1039.  *  Pass-through to CPage to tell tenants that the document
  1040.  *  changes names.
  1041.  *
  1042.  * Parameters:
  1043.  *  pszFile         LPTSTR of the new filename.
  1044.  *  pmk             LPMONKIER to the new file moniker.
  1045.  *
  1046.  * Return Value:
  1047.  *  None
  1048.  */
  1049.  
  1050. void CPages::NotifyTenantsOfRename(LPTSTR pszFile, LPMONIKER pmk)
  1051.     {
  1052.     if (NULL==m_pPageCur)
  1053.         return;
  1054.  
  1055.     ReleaseInterface(m_pmkFile);
  1056.     m_pmkFile=pmk;
  1057.     m_pmkFile->AddRef();
  1058.     m_pPageCur->NotifyTenantsOfRename(pszFile, pmk);
  1059.     return;
  1060.     }
  1061.  
  1062.  
  1063.  
  1064.  
  1065. /*
  1066.  * CPages::FQueryLinksInPage
  1067.  *
  1068.  * Purpose:
  1069.  *  Pass through to current page to see if there are any
  1070.  *  linked objects
  1071.  *
  1072.  * Parameters:
  1073.  *  None
  1074.  *
  1075.  * Return Value:
  1076.  *  None
  1077.  */
  1078.  
  1079. BOOL CPages::FQueryLinksInPage()
  1080.     {
  1081.     if (NULL==m_pPageCur)
  1082.         return FALSE;
  1083.  
  1084.     return m_pPageCur->FQueryLinksInPage();
  1085.     }
  1086.  
  1087.  
  1088.  
  1089.  
  1090.  
  1091. /*
  1092.  * CPages::GetUILinkContainer
  1093.  *
  1094.  * Purpose:
  1095.  *  Creates an object with the IOleUILinkContainer interface for
  1096.  *  the links dialog.  We know the current page which is what
  1097.  *  we need to create this thing, so we can create it here instead
  1098.  *  of bugging the page for it.
  1099.  *
  1100.  * Parameters:
  1101.  *  ppObj           PCIOleUILinkContainer * in which we return
  1102.  *                  the pointer.
  1103.  *
  1104.  * Return Value:
  1105.  *  BOOL            TRUE if successful, FALSE otherwise.
  1106.  */
  1107.  
  1108. BOOL CPages::GetUILinkContainer(PCIOleUILinkContainer *ppObj)
  1109.     {
  1110.     PCIOleUILinkContainer   pObj;
  1111.  
  1112.     *ppObj=NULL;
  1113.  
  1114.     if (NULL==m_pPageCur)
  1115.         return FALSE;
  1116.  
  1117.     pObj=new CIOleUILinkContainer(m_pPageCur);
  1118.  
  1119.     if (NULL==pObj)
  1120.         return FALSE;
  1121.  
  1122.     if (!pObj->Init())
  1123.         {
  1124.         delete pObj;
  1125.         return FALSE;
  1126.         }
  1127.  
  1128.     pObj->AddRef();
  1129.     *ppObj=pObj;
  1130.     return TRUE;
  1131.     }
  1132.  
  1133.  
  1134.  
  1135.  
  1136. /*
  1137.  * CPages::ConvertObject
  1138.  *
  1139.  * Purpose:
  1140.  *  Pass-through to the current page.
  1141.  *
  1142.  * Parameters:
  1143.  *  hWndFrame       HWND of the frame window.
  1144.  *
  1145.  * Return Value:
  1146.  *  BOOL            TRUE if the function is successful, FALSE
  1147.  *                  otherwise.
  1148.  */
  1149.  
  1150. BOOL CPages::ConvertObject(HWND hWndFrame)
  1151.     {
  1152.     if (NULL==m_pPageCur)
  1153.         return FALSE;
  1154.  
  1155.     return m_pPageCur->ConvertObject(hWndFrame, FALSE);
  1156.     }
  1157.  
  1158.  
  1159.  
  1160.  
  1161.  
  1162. /*
  1163.  * CPages::CalcBoundingRect
  1164.  * (Protected)
  1165.  *
  1166.  * Purpose:
  1167.  *  Calculates a rectangle that bounds the printed page and the
  1168.  *  current scroll state of the window.
  1169.  *
  1170.  * Parameters:
  1171.  *  prc             LPRECT to fill with window (device) coordinates.
  1172.  *  fWindow         BOOL indicating to include the window in this
  1173.  *                  calculation or return only the printed page
  1174.  *                  coordinates.
  1175.  *
  1176.  * Return Value:
  1177.  *  None
  1178.  */
  1179.  
  1180. void CPages::CalcBoundingRect(LPRECT prc, BOOL fWindow)
  1181.     {
  1182.     RECT        rc, rcT;
  1183.  
  1184.     if (NULL==prc)
  1185.         return;
  1186.  
  1187.     //Calculate the boundaries for sizing: intersect page & screen
  1188.     rc.left=LOMETRIC_BORDER+m_xMarginLeft;
  1189.     rc.top =-LOMETRIC_BORDER-m_yMarginTop;
  1190.     rc.right =rc.left+(UINT)m_cx;
  1191.     rc.bottom=rc.top -(UINT)m_cy;
  1192.     RectConvertMappings(&rc, NULL, TRUE);
  1193.     OffsetRect(&rc, -(int)m_xPos, -(int)m_yPos);
  1194.  
  1195.     if (!fWindow)
  1196.         {
  1197.         *prc=rc;
  1198.         return;
  1199.         }
  1200.  
  1201.     //Intersect with window to make the size bounds.
  1202.     GetClientRect(m_hWnd, &rcT);
  1203.     IntersectRect(prc, &rc, &rcT);
  1204.     return;
  1205.     }
  1206.  
  1207.  
  1208.  
  1209.  
  1210.  
  1211.  
  1212. /*
  1213.  * CPages::PageGet
  1214.  * (Protected)
  1215.  *
  1216.  * Purpose:
  1217.  *  Returns a page of a given index returning a BOOL so it's simple
  1218.  *  to use this function inside if statements.
  1219.  *
  1220.  * Parameters:
  1221.  *  iPage           UINT page to retrieve 0 based.
  1222.  *  ppPage          PCPage * in which to return the page pointer
  1223.  *  fOpen           BOOL indicating if we should open this page as
  1224.  *                  well.
  1225.  *
  1226.  * Return Value:
  1227.  *  BOOL            TRUE if successful, FALSE otherwise.
  1228.  */
  1229.  
  1230. BOOL CPages::PageGet(UINT iPage, PCPage *ppPage, BOOL fOpen)
  1231.     {
  1232.     if (NULL==ppPage)
  1233.         return FALSE;
  1234.  
  1235.     if (LB_ERR!=SendMessage(m_hWndPageList, LB_GETTEXT
  1236.         , iPage, (LONG)ppPage))
  1237.         {
  1238.         if (fOpen)
  1239.             (*ppPage)->Open(m_pIStorage);
  1240.  
  1241.         return TRUE;
  1242.         }
  1243.  
  1244.     return FALSE;
  1245.     }
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.  
  1252. /*
  1253.  * CPages::PageAdd
  1254.  * (Protected)
  1255.  *
  1256.  * Purpose:
  1257.  *  Creates a new page initialized to the given values.  The new
  1258.  *  page's storage is created if it does not already exist.  If
  1259.  *  fOpenStorage is set the page's storage is opened and left
  1260.  *  opened.
  1261.  *
  1262.  * Parameters:
  1263.  *  iPage           UINT Location at which to insert page; new page
  1264.  *                  is inserted after this position.  NOVALUE for
  1265.  *                  the end.
  1266.  *  dwID            DWORD ID for this page.
  1267.  *  fOpenStorage    BOOL indicating if we're to leave the storage
  1268.  *                  open.
  1269.  *
  1270.  * Return Value:
  1271.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  1272.  */
  1273.  
  1274. BOOL CPages::PageAdd(UINT iPage, DWORD dwID, BOOL fOpenStorage)
  1275.     {
  1276.     PCPage      pPage;
  1277.     LRESULT     lr;
  1278.  
  1279.     pPage=new CPage(dwID, m_hWnd, this);
  1280.  
  1281.     if (NULL==pPage)
  1282.         return FALSE;
  1283.  
  1284.     pPage->AddRef();
  1285.  
  1286.     if (fOpenStorage)
  1287.         pPage->Open(m_pIStorage);
  1288.  
  1289.     if (NOVALUE==iPage)
  1290.         iPage--;
  1291.  
  1292.     //Now try to add to the listbox.
  1293.     lr=SendMessage(m_hWndPageList, LB_INSERTSTRING, iPage+1
  1294.         , (LONG)pPage);
  1295.  
  1296.     if (LB_ERRSPACE==lr)
  1297.         {
  1298.         if (fOpenStorage)
  1299.             pPage->Close(FALSE);
  1300.  
  1301.         pPage->Release();
  1302.         return FALSE;
  1303.         }
  1304.  
  1305.     return TRUE;
  1306.     }
  1307.  
  1308.  
  1309.  
  1310.  
  1311. /*
  1312.  * CPages::IPageGetFromID
  1313.  * (Protected)
  1314.  *
  1315.  * Purpose:
  1316.  *  Returns a page of a given identifier
  1317.  *
  1318.  * Parameters:
  1319.  *  dwID            DWORD identifier of the page to retrieve.  If
  1320.  *                  NOVALUE, then we return the current page.
  1321.  *  ppPage          PCPage * in which to return the page
  1322.  *                  pointer
  1323.  *  fOpen           BOOL indicating if we should open this page as
  1324.  *                  well.
  1325.  *
  1326.  * Return Value:
  1327.  *  UINT            Index of the page if successful, NOVALUE
  1328.  *                  otherwise.
  1329.  */
  1330.  
  1331. UINT CPages::IPageGetFromID(DWORD dwID, PCPage *ppPage
  1332.     , BOOL fOpen)
  1333.     {
  1334.     UINT        i;
  1335.     PCPage      pPage;
  1336.  
  1337.     if (NULL==ppPage)
  1338.         return FALSE;
  1339.  
  1340.     if ((LONG)-1==(LONG)dwID)
  1341.         {
  1342.         *ppPage=m_pPageCur;
  1343.         return m_iPageCur;
  1344.         }
  1345.  
  1346.     *ppPage=NULL;
  1347.  
  1348.     for (i=0; i < m_cPages; i++)
  1349.         {
  1350.         if (!PageGet(i, &pPage, FALSE))
  1351.             continue;
  1352.  
  1353.         if (pPage->GetID()==dwID)
  1354.             {
  1355.             if (fOpen)
  1356.                 pPage->Open(m_pIStorage);
  1357.  
  1358.             *ppPage=pPage;
  1359.             return i;
  1360.             }
  1361.         }
  1362.  
  1363.     return NOVALUE;
  1364.     }
  1365.