/*
 * PageDlg.rc - source code for the Multi-Pages dialog
 *
 * Author:      Kanhom Ng
 *             Kansmen Corporation
 *
 * Date:         12/09/91
 *
 *   Compiler:   Microsoft C 6.00A
 * OS:         Windows 3.0
 *
 * Copyright (C) 1991 Kanhom Ng.  All rights reserved.
 *
 */

#define      NOCOMM
#include      <windows.h>

#define     MAXPAGE                 10
#define      SYSCLASS                  0x80

typedef struct {
   WORD      cCtls;   /* count of control */
   HANDLE   hCtls;      /* handle to the control list*/
} PAGE, FAR * LPPAGE;

/* paging dialog information */
typedef struct {
   WORD      cPg;               /* count of page  */
   PAGE      aPg[MAXPAGE];      /* Page list */
} DLGHDR, FAR * LPDLGHDR;

typedef struct { /* dialog box template */
   long   lStyle;      /* dialog box style */
   BYTE   cItem;      /* number of item in dialog */
   int   x;            /* x ( RC ) of upper-left corner*/
   int   y;            /* y ( RC ) of upper-left corner*/
   int   cx;         /* width (RC) of the dialog box*/
   int   cy;         /* height (RC) of the dialog box */
   /* szResource[]*/ /* Null-terminated string  */
   /* szClass[] */   /* Null-terminated string  */
   /* szCaption[] */   /* Null-terminated string  */
   /* fontinfo */      /* font info if specified */
} DT, FAR * LPDT;

typedef struct { /* dialog item */
   int   x;         /* x (RC) of the upper-left corner */
   int   y;         /* y (RC) of the upper-left corner */
   int   cx;      /* width ( RC ) of the item */
   int   cy;      /* height ( RC ) of the item */
   int   id;      /* id of the item */
   long   lStyle;   /* style of the item */
   /* szClass[]*/ /* Null-terminated string  */
   /* szText[] */   /* Null-terminated string */
   /* byInfo */   /* count of the additional data */
} DIT, FAR * LPDIT;

static char     szDlgPageProp[] = "DialogPageHeader";
static char               *aSysClass[] = {
   "button", "edit", "static", "listbox", 
   "scrollbar", "combobox" 
};
static HANDLE CreatePageCtl( LPDIT, HANDLE, HWND, WORD, POINT, BOOL );

BOOL  CreateDlgPage( 
   HWND     hWnd,    // handle to the base dialog 
   HANDLE   hInst,   // instance handle of resource
   LPSTR    lpName,  // name of the dialog template
   POINT    pt,      // controls offset
   BOOL     fShow )  // initially visiable?
{

   BOOL      fSuccess;/* result of this function */
   HANDLE   hRes;      /* handle to the resource */
   HANDLE   hDlgRes;   /* handle to the mem resource */
   HANDLE   hHdr;      /* handle to the page header */
   HANDLE   hCtls;   /* handle to the control list */
   LPDT      lpdt;      /* points to dialogTemplate */
   LPBYTE   lpby;      /* pointer for calculation */
   LPDLGHDR   lpHdr;   /* points to page header */

   fSuccess = FALSE;
   hRes = hDlgRes = 0;
   lpdt = NULL;

   hHdr = GetProp( hWnd, szDlgPageProp );
   if ( ! hHdr )
   {
      fSuccess=hHdr=GlobalAlloc(GHND, sizeof(DLGHDR));
   }
   else
   {
      lpHdr = ( LPDLGHDR ) GlobalLock( hHdr );
      if ( lpHdr )
      {
         fSuccess = lpHdr->cPg < MAXPAGE;
         GlobalUnlock( hHdr );
      }
   }
   SetProp( hWnd, szDlgPageProp, hHdr );

   /* find the dialog box template */
   if (  fSuccess
      && ( hRes=FindResource(hInst,lpName,RT_DIALOG))
      && ( hDlgRes = LoadResource( hInst, hRes ) )
      && ( lpdt = ( LPDT ) LockResource( hDlgRes ) ) )
   {
      lpby = ( LPBYTE ) ( lpdt + 1 );  // style ...
      lpby += lstrlen( lpby ) + 1;  // resource name
      lpby += lstrlen( lpby ) + 1;  // class
      lpby += lstrlen( lpby ) + 1;  // caption

      /* skip font info if specified */
      if ( DS_SETFONT & lpdt->lStyle )
      {
         lpby += sizeof ( short );     // point size
         lpby += lstrlen( lpby ) + 1;  // font name
      }

      /* Create the PAGE */
      fSuccess = hCtls = CreatePageCtl( (LPDIT) lpby,
         GetWindowWord( hWnd, GWW_HINSTANCE ), 
         hWnd, lpdt->cItem, pt, fShow );
   }
   if ( fSuccess )
   {
      fSuccess = FALSE;
      lpHdr = GlobalLock( hHdr );
      if ( lpHdr )
      {
         lpHdr->aPg[ lpHdr->cPg ].cCtls = lpdt->cItem;
         lpHdr->aPg[ lpHdr->cPg ].hCtls = hCtls;
         ( lpHdr->cPg )++;
         fSuccess = TRUE;
         GlobalUnlock( hHdr );
      }
   }
   if ( lpdt )
   {
      UnlockResource( hDlgRes );
   }
   if ( hDlgRes )
   {
      FreeResource( hDlgRes );
   }
   return ( fSuccess );
}

BOOL  ShowDlgPage( 
   HWND        hWnd,
   WORD        iPage,
   BOOL        fShow )
{

   int      i;         /* loop index */
   BOOL      fSuccess;/* result of this function */
   HANDLE   hHdr;      /* handle to dialog header data */
   LPHANDLE   lpCtls;   /* points to control list */
   LPDLGHDR   lpHdr;   /* points to page header */
   WORD      wShowFlag;      /* ShowWindow Flag */

   fSuccess = FALSE;

   /* ensure we can get our data */
   hHdr = GetProp( hWnd, szDlgPageProp );
   lpHdr = hHdr ? GlobalLock( hHdr ) : NULL;
   if ( lpHdr && lpHdr->cPg > iPage )
   {
      lpCtls = GlobalLock( lpHdr->aPg[ iPage ].hCtls );
      wShowFlag = fShow ? SW_SHOWNOACTIVATE : SW_HIDE;

      /* Show/hide each control in the list */
      for ( i = 0; i < lpHdr->aPg[ iPage ].cCtls; i++ )
      {
         ShowWindow( lpCtls[ i ], wShowFlag );
         InvalidateRect( lpCtls[ i ], NULL, TRUE );
         UpdateWindow( lpCtls[ i ] );
      }

      fSuccess = TRUE;
      GlobalUnlock( lpHdr->aPg[ iPage ].hCtls );
   }
   if ( lpHdr )
   {
      GlobalUnlock( hHdr );
   }

   return( fSuccess );

}
 
BOOL  EndDlgPage( 
   HWND        hWnd )
{

   int      i;            /* loop index */
   BOOL      fSuccess;   /* result of this function */
   HANDLE   hHdr;         /* handle to the page header*/
   LPDLGHDR   lpHdr;      /* points to page header */

   fSuccess = FALSE;
   hHdr = GetProp( hWnd, szDlgPageProp );
   lpHdr = hHdr ? GlobalLock( hHdr ) : NULL;
   if ( lpHdr )
   {
      /* Free each pages' control list */
      for ( i = 0; i < lpHdr->cPg; i++ )
      {
         if ( lpHdr->aPg[ i ].hCtls )
         {
            GlobalFree( lpHdr->aPg[ i ].hCtls );
         }
      }

      fSuccess = TRUE;
      GlobalUnlock( hHdr );
      GlobalFree( hHdr );
   }
   RemoveProp( hWnd, szDlgPageProp );

   return ( fSuccess );
}

static HANDLE CreatePageCtl( 
   LPDIT         lpdit,
   HANDLE      hInst,
   HWND        hwndParent,
   WORD        cItem,
   POINT       ptOffset,
   BOOL        fVisible )
{

   RECT        rc;
   int         id;         /* id of the control */
   HWND         hwnd;         /* handle to the  */
   HANDLE      hCtls;      /* handle to the list */
   WORD         cCtlCreated;/* count of created  */
   LONG         lStyle;      /* style of the control */
   LPSTR         lpszClass;   /* control class name */
   LPSTR         lpszText;   /* control text */
   LPBYTE      lpbyInfo;   /* control information */
   LPBYTE      lpby;         /* pointer for calculation*/
   LPHANDLE      lpCtls;      /* points to control list */

   cCtlCreated = 0;        /* intialization */

   /* allocate memory for control list */
    hCtls = GlobalAlloc( GHND, sizeof( HWND ) * cItem );
   lpCtls = (LPHANDLE)(hCtls?GlobalLock(hCtls) : NULL);

   while ( lpCtls && cCtlCreated < cItem )
   {
      rc.left = lpdit->x;
      rc.top = lpdit->y;
      rc.right = lpdit->x + lpdit->cx;
      rc.bottom = lpdit->y + lpdit->cy;
      MapDialogRect( hwndParent, &rc );
      OffsetRect( &rc, ptOffset.x, ptOffset.y );

      id = lpdit->id;
      lStyle = lpdit->lStyle;
      lpby = ( LPBYTE ) ( lpdit + 1 );

      /* Is this a system defined class ? */
      if ( *lpby & SYSCLASS )
      {
         lpszClass = aSysClass[ *lpby - SYSCLASS ];
         lpby++;
      }
      else
      {
         lpszClass = lpby;
         lpby += lstrlen( lpszClass ) + 1;
      }

      lpszText = ( LPSTR )lpby;
      lpby += lstrlen( lpszText ) + 1;
      lpbyInfo = *lpby ? lpby + 1 : 0; 
      lpdit = (LPDIT) (LPBYTE) ( *lpby + 1 + lpby );

      /* Should the control be visible ? */
      lStyle = fVisible ? lStyle | WS_VISIBLE : lStyle & ~WS_VISIBLE;
      hwnd = CreateWindow( lpszClass, lpszText, 
         lStyle, 
         rc.left, rc.top,
         rc.right - rc.left, rc.bottom - rc.top,
         hwndParent, id, hInst, lpbyInfo );

      if ( IsWindow( hwnd ) )
      {
         lpCtls[ cCtlCreated++ ] = hwnd;
      }
      else
      {
         break;
      }
   }
   if ( lpCtls )
   {
      GlobalUnlock( hCtls );
   }
   return ( hCtls );
}

