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 / chap01 / patron / pages.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  12KB  |  595 lines

  1. /*
  2.  * PAGES.CPP
  3.  * Patron Chapter 1
  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.     m_hDevMode=NULL;
  50.     return;
  51.     }
  52.  
  53.  
  54. CPages::~CPages(void)
  55.     {
  56.     //Ensure memory is cleaned up in the list
  57.     New();
  58.  
  59.     if (NULL!=m_hFont && !m_fSystemFont)
  60.         DeleteObject(m_hFont);
  61.  
  62.     if (NULL!=m_hWndPageList)
  63.         DestroyWindow(m_hWndPageList);
  64.  
  65.     return;
  66.     }
  67.  
  68.  
  69.  
  70.  
  71.  
  72. /*
  73.  * CPages::Init
  74.  *
  75.  * Purpose:
  76.  *  Instantiates a pages window within a given parent.  The
  77.  *  parent may be a main application window, could be an MDI child
  78.  *  window. We really do not care.
  79.  *
  80.  * Parameters:
  81.  *  hWndParent      HWND of the parent of this window
  82.  *  pRect           LPRECT that this window should occupy
  83.  *  dwStyle         DWORD containing the window's style flags.
  84.  *                  Should contain WS_CHILD | WS_VISIBLE in
  85.  *                  typical circumstances.
  86.  *  uID             UINT ID to associate with this window
  87.  *  pv              LPVOID unused for now.
  88.  *
  89.  * Return Value:
  90.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  91.  */
  92.  
  93. BOOL CPages::Init(HWND hWndParent, LPRECT pRect, DWORD dwStyle
  94.     , UINT uID, LPVOID pv)
  95.     {
  96.     int     cy;
  97.  
  98.     m_hWnd=CreateWindowEx(WS_EX_NOPARENTNOTIFY, SZCLASSPAGES
  99.         , SZCLASSPAGES, dwStyle, pRect->left, pRect->top
  100.         , pRect->right-pRect->left, pRect->bottom-pRect->top
  101.         , hWndParent, (HMENU)uID, m_hInst, this);
  102.  
  103.     if (NULL==m_hWnd)
  104.         return FALSE;
  105.  
  106.     /*
  107.      * Create the hidden listbox we'll use to track pages.  We give
  108.      * it the owner-draw style so we can just store pointers in it.
  109.      */
  110.     m_hWndPageList=CreateWindow(TEXT("listbox"), TEXT("Page List")
  111.         , WS_POPUP | LBS_OWNERDRAWFIXED, 0, 0, 100, 100
  112.         , HWND_DESKTOP, NULL, m_hInst, NULL);
  113.  
  114.     if (NULL==m_hWndPageList)
  115.         return FALSE;
  116.  
  117.     //Create a 14 point Arial font, or use the system variable font.
  118.     cy=MulDiv(-14, LOMETRIC_PER_INCH, 72);
  119.     m_hFont=CreateFont(cy, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE
  120.         , ANSI_CHARSET, OUT_TT_PRECIS, CLIP_TT_ALWAYS, PROOF_QUALITY
  121.         , VARIABLE_PITCH | FF_SWISS, TEXT("Arial"));
  122.  
  123.     if (NULL==m_hFont)
  124.         {
  125.         m_hFont=(HFONT)GetStockObject(ANSI_VAR_FONT);
  126.         m_fSystemFont=TRUE;
  127.         }
  128.  
  129.     return TRUE;
  130.     }
  131.  
  132.  
  133.  
  134.  
  135. /*
  136.  * CPages::New
  137.  *
  138.  * Purpose:
  139.  *  Cleans out and reinitializes the data to defaults.
  140.  *
  141.  * Parameters:
  142.  *  None
  143.  *
  144.  * Return Value:
  145.  *  None
  146.  */
  147.  
  148. void CPages::New(void)
  149.     {
  150.     PCPage      pPage;
  151.     UINT        i;
  152.  
  153.     //First walk the page list and clean out the allocations.
  154.     for (i=0; i < m_cPages; i++)
  155.         {
  156.         if (PageGet(i, &pPage, FALSE))
  157.             delete pPage;
  158.         }
  159.  
  160.     if (NULL!=m_hWndPageList)
  161.         SendMessage(m_hWndPageList, LB_RESETCONTENT, 0, 0L);
  162.  
  163.     if (NULL!=m_hDevMode)
  164.         GlobalFree(m_hDevMode);
  165.  
  166.     return;
  167.     }
  168.  
  169.  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176. /*
  177.  * CPages::RectGet
  178.  *
  179.  * Purpose:
  180.  *  Returns the rectangle of the Pages window in parent coordinates.
  181.  *
  182.  * Parameters:
  183.  *  pRect           LPRECT in which to return the rectangle.
  184.  *
  185.  * Return Value:
  186.  *  None
  187.  */
  188.  
  189. void CPages::RectGet(LPRECT pRect)
  190.     {
  191.     RECT        rc;
  192.     POINT       pt;
  193.  
  194.     //Retrieve the size of our rectangle in parent coordinates.
  195.     GetWindowRect(m_hWnd, &rc);
  196.     pt.x=rc.left;
  197.     pt.y=rc.top;
  198.     ScreenToClient(GetParent(m_hWnd), &pt);
  199.  
  200.     SetRect(pRect, pt.x, pt.y, pt.x+(rc.right-rc.left)
  201.         , pt.y+(rc.bottom-rc.top));
  202.  
  203.     return;
  204.     }
  205.  
  206.  
  207.  
  208.  
  209.  
  210.  
  211. /*
  212.  * CPages::RectSet
  213.  *
  214.  * Purpose:
  215.  *  Sets a new rectangle for the Pages window which sizes to fit.
  216.  *  Coordinates are given in parent terms.
  217.  *
  218.  * Parameters:
  219.  *  pRect           LPRECT containing the new rectangle.
  220.  *  fNotify         BOOL indicating if we're to notify anyone of
  221.  *                  the change.
  222.  *
  223.  * Return Value:
  224.  *  None
  225.  */
  226.  
  227. void CPages::RectSet(LPRECT pRect, BOOL fNotify)
  228.     {
  229.     UINT        cx, cy;
  230.  
  231.     if (NULL==pRect)
  232.         return;
  233.  
  234.     cx=pRect->right-pRect->left;
  235.     cy=pRect->bottom-pRect->top;
  236.  
  237.     SetWindowPos(m_hWnd, NULL, pRect->left, pRect->top
  238.         , (UINT)cx, (UINT)cy, SWP_NOZORDER);
  239.  
  240.     UpdateScrollRanges();
  241.     return;
  242.     }
  243.  
  244.  
  245.  
  246.  
  247. /*
  248.  * CPages::SizeGet
  249.  *
  250.  * Purpose:
  251.  *  Retrieves the size of the pages window in parent coordinates.
  252.  *
  253.  * Parameters:
  254.  *  pRect           LPRECT in which to return the size.  The right
  255.  *                  and bottom fields will contain the dimensions.
  256.  *
  257.  * Return Value:
  258.  *  None
  259.  */
  260.  
  261. void CPages::SizeGet(LPRECT pRect)
  262.     {
  263.     RectGet(pRect);
  264.     return;
  265.     }
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273. /*
  274.  * CPages::SizeSet
  275.  *
  276.  * Purpose:
  277.  *  Sets a new size in parent coordinates for the Pages window.
  278.  *
  279.  * Parameters:
  280.  *  pRect           LPRECT containing the new rectangle.
  281.  *  fNotify         BOOL indicating if we're to notify anyone of
  282.  *                  the change.
  283.  *
  284.  * Return Value:
  285.  *  None
  286.  */
  287.  
  288. void CPages::SizeSet(LPRECT pRect, BOOL fNotify)
  289.     {
  290.     UINT        cx, cy;
  291.  
  292.     if (NULL==pRect)
  293.         return;
  294.  
  295.     cx=pRect->right-pRect->left;
  296.     cy=pRect->bottom-pRect->top;
  297.  
  298.     SetWindowPos(m_hWnd, NULL, 0, 0, (UINT)cx, (UINT)cy
  299.         , SWP_NOMOVE | SWP_NOZORDER);
  300.  
  301.     UpdateScrollRanges();
  302.     return;
  303.     }
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310. /*
  311.  * CPages::ActivePage
  312.  *
  313.  * Purpose:
  314.  *  Returns a CPage pointer to the current page.
  315.  *
  316.  * Parameters:
  317.  *  None
  318.  *
  319.  * Return Value:
  320.  *  PCPage          Pointer to the current page.
  321.  */
  322.  
  323. PCPage CPages::ActivePage(void)
  324.     {
  325.     PCPage      pPage;
  326.     BOOL        fRet;
  327.  
  328.     fRet=PageGet(m_iPageCur, &pPage, FALSE);
  329.     return fRet ? pPage : NULL;
  330.     }
  331.  
  332.  
  333.  
  334.  
  335.  
  336. /*
  337.  * CPages::PageInsert
  338.  *
  339.  * Purpose:
  340.  *  Creates a new page immediately after the current page.  If
  341.  *  there are no pages then this creates page 1.
  342.  *
  343.  * Parameters:
  344.  *  uReserved       UINT unused
  345.  *
  346.  * Return Value:
  347.  *  UINT            Index of the new page, 0 on failure.
  348.  */
  349.  
  350. UINT CPages::PageInsert(UINT uReserved)
  351.     {
  352.     //Create and open the new page.
  353.     if (!PageAdd(m_iPageCur, m_dwIDNext, TRUE))
  354.         return 0;
  355.  
  356.     m_dwIDNext++;
  357.     m_iPageCur++;
  358.     m_cPages++;
  359.  
  360.     InvalidateRect(m_hWnd, NULL, FALSE);
  361.     UpdateWindow(m_hWnd);
  362.     return m_iPageCur;
  363.     }
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371. /*
  372.  * CPages::PageDelete
  373.  *
  374.  * Removes the current page from the page list.
  375.  *
  376.  * Parameters:
  377.  *  uReserved       UINT unused
  378.  *
  379.  * Return Value:
  380.  *  UINT            Index to the now current page from the page
  381.  *                  list, NOVALUE on error.
  382.  */
  383.  
  384. UINT CPages::PageDelete(UINT uReserved)
  385.     {
  386.     PCPage      pPage;
  387.  
  388.     if (!PageGet(m_iPageCur, &pPage, FALSE))
  389.         return NOVALUE;
  390.  
  391.     //Delete the page in both the listbox and in memory.
  392.     SendMessage(m_hWndPageList, LB_DELETESTRING, m_iPageCur, 0L);
  393.     delete pPage;
  394.  
  395.  
  396.     /*
  397.      * If this is the last page then the current is one less.  If
  398.      * it's the only page the current is zero.  Otherwise the
  399.      * current is the next page.
  400.      */
  401.  
  402.     if (m_iPageCur==m_cPages-1)   //Covers last or only page.
  403.         m_iPageCur--;
  404.  
  405.     m_cPages--;
  406.  
  407.     if (0!=m_cPages)
  408.         InvalidateRect(m_hWnd, NULL, FALSE);
  409.     else
  410.         InvalidateRect(m_hWnd, NULL, TRUE);
  411.  
  412.     UpdateWindow(m_hWnd);
  413.     return m_iPageCur;
  414.     }
  415.  
  416.  
  417.  
  418.  
  419.  
  420.  
  421. /*
  422.  * CPages::CurPageGet
  423.  *
  424.  * Purpose:
  425.  *  Retrieves the index of the current page we're viewing.
  426.  *
  427.  * Parameters:
  428.  *  None
  429.  *
  430.  * Return Value:
  431.  *  UINT            Index of the current page.
  432.  */
  433.  
  434. UINT CPages::CurPageGet(void)
  435.     {
  436.     return m_iPageCur;
  437.     }
  438.  
  439.  
  440.  
  441.  
  442.  
  443. /*
  444.  * CPages::CurPageSet
  445.  *
  446.  * Purpose:
  447.  *  Sets the index of the current page to view.
  448.  *
  449.  * Parameters:
  450.  *  iPage           UINT index of the page to view. 0 means first
  451.  *                  page, NOVALUE means last page.
  452.  *
  453.  * Return Value:
  454.  *  UINT            Index of the previous current page, NOVALUE on
  455.  *                  error.
  456.  */
  457.  
  458. UINT CPages::CurPageSet(UINT iPage)
  459.     {
  460.     UINT    iPageNew;
  461.     UINT    iPagePrev=m_iPageCur;
  462.  
  463.     switch (iPage)
  464.         {
  465.         case 0:
  466.             iPageNew=0;
  467.             break;
  468.  
  469.         case NOVALUE:
  470.             iPageNew=m_cPages-1;
  471.             break;
  472.  
  473.         default:
  474.             if (iPage >= m_cPages)
  475.                 iPage=0;
  476.  
  477.             iPageNew=iPage;
  478.             break;
  479.         }
  480.  
  481.     //No reason to switch to the same page.
  482.     if (iPagePrev==iPageNew)
  483.         return iPage;
  484.  
  485.     m_iPageCur=iPageNew;
  486.  
  487.     InvalidateRect(m_hWnd, NULL, FALSE);
  488.     UpdateWindow(m_hWnd);
  489.     return iPagePrev;
  490.     }
  491.  
  492.  
  493.  
  494. /*
  495.  * CPages::NumPagesGet
  496.  *
  497.  * Purpose:
  498.  *  Returns the number of pages this object current contains.
  499.  *
  500.  * Parameters:
  501.  *  None
  502.  *
  503.  * Return Value:
  504.  *  UINT            Number of pages we contain.
  505.  */
  506.  
  507. UINT CPages::NumPagesGet(void)
  508.     {
  509.     return m_cPages;
  510.     }
  511.  
  512.  
  513.  
  514.  
  515.  
  516. /*
  517.  * CPages::PageGet
  518.  * (Protected)
  519.  *
  520.  * Purpose:
  521.  *  Returns a page of a given index returning a BOOL so it's simple
  522.  *  to use this function inside if statements.
  523.  *
  524.  * Parameters:
  525.  *  iPage           UINT page to retrieve.
  526.  *  ppPage          PCPage * in which to return the page
  527.  *                  pointer
  528.  *  fReserved       BOOL reserved for future use.
  529.  *
  530.  * Return Value:
  531.  *  BOOL            TRUE if successful, FALSE otherwise.
  532.  */
  533.  
  534. BOOL CPages::PageGet(UINT iPage, PCPage *ppPage
  535.     , BOOL fReserved)
  536.     {
  537.     if (NULL==ppPage)
  538.         return FALSE;
  539.  
  540.     if (LB_ERR!=SendMessage(m_hWndPageList, LB_GETTEXT
  541.         , iPage, (LONG)ppPage))
  542.         return TRUE;
  543.  
  544.     return FALSE;
  545.     }
  546.  
  547.  
  548.  
  549.  
  550.  
  551. /*
  552.  * CPages::PageAdd
  553.  * (Protected)
  554.  *
  555.  * Purpose:
  556.  *  Creates a new page initialized to the given values.
  557.  *
  558.  * Parameters:
  559.  *  iPage           UINT Location at which to insert page; new page
  560.  *                  is inserted after this position.  NOVALUE for
  561.  *                  the end.
  562.  *  cObjects        UINT number of objects on this page.
  563.  *  dwID            DWORD ID for this page.
  564.  *  fReserved       BOOL reserved for future use.
  565.  *
  566.  * Return Value:
  567.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  568.  */
  569.  
  570. BOOL CPages::PageAdd(UINT iPage, DWORD dwID, BOOL fReserved)
  571.     {
  572.     PCPage      pPage;
  573.     LRESULT     lr;
  574.  
  575.     pPage=new CPage(dwID);
  576.  
  577.     if (NULL==pPage)
  578.         return FALSE;
  579.  
  580.     if (NOVALUE==iPage)
  581.         iPage--;
  582.  
  583.     //Now try to add to the listbox.
  584.     lr=SendMessage(m_hWndPageList, LB_INSERTSTRING, iPage+1
  585.         , (LONG)pPage);
  586.  
  587.     if (LB_ERRSPACE==lr)
  588.         {
  589.         delete pPage;
  590.         return FALSE;
  591.         }
  592.  
  593.     return TRUE;
  594.     }
  595.