home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: SysTools / SysTools.zip / taman002.zip / TASKMANA.ZIP / src / kNotebookBase.cpp < prev    next >
C/C++ Source or Header  |  2000-04-29  |  15KB  |  481 lines

  1. /* $Id: kNotebookBase.cpp,v 1.1 2000/04/29 19:06:35 stknut Exp $
  2.  *
  3.  * kNotebookBase (kClassLib) - Notebook dialog base class.
  4.  *
  5.  * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
  6.  *
  7.  */
  8.  
  9. /*******************************************************************************
  10. *   Defined Constants And Macros                                               *
  11. *******************************************************************************/
  12. #define INCL_WIN
  13. #define INCL_DOS
  14.  
  15.  
  16. /*******************************************************************************
  17. *   Internal Functions                                                         *
  18. *******************************************************************************/
  19. #include <os2.h>
  20. #ifdef USE_KLIB
  21.     #include <kAssert.h>
  22.     #include <kLog.h>
  23.     #include <kHeap.h>
  24. #else
  25.     #include <malloc.h>
  26. #endif
  27. #include <memory.h>
  28.  
  29. #include "kBase.h"
  30. #include "kError.h"
  31. #include "kDlgBase.h"
  32. #include "kNotebookPageBase.h"
  33. #include "kNotebookBase.h"
  34.  
  35.  
  36.  
  37. /**
  38.  * Gets a page (pointer) from a Page id.
  39.  * @returns   Pointer to page object. NULL if not found or error.
  40.  * @param     ulPageId  Page id.
  41.  */
  42. kNotebookPageBase * kNotebookBase::queryPageFromId(ULONG ulPageId)
  43. {
  44.     int i;
  45.     for (i = 0; i < cPages; i++)
  46.         if (paPages[i].ulPageId == ulPageId)
  47.             return paPages[i].pPage;
  48.     return NULL;
  49. }
  50.  
  51.  
  52.  
  53. /**
  54.  * Gets a page (pointer) from a page handle (hwnd).
  55.  * @returns   Pointer to page object. NULL if not found or error.
  56.  * @param     hwndPage  Window handle of the page.
  57.  */
  58. kNotebookPageBase * kNotebookBase::queryPageFromHwnd(HWND hwndPage)
  59. {
  60.     int i;
  61.     for (i = 0; i < cPages; i++)
  62.         if (paPages[i].hwnd == hwndPage)
  63.             return paPages[i].pPage;
  64.     return NULL;
  65. }
  66.  
  67.  
  68. /**
  69.  * Handler of notebook specific controls.
  70.  * Control message.
  71.  * @param     usId           Control id.
  72.  * @param     usNotifyCode   Notification code.
  73.  * @param     ulControlSpec  Controlspecific paramenter.
  74.  */
  75. ULONG kNotebookBase::control(USHORT id, USHORT usNotifyCode, ULONG ulControlSpec)
  76. {
  77.     /* If this is the notebook id we'll handle the notifications. */
  78.     if (id == idNotebook)
  79.         switch (usNotifyCode)
  80.         {
  81.             case BKN_HELP:
  82.                 ntbkHelp(ulControlSpec);
  83.                 return 0UL;
  84.  
  85.             case BKN_NEWPAGESIZE:
  86.                 ntbkNewPageSize();
  87.                 return 0UL;
  88.  
  89.             case BKN_PAGEDELETED:
  90.                 ntbkPageDeleted((PDELETENOTIFY)ulControlSpec);
  91.                 return 0UL;
  92.  
  93.             case BKN_PAGESELECTED:
  94.                 ntbkPageSelected((PPAGESELECTNOTIFY)ulControlSpec);
  95.                 return 0UL;
  96.  
  97.             case BKN_PAGESELECTEDPENDING:
  98.                 ntbkPageSelectedPending((PPAGESELECTNOTIFY)ulControlSpec);
  99.                 return 0UL;
  100.         }
  101.     return kDlgBase::control(id, usNotifyCode, ulControlSpec);
  102. }
  103.  
  104.  
  105. /**
  106.  * Resizes the notebook according to the size changes.
  107.  * Note! Forwarding messages to the default dialog proc is probably useful!
  108.  * @param     pswp          New windowframe state.
  109.  */
  110. BOOL  kNotebookBase::adjustWindowPos(PSWP pswp)
  111. {
  112.     /* if size change resize notebook. */
  113.     if (pswp->fl & (SWP_SIZE | SWP_RESTORE | SWP_MAXIMIZE))
  114.     {
  115.         SWP     swp;
  116.  
  117.         if (pswp->fl & SWP_SIZE)
  118.             memcpy(&swp, pswp, sizeof(swp));
  119.         else if (pswp->fl & SWP_MAXIMIZE)
  120.             WinGetMaxPosition(hwnd, &swp);
  121.         else
  122.         {
  123.             swp.cx = WinQueryWindowUShort(hwnd, QWS_CXRESTORE);
  124.             swp.cy = WinQueryWindowUShort(hwnd, QWS_CYRESTORE);
  125.         }
  126.  
  127.         WinSetWindowPos(hwndNtbk, HWND_TOP,
  128.                         ptlBorder.x,
  129.                         ptlBorder.y,
  130.                         swp.cx - ptlBorder.x*2,
  131.                         swp.cy - ptlBorder.y*2 - cyTitleBar,
  132.                         SWP_MOVE | SWP_SIZE);
  133.     }
  134.  
  135.     return kDlgBase::adjustWindowPos(pswp);
  136. }
  137.  
  138.  
  139. /**
  140.  * Resizes the notebook according to the size changes.
  141.  * @param     cxOld  Old width.
  142.  * @param     cyOld  Old height.
  143.  * @param     cxNew  New width.
  144.  * @param     cyNew  New height
  145.  * @remark    ARG!!! This event don't occure for dialogs it seems!
  146.  */
  147. VOID kNotebookBase::size(SHORT cxOld, SHORT cyOld, SHORT cxNew, SHORT cyNew)
  148. {
  149.     /*
  150.     SWP swp;
  151.     if (WinQueryWindowPos(hwndNtbk, &swp))
  152.     {
  153.         WinSetWindowPos(hwndNtbk, HWND_TOP,
  154.                         0, 0,
  155.                         cxNew - cxOld + swp.cx,
  156.                         cyNew - cyOld + swp.cy,
  157.                         SWP_MOVE | SWP_SIZE);
  158.     }
  159.     */
  160.     cxOld = cxOld;
  161.     cyOld = cyOld;
  162.     cxNew = cxNew;
  163.     cyNew = cyNew;
  164. }
  165.  
  166.  
  167. /**
  168.  * Help is requested.
  169.  * @param     ulPageId  Page id of the focus page.
  170.  */
  171. VOID  kNotebookBase::ntbkHelp(ULONG ulPageId)
  172. {
  173.     kNotebookPageBase *pPage;
  174.     pPage = queryPageFromId(ulPageId);
  175.     if (pPage != NULL)
  176.         pPage->ntfyHelp();
  177. }
  178.  
  179.  
  180. /**
  181.  * All pages are notified that the size of the notebook has changed.
  182.  */
  183. VOID  kNotebookBase::ntbkNewPageSize()
  184. {
  185.     int     i;
  186.     BOOL    fRet;
  187.     SWP     swp;
  188.     if (cPages != 0)
  189.     {
  190.         fRet = WinQueryWindowPos(WinQueryWindow(paPages[0].hwnd, QW_PARENT), &swp);
  191.         ASSERT(fRet);
  192.  
  193.         for (i = 0; i < cPages; i++)
  194.             paPages[i].pPage->ntfySized(swp.cx, swp.cy);
  195.  
  196.         fRet = fRet;
  197.     }
  198. }
  199.  
  200.  
  201. /**
  202.  * Removes the page from the pagetable.
  203.  * @param     pDeleteNotify  Pointer to a delete notify struct.
  204.  */
  205. VOID  kNotebookBase::ntbkPageDeleted(PDELETENOTIFY pDeleteNotify)
  206. {
  207.     int i;
  208.     for (i = 0; i < cPages; i++)
  209.         if (paPages[i].hwnd == pDeleteNotify->hwndPage)
  210.         {   /* found page index, shift down the next pages one entry.*/
  211.             cPages--;
  212.             for (i = i; i < cPages; i++)
  213.                 memcpy(&paPages[i], &paPages[i+1], sizeof(paPages[0]));
  214.         }
  215. }
  216.  
  217.  
  218. /**
  219.  * Notify the page(s) that they have been selected and deselected.
  220.  * @param     pPageSelectNotify  Notify select struct.
  221.  */
  222. VOID  kNotebookBase::ntbkPageSelected(PPAGESELECTNOTIFY pPageSelectNotify)
  223. {
  224.     kNotebookPageBase *pPage;
  225.  
  226.     /* the deselected page first */
  227.     pPage = queryPageFromId(pPageSelectNotify->ulPageIdCur);
  228.     if (pPage != NULL)
  229.         pPage->ntfyDeselected();
  230.  
  231.     /* the selected page last */
  232.     pPage = queryPageFromId(pPageSelectNotify->ulPageIdNew);
  233.     if (pPage != NULL)
  234.         pPage->ntfySelected();
  235. }
  236.  
  237.  
  238. /**
  239.  * Notify that a page switch is to be done soon.
  240.  * Check if the current page is willing to loose focus.
  241.  * If it's not willing Then cancel page switch.
  242.  * If it's willing Then ask the new page if it may receive focus.
  243.  * Cancel if it wont have the focus.
  244.  * @param     pPageSelectNotify  Notify select struct.
  245.  */
  246. VOID  kNotebookBase::ntbkPageSelectedPending(PPAGESELECTNOTIFY pPageSelectNotify)
  247. {
  248.     BOOL               fOK = TRUE;
  249.     kNotebookPageBase *pPage;
  250.  
  251.     /* the deselected page */
  252.     pPage = queryPageFromId(pPageSelectNotify->ulPageIdCur);
  253.     if (pPage != NULL)
  254.         fOK = pPage->ntfyDeselectedPending();
  255.  
  256.     /* the selected page */
  257.     if (fOK)
  258.     {
  259.         pPage = queryPageFromId(pPageSelectNotify->ulPageIdNew);
  260.         if (pPage != NULL)
  261.             fOK = pPage->ntfySelectedPending();
  262.     }
  263.  
  264.     /* Cancel the page switching? */
  265.     if (!fOK)
  266.         pPageSelectNotify->ulPageIdNew = 0UL;
  267. }
  268.  
  269.  
  270. /**
  271.  * Create a notebook from a dialog template.
  272.  * @param     usResId     Id of the dialog template.
  273.  * @param     hmodRes     Resource module handle. (NULLHANDLE is current .EXE)
  274.  * @param     idNotebook  Notebook control id.
  275.  * @param     hwndOwner   Owner window
  276.  * @param     hwndParent  Parent window.
  277.  * @remark    not implemented.
  278.  */
  279. kNotebookBase::kNotebookBase(ULONG ulResId, HMODULE hmodRes, ULONG idNotebook, HWND hwndOwner,
  280.                              HWND hwndParent/* = HWND_DESKTOP*/) throw (kError)
  281. : kDlgBase(ulResId, hmodRes, hwndOwner, hwndParent),
  282.     paPages(NULL), cPages(0), idNotebook((USHORT)idNotebook)
  283. {
  284.  
  285.     hwndNtbk   = WinWindowFromID(hwnd, idNotebook);
  286.     if (WinWindowFromID(hwnd, FID_TITLEBAR) != NULLHANDLE)
  287.         cyTitleBar = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
  288.     else
  289.         cyTitleBar = 0;
  290.     WinSendMsg(hwnd, WM_QUERYBORDERSIZE, &ptlBorder, NULL);
  291. }
  292.  
  293.  
  294.  
  295.  
  296. /**
  297.  * Create a notebook from a dialog template.
  298.  * @param     pszTitle          Dialog title.
  299.  * @param     id                Window id.
  300.  * @param     flDialogStyle     Dialog style flags.
  301.  * @param     flDialogCreate    Dialog (frame) create flags.
  302.  * @param     x                 x-coordinate.
  303.  * @param     y                 y-coordinate.
  304.  * @param     cx                width
  305.  * @param     cy                hight
  306.  * @param     flNotebookStyle   Notebook style flags.
  307.  * @param     hwndOwner         Owner window
  308.  * @param     hwndParent        Parent window.
  309.  * @remark    not implemented.
  310.  */
  311. kNotebookBase::kNotebookBase(PCSZ pszTitle, ULONG id,  ULONG flDialogStyle, ULONG flDialogCreate,
  312.                              LONG x, LONG y, LONG cx, LONG cy,
  313.                              ULONG flNotebookStyle, HWND hwndOwner, HWND hwndParent/* = HWND_DESKTOP*/) throw (kError)
  314. : kDlgBase(pszTitle, id, flDialogStyle, flDialogCreate, x, y, cx, cy, hwndOwner, hwndParent),
  315. cPages(0), paPages(NULL)
  316. {
  317.     RECTL rectl;
  318.     queryRectangle(&rectl);
  319.  
  320.     /* create the notebook control */
  321.     idNotebook = 100;
  322.     hwndNtbk = WinCreateWindow(
  323.                               hwnd,
  324.                               WC_NOTEBOOK,
  325.                               NULL,
  326.                               flNotebookStyle,
  327.                               0,
  328.                               0,
  329.                               rectl.xRight - rectl.xLeft,
  330.                               rectl.yTop   - rectl.yBottom,
  331.                               hwnd,
  332.                               HWND_TOP,
  333.                               idNotebook,
  334.                               NULL,
  335.                               NULL);
  336.     if (hwndNtbk == NULLHANDLE)
  337.         throw(kError(kError::unused, kError::win));
  338.  
  339.     /*
  340.      * Get border size and height of the titlebar.
  341.      */
  342.     if (flDialogCreate & FCF_TITLEBAR)
  343.         cyTitleBar = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
  344.     else
  345.         cyTitleBar = 0;
  346.     WinSendMsg(hwnd, WM_QUERYBORDERSIZE, &ptlBorder, NULL);
  347. }
  348.  
  349.  
  350.  
  351. /**
  352.  * Destructor.
  353.  */
  354. kNotebookBase::~kNotebookBase()
  355. {
  356.     /* destroy pages? */
  357.  
  358.     /* free page table */
  359.     if (paPages)
  360.         free(paPages);
  361.     paPages = NULL;
  362. }
  363.  
  364.  
  365.  
  366.  
  367.  
  368. /**
  369.  * Inserts a page into the notebook.
  370.  * @returns   success indicator. TRUE / FALSE.
  371.  * @param     usPageStyle  See PMREF.
  372.  * @param     usPageOrder  See PMREF.
  373.  * @param     ulPageId     See PMREF.
  374.  */
  375. BOOL    kNotebookBase::insertPage(kNotebookPageBase *pNtbkPage,
  376.                                   USHORT usPageStyle,
  377.                                   USHORT usPageOrder,
  378.                                   ULONG  ulPageId/* = 0UL*/)
  379. {
  380.     SWP     swp;
  381.     CHAR    szTabText[64];
  382.  
  383.     /*
  384.      * Reallocate the pages table to make space for the new page.
  385.      */
  386.     PVOID pvaPages = realloc(paPages, (cPages+1) * sizeof(paPages[0]));
  387.  
  388.     if (pvaPages == NULL)
  389.         return FALSE;
  390.     paPages = (struct _PageEntry*) pvaPages;
  391.  
  392.  
  393.     /*
  394.      * Insert the page in the notebook.
  395.      * Add it to paPages too. (Don't "commit" it)
  396.      */
  397.     paPages[cPages].pPage    = pNtbkPage;
  398.     paPages[cPages].hwnd     = pNtbkPage->getHwnd();
  399.     paPages[cPages].ulPageId = (ULONG)WinSendMsg(hwndNtbk,
  400.                                                  BKM_INSERTPAGE,
  401.                                                  MPFROMLONG(ulPageId),
  402.                                                  MPFROM2SHORT(usPageStyle, usPageOrder));
  403.     if (paPages[cPages].ulPageId == 0)
  404.         return FALSE;
  405.  
  406.     /*
  407.      * Associate the the kNtbkPage window with the new page.
  408.      */
  409.     if (!(BOOL)WinSendMsg(hwndNtbk, BKM_SETPAGEWINDOWHWND,
  410.                           MPFROMLONG(paPages[cPages].ulPageId),
  411.                           MPFROMHWND(paPages[cPages].hwnd))
  412.        )
  413.     {
  414.         WinSendMsg(hwndNtbk, BKM_DELETEPAGE,
  415.                    MPFROMLONG(paPages[cPages].ulPageId),
  416.                    MPFROMLONG(BKA_SINGLE));
  417.         return FALSE;
  418.     }
  419.  
  420.     /*
  421.      * Set the notebook as owner of the page.
  422.      */
  423.     WinSetOwner(pNtbkPage->getHwnd(), hwndNtbk);
  424.  
  425.     /*
  426.      * Set tab text.
  427.      */
  428.     if (pNtbkPage->queryTabText(&szTabText[0], sizeof(szTabText)) != NULL)
  429.         setTabText(paPages[cPages].ulPageId, &szTabText[0]);
  430.  
  431.     /*
  432.      * Finally we commits the new page by incrementing the page count.
  433.      */
  434.     cPages++;
  435.  
  436.     /*
  437.      * Send a hint of the page size.
  438.      */
  439.     if (WinQueryWindowPos(WinQueryWindow(paPages[cPages-1].hwnd, QW_PARENT), &swp))
  440.         paPages[cPages-1].pPage->ntfySized(swp.cx, swp.cy);
  441.  
  442.     /*
  443.      * Notify the page that it has been inserted.
  444.      */
  445.     paPages[cPages-1].pPage->ntfyInserted();
  446.  
  447.     return TRUE;
  448. }
  449.  
  450.  
  451. /**
  452.  * Gets the size of the page(fPage=FALSE) or the notebook(fPage=TRUE).
  453.  * @returns   success indicator.
  454.  * @param     pRectl    Pointer to the RECTL structure that contains the coordinates of the rectangle.
  455.  * @param     fPage     If the fPage parameter is TRUE, this structure contains the coordinates of
  456.  *                      a notebook window on input, and on return it contains the coordinates of an
  457.  *                      application page window.
  458.  *                      If the fPage parameter is FALSE, this structure contains the coordinates of
  459.  *                      an application page window on input, and on return it contains the
  460.  *                      coordinates of a notebook window.
  461.  */
  462. BOOL kNotebookBase::queryPageRectangle(PRECTL pRectl, BOOL fPage)
  463. {
  464.     return(BOOL)WinSendMsg(hwndNtbk, BKM_CALCPAGERECT,
  465.                            pRectl, MPFROMLONG(fPage));
  466. }
  467.  
  468.  
  469. /**
  470.  * Sets the tab text for the specified page.
  471.  * @returns   success indicator.
  472.  * @param     ulPageId    Page identificator.
  473.  * @param     pszTabText  Pointer to the tab text.
  474.  */
  475. BOOL kNotebookBase::setTabText(ULONG ulPageId, PSZ pszTabText)
  476. {
  477.     return (BOOL)WinSendMsg(hwndNtbk, BKM_SETTABTEXT,
  478.                             MPFROMLONG(ulPageId), pszTabText);
  479. }
  480.  
  481.