Easily Load and Manage Pages

From EDM2
Jump to: navigation, search

By Samuel Audet


Last Modified: May 7, 2001 20:07:03 EDT.


The most annoying problem with Notebooks is the ability to directly communicate with the dialogs. However, this can be easily compensated through some simple functions and a nice structure, thanks to Rick Fishman for the great idea!

typedef struct _NBPAGE
{
  PFNWP  pfnwpDlg;     /* Window procedure address for the dialog */
  PSZ   szStatusLineText;  /* Text to go on status line */
  PSZ   szTabText;     /* Text to go on major tab */
  ULONG  idDlg;      /* ID of the dialog box for this page */
  BOOL   skip;      /* skip this page (for major pages with minor pages) */
  USHORT  usTabType;     /* BKA_MAJOR or BKA_MINOR */
  ULONG  ulPageId;     /* notebook page ID */
  HWND   hwnd;      /* set when page frame is loaded */

} NBPAGE, *PNBPAGE;

You make a global variable that initializes some of the values of that structure. For example:

NBPAGE nbpage[] =
{
   {wpFoo,  "Tab 1 of 4", "~Foo",  ID_FOO, FALSE, BKA_MAJOR, 0, 0},
   {wpFoo2, "Tab 2 of 4", "Foo~2", ID_FOO2, FALSE, BKA_MAJOR, 0, 0},
}

/* some constants so that we don't have
   to modify code if we add pages */
#define PAGE_COUNT (sizeof( nbpage ) / sizeof( NBPAGE ))
#define PAGE_FOO  0
#define PAGE_FOO2 1

Once this is filled, you can call createNotebook() and loadNotebookDlg() and voila! no hassle. Send messages to your controls using nbpage[PAGE_FOO].hwnd. Also, you can delay the calling of loadNotebookDlg() by trapping BKN_PAGESELECTEDPENDING and checking if NBPAGE.hwnd is valid to save initial loading time. Also, to skip major pages and show only minor pages, BKN_PAGESELECTEDPENDING does require some attention. See below for an example.

HWND createNotebook(HWND hwnd, NBPAGE *nbpage, ULONG pageCount)
{
   HWND hwndNB;
   int i;

   /* create notebook, here if the warp 4 style doesn't show,
      I am trying to minic it with the old style one */
   hwndNB =  WinCreateWindow( hwnd, WC_NOTEBOOK, NULL, WS_VISIBLE |
             BKS_TABBEDDIALOG | /* BKS_BUTTONAREA | */ WS_GROUP | WS_TABSTOP |
             /* needed for old style customizeable notebook */
             BKS_BACKPAGESTR | BKS_MAJORTABTOP | BKS_ROUNDEDTABS |
             BKS_STATUSTEXTCENTER | BKS_SPIRALBIND | BKS_TABTEXTLEFT,
             0, 0, 0, 0, hwnd, HWND_TOP, FID_CLIENT, NULL, NULL );

   if(!hwndNB) return FALSE;

   /* change colors for old style notebook not to look ugly */
   WinSendMsg(hwndNB, BKM_SETNOTEBOOKCOLORS, MPFROMLONG(SYSCLR_FIELDBACKGROUND),
                 MPFROMSHORT(BKA_BACKGROUNDPAGECOLORINDEX));

   /* change tab width for old style notebook to something OK for most font size */
   WinSendMsg(hwndNB, BKM_SETDIMENSIONS, MPFROM2SHORT(80,25),
                 MPFROMSHORT(BKA_MAJORTAB));

   /* no minor */
   WinSendMsg(hwndNB, BKM_SETDIMENSIONS, 0, MPFROMSHORT(BKA_MINORTAB));

   for(i = 0; i < pageCount; i++)
   {
       nbpage[i].ulPageId = (LONG)WinSendMsg(hwndNB,  BKM_INSERTPAGE, NULL,
             MPFROM2SHORT((BKA_STATUSTEXTON | BKA_AUTOPAGESIZE | nbpage[i].usTabType),
             BKA_LAST));

       if ( !nbpage[i].ulPageId)
          return FALSE;

       if ( !WinSendMsg(hwndNB, BKM_SETSTATUSLINETEXT, MPFROMLONG(nbpage[i].ulPageId),
             MPFROMP(nbpage[i].szStatusLineText)))
          return FALSE;

       if ( !WinSendMsg(hwndNB, BKM_SETTABTEXT, MPFROMLONG(nbpage[i].ulPageId),
             MPFROMP(nbpage[i].szTabText)))
          return FALSE;

       if (!WinSendMsg( hwndNB, BKM_SETPAGEDATA, MPFROMLONG(nbpage[i].ulPageId),
             MPFROMP(&nbpage[i])))
          return FALSE;
   }

   /* return success (notebook window handle) */
   return hwndNB;
}

BOOL loadNotebookDlg(HWND hwndNotebook, NBPAGE *nbpage, ULONG pageCount)
{
   int i;
   for(i = 0; i < pageCount; i++)
   {
       /* loading dialog page frame */
       nbpage[i].hwnd = WinLoadDlg(hwndNotebook, hwndNotebook,
                                   nbpage[i].pfnwpDlg, 0, nbpage[i].idDlg, NULL);

       if(!nbpage[i].hwnd) return FALSE;

  //   WinSetPresParam(nbpage[i].hwnd, PP_FONTNAMESIZE, strlen(font)+1, font);

       WinSendMsg(hwndNotebook, BKM_SETPAGEWINDOWHWND,
           MPFROMLONG(nbpage[i].ulPageId), MPFROMHWND(nbpage[i].hwnd));
   }

   /* I want the focus on the notebook tab after load */
   WinSetFocus(HWND_DESKTOP, hwndNotebook);

   return TRUE;
}

In the client or main dialog window procedure, you will need something that looks like this:

/* received from the notebook window,
   allows loading and refreshing of pages */
case WM_CONTROL:
{
   switch(SHORT2FROMMP(mp1))
   {
      case BKN_PAGESELECTEDPENDING:
      {
         PAGESELECTNOTIFY *pageselect = PVOIDFROMMP(mp2);
         /* get page window handle */
         HWND FrameHwnd = HWNDFROMMR(WinSendMsg(pageselect->hwndBook,
                          BKM_QUERYPAGEWINDOWHWND,
                          MPFROMLONG(pageselect->ulPageIdNew), NULL));

         NBPAGE *pagedata = PVOIDFROMMR(WinSendMsg(pageselect->hwndBook,
                            BKM_QUERYPAGEDATA,
                            MPFROMLONG(pageselect->ulPageIdNew), NULL));

         if (!pagedata) return 0;

          /* skip dummy (major) pages that we want
             to skip to only show their minor pages */
         if(pagedata->skip)
         {
            ULONG ulPageNext = (ULONG) WinSendMsg(pageselect->hwndBook,
                                       BKM_QUERYPAGEID,
                                       MPFROMLONG( pageselect->ulPageIdNew ),
                                       MPFROM2SHORT( BKA_NEXT, 0 ) );

            /* if the next page was the previously
               viewed page, means the user is
               going backward, so we show the previous page */
            if(ulPageNext == pageselect->ulPageIdCur)
               WinSendMsg(pageselect->hwndBook, BKM_TURNTOPAGE,

                  MPFROMLONG( (ULONG) WinSendMsg(pageselect->hwndBook,
                                      BKM_QUERYPAGEID,
                                      MPFROMLONG(pageselect->ulPageIdNew),
                                      MPFROM2SHORT(BKA_PREV, 0))

                                                               ), NULL);
            /* else we want to show the next page */
            else
               WinSendMsg( pageselect->hwndBook,
                           BKM_TURNTOPAGE, MPFROMLONG(ulPageNext), NULL);

            /* prevents the current page from showing at all */
            pageselect->ulPageIdNew = 0;
            break;
         }
         else if (!FrameHwnd)
            loadNotebookDlg(pageselect->hwndBook, pagedata, 1);

         return 0;
      }
   }
}