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

Windows编程

开发平台:

Visual C++

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