#pragma	title("Super Notebook Custom Control  --  Version 1.0 -- (NotePage.C)")
#pragma	subtitle("   Resource Editor - Interface Definitions")

#pragma	info(noext)
	
#define	INCL_DOS		   /* Include OS/2 DOS Kernal		*/
#define	INCL_GPI		   /* Include OS/2 PM GPI Interface	*/
#define	INCL_WIN		   /* Include OS/2 PM Windows Interface	*/
#define	INCL_NLS		   /* Include OS/2 PM NLS Support	*/

#include <os2.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <pmcx.h>

#include "notepage.h"

/* This	module contains	an example installable control that can	be used	*/
/* within applications where additional	facilities are provided	that	*/
/* are not found within	the default controls of	OS/2 PM.		*/
/*									*/
/* For complete	details	regarding the PM Control Extensions (PMCX)	*/
/* consult the User's Guide.                                            */
/*									*/
/* The DLL is created using the	following command line invocation:	*/
/*									*/
/*     Icc -G3e- -O+ -Rn -W3 -C	NotePage.C				*/

/* Filename:   NotePage.C						*/

/*  Version:   1.0							*/
/*  Created:   1993-12-21						*/
/*  Revised:   1994-06-26						*/

/* Routines:   BOOL EXPENTRY NotePageRegister(HAB hAB);			*/
/*	       BOOL EXPENTRY NotePageQuery(PUSERINFO pUserInfo);	*/
/*	       MRESULT EXPENTRY	NotePageWndProc(HWND hWnd, ULONG msg,	*/
/*						MPARAM mp1, MPARAM mp2);*/
/*	       MRESULT EXPENTRY	NotePageStyles(HWND hWnd, ULONG	msg,	*/
/*					       MPARAM mp1, MPARAM mp2);	*/


/* Copyright ¸ 1989-1994  Prominare Inc.  All Rights Reserved.		*/

/* --------------------------------------------------------------------	*/

/************************************************************************/
/************************************************************************/
/*		       DISCLAIMER OF WARRANTIES.			*/
/************************************************************************/
/************************************************************************/
/*     The following [enclosed]	code is	library	code created by		*/
/*     Prominare Inc.  This library code is  provided to you solely	*/
/*     for the purpose of assisting you	in the development of your	*/
/*     applications.  The code is provided "AS IS", without		*/
/*     warranty	of any kind.  Prominare	Inc. shall not be liable	*/
/*     for any damages arising out of your use of the library code,	*/
/*     even if they have been advised of the possibility of such	*/
/*     damages.								*/
/************************************************************************/
/************************************************************************/

/* --- Notebook	Page Window Information	Structures --------------------	*/

typedef	struct _NOTEPAGE
   {
   HWND	     hWnd;		   /* Control Window Handle		*/
   ULONG     id;		   /* ID Value				*/
   HWND	     hwndOwner;		   /* Owner Window Handle		*/
   HWND	     hwndParent;	   /* Parent Window Handle		*/
   HWND	     hwndNotePage;	   /* Combo Box	Window Handle		*/
   ULONG     cPages;		   /* Total Page Count			*/
   PHWND     ahwndPages;	   /* Pages Window Handle Array		*/
   PULONG    aidPages;		   /* Pages ID Array			*/
   } NOTEPAGE ;

typedef	NOTEPAGE *PNOTEPAGE;

/* --- Notebook	Page Control Data Support -----------------------------	*/

typedef	struct _NOTEPAGECDATA
   {
   ULONG    cb;			   /* Structure	Size			*/
   ULONG    cPages;		   /* Page Count			*/
   ULONG    cIDs;		   /* ID's Count                        */
   ULONG    cTabItems;		   /* Tab Item Count			*/
   ULONG    cTab;		   /* Tab Text Length			*/
   ULONG    cStatusItems;	   /* Status Item Count			*/
   ULONG    cStatus;		   /* Status Text Length		*/
   BYTE	    abList[1];		   /* Variable Data Start		*/
   } NOTEPAGECDATA ;

typedef	NOTEPAGECDATA *PNOTEPAGECDATA;

BOOL	EXPENTRY NotePageRegister(HAB hAB);
BOOL	EXPENTRY NotePageQuery(PUSERINFO pUserInfo);
MRESULT	EXPENTRY NotePageStyles(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);

/************************************************************************/
/************************************************************************/
/*									*/
/* Styles supported:							*/
/*									*/
/*     All notebook styles						*/
/*									*/
/* Notification	messages:						*/
/*									*/
/*     All notebook notifications					*/
/*									*/
/* Control messages:							*/
/*									*/
/*     In addition to the BKM_*	messages:				*/
/*									*/
/*     NPM_QUERYHANDLES	   : Query notebook dialogue handles		*/
/*	   Input:							*/
/*		   mp1 = address of HWND array for the total number	*/
/*			 pages notebook	contains			*/
/*		   mp2 = 0L;						*/
/*	   Ouptut:							*/
/*		   0L							*/
/*     NPM_QUERYIDS	   : Query notebook page ID's                   */
/*	   Input:							*/
/*		   mp1 = address of ULONG array	for the	total number	*/
/*			 pages notebook	contains			*/
/*		   mp2 = 0L;						*/
/*	   Ouptut:							*/
/*		   0L							*/
/*									*/
/************************************************************************/
/************************************************************************/

MRESULT	EXPENTRY PageDlgProc(HWND hWnd,	ULONG msg, MPARAM mp1, MPARAM mp2);
VOID InitNotebook(HWND hWnd, PNOTEPAGE pnp, PNOTEPAGECDATA pnpcd);

MRESULT	EXPENTRY NotePageWndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);

VOID  EnableNoteBookCtrls(HWND hWnd, ULONG flStyle);
VOID  SetNoteBookCtrls(HWND hWnd, ULONG	flStyle);
VOID  UpdateNoteBookCtrls(HWND hWnd, MPARAM mp1);
ULONG flGetNoteBookCtrls(HWND hWnd);
VOID  InitNotebookPageData(HWND	hWnd, PNOTEPAGECDATA pnpcd);
VOID  GetNotebookPageData(HWND hWnd, PNOTEPAGECDATA pnpcd, PUSERSTYLE	pust);

#pragma	subtitle("   Super Notebook Control - Control Initialization Function")
#pragma	page ( )

/* --- NotePageRegister	-------------------------------- [ Public ] ---	*/
/*									*/
/*     This function is	used to	register the installable control class	*/
/*     with OS/2 Presentation Manager.	The registration must use the	*/
/*     USER_CWINDOWWORDS to reserve memory for the control to allow for	*/
/*     proper usage by Resource	Editor and for use by the control	*/
/*     dialog and window procedures.  The information for the control	*/
/*     containing the style, presentation parameters and control data	*/
/*     is pointed to by	a pointer that can be referenced by the		*/
/*     control's dialog and window procedure as required.  The memory   */
/*     for the structure is allocated and controlled through Resource	*/
/*     Editor.	 The control can reserve more memory for its use	*/
/*     by adding the memory required to	that of	the USER_CWINDOWWORDS	*/
/*     constant.							*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HAB hAB;	= Application Anchor Block Handle			*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     NotePageRegister	=  TRUE	: Class	Registration Successful		*/
/*			= FALSE	: Class	Registration Failed		*/
/*									*/
/* --------------------------------------------------------------------	*/

BOOL EXPENTRY NotePageRegister(HAB hAB)

{
		       /* Register the control class with OS/2		*/
		       /* Presentation Manager and return registration	*/
		       /* result					*/

return(WinRegisterClass(hAB, "NotePage", (PFNWP)NotePageWndProc,
			CS_MOVENOTIFY |	CS_PARENTCLIP |	CS_SIZEREDRAW |	CS_SYNCPAINT,
			USER_CWINDOWWORDS));

}
#pragma	subtitle("   Combo Box - Query Control Information Function")
#pragma	page ( )

/* --- NotePageQuery ----------------------------------- [ Public ] ---	*/
/*									*/
/*     This function is	used to	return to the caller information	*/
/*     regarding the installable control and its capabilities.	The	*/
/*     function	should return a	true value otherwise Resource		*/
/*     Editor will not register	the control as being usable.		*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     PUSERINFO pUserInfo; = User Information Pointer			*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     NotePageQuery =	TRUE : User Information	Being Returned		*/
/*		     = FALSE : No User Information Available		*/
/*									*/
/* --------------------------------------------------------------------	*/

BOOL EXPENTRY NotePageQuery(PUSERINFO pUserInfo)

{
		       /* Complete the User Information	structure	*/
		       /* passed to the	function by Resource Editor	*/

		       /* Complete the version and number of control	*/
		       /* types.  In Version 1.00 of CCRS, only	one	*/
		       /* control type is used.				*/
pUserInfo->ulMajor = 2UL;
pUserInfo->ulMinor = 0UL;
		       /* Complete the author and control classname	*/

memcpy(pUserInfo->szAuthor,    "Prominare Inc.", 15);
memcpy(pUserInfo->szClassname, "NotePage", 9);
memcpy(pUserInfo->szName,      "NotePage", 9);

		       /* Complete the default size and	style of the	*/
		       /* first	user control type			*/

pUserInfo->utDefined[0].cx	     = 100L;
pUserInfo->utDefined[0].cy	     = 100L;
pUserInfo->utDefined[0].flStyle	     = BKS_BACKPAGESBR | BKS_MAJORTABRIGHT | BKS_SQUARETABS |
				       WS_VISIBLE | WS_TABSTOP;

		       /* Set the maximum amount of text control can	*/
		       /* accept including NULL	termination byte	*/

pUserInfo->utDefined[0].cMaxText     = 0UL;

		       /* Save the style's dialogue ID, type, control   */
		       /* data size and	count of style masks		*/

pUserInfo->utDefined[0].idDlg	     = DLG_CTRLUSER;
pUserInfo->utDefined[0].ulType	     = UTYPE_PRIVATE;
pUserInfo->utDefined[0].cCtlData     = sizeof(NOTEPAGECDATA);
pUserInfo->utDefined[0].cMasks	     = 19UL;
pUserInfo->utDefined[0].flOptions    = PMCXOPT_VARICDATA | PMCXOPT_REFRESH;
pUserInfo->utDefined[0].flStyleType  = STYLETYPE_BITFLAGS;
pUserInfo->utDefined[0].stMasks[0].flStyleMask = BKS_BACKPAGESBR;
pUserInfo->utDefined[0].stMasks[0].idStyle     = IDS_BKS_BACKPAGESBR;
pUserInfo->utDefined[0].stMasks[1].flStyleMask = BKS_BACKPAGESBL;
pUserInfo->utDefined[0].stMasks[1].idStyle     = IDS_BKS_BACKPAGESBL;
pUserInfo->utDefined[0].stMasks[2].flStyleMask = BKS_BACKPAGESTR;
pUserInfo->utDefined[0].stMasks[2].idStyle     = IDS_BKS_BACKPAGESTR;
pUserInfo->utDefined[0].stMasks[3].flStyleMask = BKS_BACKPAGESTL;
pUserInfo->utDefined[0].stMasks[3].idStyle     = IDS_BKS_BACKPAGESTL;
pUserInfo->utDefined[0].stMasks[4].flStyleMask = BKS_MAJORTABLEFT;
pUserInfo->utDefined[0].stMasks[4].idStyle     = IDS_BKS_MAJORTABLEFT;
pUserInfo->utDefined[0].stMasks[5].flStyleMask = BKS_MAJORTABRIGHT;
pUserInfo->utDefined[0].stMasks[5].idStyle     = IDS_BKS_MAJORTABRIGHT;
pUserInfo->utDefined[0].stMasks[6].flStyleMask = BKS_MAJORTABTOP;
pUserInfo->utDefined[0].stMasks[6].idStyle     = IDS_BKS_MAJORTABTOP;
pUserInfo->utDefined[0].stMasks[7].flStyleMask = BKS_MAJORTABBOTTOM;
pUserInfo->utDefined[0].stMasks[7].idStyle     = IDS_BKS_MAJORTABBOTTOM;
pUserInfo->utDefined[0].stMasks[8].flStyleMask = BKS_SQUARETABS;
pUserInfo->utDefined[0].stMasks[8].idStyle     = IDS_BKS_SQUARETABS;
pUserInfo->utDefined[0].stMasks[9].flStyleMask = BKS_ROUNDEDTABS;
pUserInfo->utDefined[0].stMasks[9].idStyle     = IDS_BKS_ROUNDEDTABS;
pUserInfo->utDefined[0].stMasks[10].flStyleMask	= BKS_POLYGONTABS;
pUserInfo->utDefined[0].stMasks[10].idStyle	= IDS_BKS_POLYGONTABS;
pUserInfo->utDefined[0].stMasks[11].flStyleMask	= BKS_SOLIDBIND;
pUserInfo->utDefined[0].stMasks[11].idStyle	= IDS_BKS_SOLIDBIND;
pUserInfo->utDefined[0].stMasks[12].flStyleMask	= BKS_SPIRALBIND;
pUserInfo->utDefined[0].stMasks[12].idStyle	= IDS_BKS_SPIRALBIND;
pUserInfo->utDefined[0].stMasks[13].flStyleMask	= BKS_STATUSTEXTLEFT;
pUserInfo->utDefined[0].stMasks[13].idStyle	= IDS_BKS_STATUSTEXTLEFT;
pUserInfo->utDefined[0].stMasks[14].flStyleMask	= BKS_STATUSTEXTRIGHT;
pUserInfo->utDefined[0].stMasks[14].idStyle	= IDS_BKS_STATUSTEXTRIGHT;
pUserInfo->utDefined[0].stMasks[15].flStyleMask	= BKS_STATUSTEXTCENTER;
pUserInfo->utDefined[0].stMasks[15].idStyle	= IDS_BKS_STATUSTEXTCENTER;
pUserInfo->utDefined[0].stMasks[16].flStyleMask	= BKS_TABTEXTLEFT;
pUserInfo->utDefined[0].stMasks[16].idStyle	= IDS_BKS_TABTEXTLEFT;
pUserInfo->utDefined[0].stMasks[17].flStyleMask	= BKS_TABTEXTRIGHT;
pUserInfo->utDefined[0].stMasks[17].idStyle	= IDS_BKS_TABTEXTRIGHT;
pUserInfo->utDefined[0].stMasks[18].flStyleMask	= BKS_TABTEXTCENTER;
pUserInfo->utDefined[0].stMasks[18].idStyle	= IDS_BKS_TABTEXTCENTER;

		       /* Save the description of the control		*/

memcpy(pUserInfo->utDefined[0].szDescription, "Super Notebook",	15);

		       /* Return the success flag back to Resource	*/
		       /* Editor					*/
return(TRUE);
}
#pragma	subtitle("   Super Notebook Control - Dialogue Page Handler")
#pragma	page( )

/* --- PageDlgProc ------------------------------------	[ Private ] ---	*/
/*									*/
/*     This function is	used to	process	the messages for the dialogue	*/
/*     that is associated with a notebook page.	 Since the setting of	*/
/*     elements	within the page	are handled outside of the dialogue,	*/
/*     virtually no processing is done by procedure.			*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND   hWnd; = Dialogue Window Handle				*/
/*     ULONG  msg;  = PM Message					*/
/*     MPARAM mp1;  = Message Parameter	1				*/
/*     MPARAM mp2;  = Message Parameter	2				*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     ProjBaseInfoDlgProc = Message Handling Result			*/
/*									*/
/* --------------------------------------------------------------------	*/

MRESULT	EXPENTRY PageDlgProc(HWND hWnd,	ULONG msg, MPARAM mp1, MPARAM mp2)

{
if ( msg == WM_COMMAND )
   return(0L);

return(WinDefDlgProc(hWnd, msg,	mp1, mp2));
}
#pragma	subtitle("   Super Notebook Control - Notebook Setup Procedure")
#pragma	page( )

/* --- InitNotebook -----------------------------------	[ Private ] ---	*/
/*									*/
/*     This function is	used to	decode the CTLDATA of the notebook	*/
/*     control setting up each notebook	page, tab and status lines.	*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND	      hWnd;  = Window Handle				*/
/*     PNOTEPAGE      pnp;   = PM Message				*/
/*     PNOTEPAGECDATA pnpcd; = Message Parameter 1			*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     Nothing								*/
/*									*/
/* --------------------------------------------------------------------	*/

VOID InitNotebook(HWND hWnd, PNOTEPAGE pnp, PNOTEPAGECDATA pnpcd)

{
FONTMETRICS fm;			   /* Font Metrics Pointer		*/
HPS	    hPS;		   /* Presentation Space Handle		*/
LONG	    cxTab;		   /* Tab Width				*/
LONG	    cyTab;		   /* Tab Height			*/
PBYTE	    pb;			   /* Byte Pointer			*/
PSZ	    *apszStatusText;	   /* Status Text String Pointer Array	*/
PSZ	    *apszTabText;	   /* Tab Text String Pointer Array	*/
PULONG	    pulIDs;		   /* ID's Array Pointer                */
PVOID	    pdt;		   /* Window/Dialogue Template Pointer	*/
RECTL	    rcl;		   /* Display Rectangle			*/
register INT i,	n;		   /* Loop Counters			*/

		       /* Allocate space for the page handle and page	*/
		       /* ID array's which allow the user to            */
		       /* communicate to the individual	pages as is	*/
		       /* required					*/

DosAllocMem((PPVOID)(PVOID)&pnp->ahwndPages, pnpcd->cPages * sizeof(HWND),
	    PAG_READ | PAG_WRITE | PAG_COMMIT);
DosAllocMem((PPVOID)(PVOID)&pnp->aidPages, pnpcd->cPages * sizeof(ULONG),
	    PAG_READ | PAG_WRITE | PAG_COMMIT);

		       /* Allocate space for the tab text and status	*/
		       /* line pointer arrays				*/

DosAllocMem((PPVOID)(PVOID)&apszTabText,    pnpcd->cPages * sizeof(PSZ),
	    PAG_READ | PAG_WRITE | PAG_COMMIT);
DosAllocMem((PPVOID)(PVOID)&apszStatusText, pnpcd->cPages * sizeof(PSZ),
	    PAG_READ | PAG_WRITE | PAG_COMMIT);

		       /* Point	to the dialogue	ID list			*/

pulIDs = (PULONG)pnpcd->abList;

		       /* Point	to the start of	the data block that	*/
		       /* contains the status item text			*/

pb = pnpcd->abList + pnpcd->cPages * sizeof(ULONG);

		       /* Save the number of pages that	the notebook is	*/
		       /* to contain					*/

pnp->cPages = pnpcd->cPages;

		       /* Scan the status text block for the start of	*/
		       /* each status line and place the address within	*/
		       /* the pointer array to allow quick setting of	*/
		       /* status line text				*/

for ( i	= n = 0; i < pnpcd->cStatusItems; i++ )
   {
   apszStatusText[i] = &pb[n];
   n +=	(INT)strlen(&pb[n]) + 1;
   }
		       /* Point	to the start of	the data block that	*/
		       /* contains the status item text			*/

pb = pnpcd->abList + pnpcd->cPages * sizeof(ULONG) + pnpcd->cStatus;

		       /* Scan the tab text block for the start	of each	*/
		       /* tab and place	the address within the pointer	*/
		       /* array	to allow quick setting of tab text	*/

for ( i	= n = 0; i < pnpcd->cTabItems; i++ )
   {
   apszTabText[i] = &pb[n];
   n +=	(INT)strlen(&pb[n]) + 1;
   }
		       /* Have performed the initial decoding of the	*/
		       /* CTLDATA for the notebook, now	setup each of	*/
		       /* pages	by inserting a page within the notebook	*/
		       /* and putting the status and tab text within	*/
		       /* the page					*/

for ( i	= 0; i < pnpcd->cPages;	i++ )		
   {
		       /* Create the Dialogue/Window notebook page and	*/
		       /* save the page	ID within the internal array in	*/
		       /* case the user	wants to use it	later		*/

   pnp->aidPages[i] = (ULONG)LONGFROMMR(WinSendMsg(pnp->hwndNotePage, BKM_INSERTPAGE, 0L,
						   MPFROM2SHORT((BKA_STATUSTEXTON | BKA_AUTOPAGESIZE | BKA_MAJOR), BKA_LAST)));

		       /* Set up the status line text for the page	*/

   WinSendMsg(pnp->hwndNotePage, BKM_SETSTATUSLINETEXT,
	      MPFROMLONG(pnp->aidPages[i]), MPFROMP(apszStatusText[i]));

		       /* Set up the tab text for the page		*/

   WinSendMsg(pnp->hwndNotePage, BKM_SETTABTEXT,
	      MPFROMLONG(pnp->aidPages[i]), MPFROMP(apszTabText[i]));

		       /* Try to retrieve the dialogue template	from	*/
		       /* the executable resources			*/

   if (	!DosGetResource((HMODULE)NULL, RT_DIALOG, pulIDs[i], (PPVOID)&pdt) )
       {
		       /* Template successfully	retrieved from the	*/
		       /* executable resources,	create the dialogue	*/
		       /* from the template and	place the dialogue	*/
		       /* within the notebook page			*/

       pnp->ahwndPages[i] = WinCreateDlg(HWND_DESKTOP, (HWND)NULL, (PFNWP)PageDlgProc,
					 (PDLGTEMPLATE)pdt, NULL);
       WinSendMsg(pnp->hwndNotePage, BKM_SETPAGEWINDOWHWND,
		  MPFROMLONG(pnp->aidPages[i]),	MPFROMHWND(pnp->ahwndPages[i]));

		       /* Release the dialogue template	resource	*/

       DosFreeResource((PVOID)pdt);
       }
   }
		       /* Get the font metrics for the control		*/

GpiQueryFontMetrics(hPS	= WinGetPS(hWnd), sizeof(FONTMETRICS),
		    &fm);

		       /* Loop through the tab text array and determine	*/
		       /* the maximum width of the tab text to allow it	*/
		       /* to be	properly set				*/

for ( i	= 0, cxTab = cyTab = 0L; i < pnpcd->cTabItems; i++ )
   {
		       /* Set the display rectangle to be very large	*/

   rcl.xLeft = rcl.yBottom = 0L;
   rcl.xRight =	rcl.yTop = 1024L;

		       /* Query	the extents of the text			*/

   WinDrawText(hPS, -1L, apszTabText[i], &rcl, CLR_BLACK, CLR_BLACK,
	       DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT);

		       /* Check	to see if the tab text size is larger	*/
		       /* than the current maximum size	in which case	*/
		       /* the size should be updated			*/

   if (	(rcl.xRight - rcl.xLeft) > cxTab )
       cxTab = (rcl.xRight - rcl.xLeft);
   if (	(rcl.yTop - rcl.yBottom) > cyTab )
       cyTab = (rcl.yTop - rcl.yBottom);
   }
		       /* Release the presentation space handle		*/
WinReleasePS(hPS);
		       /* Set the tab text dimensions			*/

WinSendMsg(pnp->hwndNotePage, BKM_SETDIMENSIONS,
	   MPFROM2SHORT((SHORT)cxTab + fm.lAveCharWidth	* 2, (SHORT)cyTab + fm.lMaxBaselineExt),
	   MPFROMSHORT(BKA_MAJORTAB));

		       /* Set the dimension of the notebook buttons	*/

WinSendMsg(pnp->hwndNotePage, BKM_SETDIMENSIONS, MPFROM2SHORT(21, 21),
	   MPFROMLONG(BKA_PAGEBUTTON));

		       /* Set the background colours to	that of	the	*/
		       /* dialogue					*/

WinSendMsg(pnp->hwndNotePage, BKM_SETNOTEBOOKCOLORS, MPFROMLONG(SYSCLR_DIALOGBACKGROUND),
	   MPFROMLONG(BKA_BACKGROUNDPAGECOLORINDEX));
WinSendMsg(pnp->hwndNotePage, BKM_SETNOTEBOOKCOLORS, MPFROMLONG(SYSCLR_DIALOGBACKGROUND),
	   MPFROMLONG(BKA_BACKGROUNDMAJORCOLORINDEX));

		       /* Release the memory allocated for the string	*/
		       /* pointer arrays				*/

DosFreeMem((PVOID)&apszTabText);
DosFreeMem((PVOID)&apszStatusText);
}
#pragma	subtitle("   Super Notebook Control - Control Window Procedure")
#pragma	page( )

/* --- NotePageWndProc --------------------------------	[ Private ] ---	*/
/*									*/
/*     This function is	used to	process	the messages for the notebook	*/
/*     control window.							*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND   hWnd; = Window Handle					*/
/*     ULONG  msg;  = PM Message					*/
/*     MPARAM mp1;  = Message Parameter	1				*/
/*     MPARAM mp2;  = Message Parameter	2				*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     NotePageWndProc = Message Handling Result			*/
/*									*/
/* --------------------------------------------------------------------	*/

MRESULT	EXPENTRY NotePageWndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)

{
PNOTEPAGE      pnp;		   /* Note Page	Internal Data Pointer	*/
PCREATESTRUCT  pcrst;		   /* Create Structure Pointer		*/
PSWP	       pswp;		   /* SWP Structure Pointer		*/

switch ( msg )
   {

/************************************************************************/
/************************************************************************/
/*									*/
/* Part	1: Control creation coding					*/
/*									*/
/************************************************************************/
/************************************************************************/

   /*********************************************************************/
   /*  Control creation							*/
   /*********************************************************************/

   case	WM_CREATE :
		       /* Allocate memory for internal control data	*/

       DosAllocMem((PPVOID)(PVOID)&pnp,	sizeof(NOTEPAGE),
		   PAG_READ | PAG_WRITE	| PAG_COMMIT);

		       /* Save the address of the internal control data	*/
		       /* in the control's reserved memory to allow it  */
		       /* to be	referenced as required by the control	*/

       WinSetWindowPtr(hWnd, QWW_CDATA,	(PVOID)pnp);

		       /* Get the control's creation structure address  */
		       /* to copy the relevant information such	as the	*/
		       /* size,	position and text of the control into	*/
		       /* the internal control data			*/

       pcrst = (PCREATESTRUCT)PVOIDFROMMP(mp2);

		       /* Save the owner and parent of the control so	*/
		       /* notification messages	can be sent back to	*/
		       /* the proper locations within the owning	*/
		       /* application					*/

       pnp->hWnd       = hWnd;
       pnp->hwndOwner  = pcrst->hwndOwner;
       pnp->hwndParent = pcrst->hwndParent;

       if ( !(pnp->hwndNotePage	= WinCreateWindow(hWnd,	WC_NOTEBOOK, pcrst->pszText,
						  pcrst->flStyle,
						  0L, 0L, pcrst->cx, pcrst->cy,
						  hWnd,	HWND_TOP, 0x1234UL,
						  (PVOID)NULL, (PVOID)pcrst->pPresParams)) )
	   return(MRFROMLONG(TRUE));

		       /* Get the address of the CTLDATA structure that	*/
		       /* may contain the bitmap information that the	*/
		       /* control can use during its creation instead	*/
		       /* of using messages to set the button images	*/

       if ( PVOIDFROMMP(mp1) )
	   InitNotebook(hWnd, pnp, (PNOTEPAGECDATA)PVOIDFROMMP(mp1));
       break;

/************************************************************************/
/************************************************************************/
/*									*/
/* Part	2: Control sizing and positioning coding			*/
/*									*/
/************************************************************************/
/************************************************************************/

   /*********************************************************************/
   /*  Control being sized						*/
   /*********************************************************************/

   case	WM_ADJUSTWINDOWPOS :
		       /* Get the address of the control info from the	*/
		       /* control's reserved memory                     */

       pnp = (PNOTEPAGE)WinQueryWindowPtr(hWnd,	QWW_CDATA);
       pswp = (PSWP)PVOIDFROMMP(mp1);
       if ( pswp->fl & SWP_SIZE	)
	   WinSetWindowPos(pnp->hwndNotePage, HWND_TOP,	0L, 0L,
			   pswp->cx, pswp->cy,
			   SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
       break;

   case	WM_SIZE	:
		       /* Get the address of the control info from the	*/
		       /* control's reserved memory                     */

       pnp = (PNOTEPAGE)WinQueryWindowPtr(hWnd,	QWW_CDATA);
       WinSetWindowPos(pnp->hwndNotePage, HWND_TOP, 0L,	0L,
		       (LONG)SHORT1FROMMP(mp2),	(LONG)SHORT2FROMMP(mp2),
		       SWP_SIZE	| SWP_MOVE | SWP_SHOW |	SWP_ACTIVATE);
       break;

/************************************************************************/
/************************************************************************/
/*									*/
/* Part	3: Control sizing and positioning coding			*/
/*									*/
/************************************************************************/
/************************************************************************/

   /*********************************************************************/
   /*  Control notification messages					*/
   /*********************************************************************/

   case	WM_CONTROL :
       if ( SHORT1FROMMP(mp1) == 0x1234	)
	   {
		       /* Get the address of the control info from the	*/
		       /* control's reserved memory                     */

	   pnp = (PNOTEPAGE)WinQueryWindowPtr(hWnd, QWW_CDATA);
	   WinSendMsg(pnp->hwndOwner, msg,
		      MPFROM2SHORT(pnp->id, SHORT2FROMMP(mp1)),	mp2);
	   }
       break;

/************************************************************************/
/************************************************************************/
/*									*/
/* Part	3: Control sizing and positioning coding			*/
/*									*/
/************************************************************************/
/************************************************************************/

   /*********************************************************************/
   /*  Control being sized						*/
   /*********************************************************************/

   case	WM_CONTROLPOINTER :

		       /* Get the address of the control info from the	*/
		       /* control's reserved memory                     */

       pnp = (PNOTEPAGE)WinQueryWindowPtr(hWnd,	QWW_CDATA);
       return(WinSendMsg(pnp->hwndOwner, msg, mp1, mp2));

/************************************************************************/
/************************************************************************/
/*									*/
/* Part	4: Control specific messages coding				*/
/*									*/
/************************************************************************/
/************************************************************************/

   case	BKM_CALCPAGERECT :
   case	BKM_DELETEPAGE :
   case	BKM_INSERTPAGE :
   case	BKM_INVALIDATETABS :
   case	BKM_TURNTOPAGE :
   case	BKM_QUERYPAGECOUNT :
   case	BKM_QUERYPAGEID	:
   case	BKM_QUERYPAGEDATA :
   case	BKM_QUERYPAGEWINDOWHWND	:
   case	BKM_QUERYTABBITMAP :
   case	BKM_QUERYTABTEXT :
   case	BKM_SETDIMENSIONS :
   case	BKM_SETPAGEDATA	:
   case	BKM_SETPAGEWINDOWHWND :
   case	BKM_SETSTATUSLINETEXT :
   case	BKM_SETTABBITMAP :
   case	BKM_SETTABTEXT :
   case	BKM_SETNOTEBOOKCOLORS :
   case	BKM_QUERYPAGESTYLE :
   case	BKM_QUERYSTATUSLINETEXT	:
		       /* Get the address of the control info from the	*/
		       /* control's reserved memory                     */

       pnp = (PNOTEPAGE)WinQueryWindowPtr(hWnd,	QWW_CDATA);
       return(WinSendMsg(pnp->hwndNotePage, msg, mp1, mp2));

/************************************************************************/
/************************************************************************/
/*									*/
/* Part	5: General window messages					*/
/*									*/
/************************************************************************/
/************************************************************************/

   /*********************************************************************/
   /*  General window messages are sent	to the combo box		*/
   /*********************************************************************/

   case	WM_ACTIVATE :
   case	WM_BUTTON1CLICK	:
   case	WM_BUTTON1DBLCLK :
   case	WM_BUTTON1DOWN :
   case	WM_BUTTON1MOTIONEND :
   case	WM_BUTTON1MOTIONSTART :
   case	WM_CHAR	:
   case	WM_ENABLE :
   case	WM_HITTEST :
   case	WM_MOUSEMOVE :
   case	WM_MOVE	:
   case	WM_PRESPARAMCHANGED :
   case	WM_QUERYWINDOWPARAMS :
   case	WM_SETFOCUS :
   case	WM_SETSELECTION	:
   case	WM_SETWINDOWPARAMS :
   case	WM_SHOW	:
		       /* Get the address of the control info from the	*/
		       /* control's reserved memory                     */

       pnp = (PNOTEPAGE)WinQueryWindowPtr(hWnd,	QWW_CDATA);
       return(WinSendMsg(pnp->hwndNotePage, msg, mp1, mp2));

/************************************************************************/
/************************************************************************/
/*									*/
/* Part	6: Control destruction coding					*/
/*									*/
/************************************************************************/
/************************************************************************/

   /*********************************************************************/
   /*  Control being destroyed,	perform	clean-up			*/
   /*********************************************************************/

   case	WM_DESTROY :
		       /* Get the address of the control info from the	*/
		       /* control's reserved memory                     */

       pnp = (PNOTEPAGE)WinQueryWindowPtr(hWnd,	QWW_CDATA);
       WinDestroyWindow(pnp->hwndNotePage);
       DosFreeMem((PVOID)pnp->ahwndPages);
       DosFreeMem((PVOID)pnp->aidPages);
       DosFreeMem((PVOID)pnp);
       break;

/************************************************************************/
/************************************************************************/
/*									*/
/* Part	7: Default Processing						*/
/*									*/
/************************************************************************/
/************************************************************************/

		       /* Default message processing			*/
   default :
       return(WinDefWindowProc(hWnd, msg, mp1, mp2));

/************************************************************************/
/************************************************************************/
/*									*/
/* Part	8: Control Specific Messages					*/
/*									*/
/************************************************************************/
/************************************************************************/

		       /* Page Handles Query				*/
   case	NPM_QUERYHANDLES :
		       /* Get the address of the control info from the	*/
		       /* control's reserved memory                     */

       pnp = (PNOTEPAGE)WinQueryWindowPtr(hWnd,	QWW_CDATA);
       memcpy(PVOIDFROMMP(mp1),	pnp->ahwndPages, pnp->cPages * sizeof(HWND));
       break;

		       /* Page ID's Query                               */
   case	NPM_QUERYIDS :
		       /* Get the address of the control info from the	*/
		       /* control's reserved memory                     */

       pnp = (PNOTEPAGE)WinQueryWindowPtr(hWnd,	QWW_CDATA);
       memcpy(PVOIDFROMMP(mp1),	pnp->aidPages, pnp->cPages * sizeof(ULONG));
       break;
   }
return(0L);
}
#pragma	subtitle("   Super Notebook Control - Notebook Controls Enable Function")
#pragma	page( )

/* --- EnableNoteBookCtrls --------------------------------------------	*/
/*									*/
/*     This function is	used to	enable and disable tab position		*/
/*     controls	based on the backpage orientation option selected.	*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND hWnd;	  = Dialogue Window Handle			*/
/*     LONG flStyle;	  = Style Flags					*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     Nothing								*/
/*									*/
/* --------------------------------------------------------------------	*/

VOID EnableNoteBookCtrls(HWND hWnd, ULONG flStyle)

{
BOOL  fRight  =	FALSE;		   /* Right  Tabs Enabled Flag		*/
BOOL  fLeft   =	FALSE;		   /* Left   Tabs Enabled Flag		*/
BOOL  fTop    =	FALSE;		   /* Top    Tabs Enabled Flag		*/
BOOL  fBottom =	FALSE;		   /* Bottom Tabs Enabled Flag		*/
ULONG idBtn = 0xffffffffUL;	   /* Major Tab	Button ID		*/

		       /* Determine the	backpage orientation and	*/
		       /* enable or disable the	major tab orientation	*/
		       /* options.  The	rules are as follows:		*/
		       /*						*/
		       /* Backpage	       Major Tab		*/
		       /* Orientation	       Orientation		*/
		       /* ---------------------------------------------	*/
		       /*						*/
		       /* Bottom right	       Bottom and Right		*/
		       /* Bottom left	       Bottom and Left		*/
		       /* Top right	       Top and Right		*/
		       /* Top left	       Top and Left		*/
		       /* =============================================	*/

if ( flStyle & BKS_BACKPAGESBR )
   {
   fRight = fBottom = TRUE;
   if (	flStyle	& BKS_MAJORTABLEFT )
       idBtn = RB_BKS_MAJTABRIGHT;
   else
       if ( flStyle & BKS_MAJORTABTOP )
	   idBtn = RB_BKS_MAJTABBOT;
   }
else
   if (	flStyle	& BKS_BACKPAGESBL )
       {
       fBottom = fLeft = TRUE;
       if ( flStyle & BKS_MAJORTABRIGHT	)
	   idBtn = RB_BKS_MAJTABLEFT;
       else
	   if (	flStyle	& BKS_MAJORTABTOP )
	       idBtn = RB_BKS_MAJTABBOT;
       }
   else
       if ( flStyle & BKS_BACKPAGESTR )
	   {
	   fTop	= fRight = TRUE;
	   if (	flStyle	& BKS_MAJORTABLEFT )
	       idBtn = RB_BKS_MAJTABRIGHT;
	   else
	       if ( flStyle & BKS_MAJORTABBOTTOM )
		   idBtn = RB_BKS_MAJTABTOP;
	   }
       else
	   {
	   fTop	= fLeft	= TRUE;
	   if (	flStyle	& BKS_MAJORTABRIGHT )
	       idBtn = RB_BKS_MAJTABLEFT;
	   else
	       if ( flStyle & BKS_MAJORTABBOTTOM )
		   idBtn = RB_BKS_MAJTABTOP;
	   }

if ( idBtn != 0xffffffffUL )
   WinSendDlgItemMsg(hWnd, idBtn, BM_SETCHECK,
		     MPFROMSHORT(TRUE),	0L);

WinEnableWindow(WinWindowFromID(hWnd, RB_BKS_MAJTABRIGHT), fRight);
WinEnableWindow(WinWindowFromID(hWnd, RB_BKS_MAJTABLEFT),  fLeft);
WinEnableWindow(WinWindowFromID(hWnd, RB_BKS_MAJTABTOP),   fTop);
WinEnableWindow(WinWindowFromID(hWnd, RB_BKS_MAJTABBOT),   fBottom);
}
#pragma	subtitle("   Super Notebook Control - Notebook Setup Function")
#pragma	page( )

/* --- SetNoteBookCtrls	-----------------------------------------------	*/
/*									*/
/*     This function is	used to	set the	controls for the notebook	*/
/*     dialogue	box.							*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND hWnd;	  = Dialogue Window Handle			*/
/*     INT  iEnvironment; = Environment	Type Index			*/
/*     LONG flStyle;	  = Style Flags					*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     Nothing								*/
/*									*/
/* --------------------------------------------------------------------	*/

VOID SetNoteBookCtrls(HWND hWnd, ULONG flStyle)

{
		       /* Show the notebook type			*/

if ( flStyle & BKS_BACKPAGESBR )
   WinSendDlgItemMsg(hWnd, RB_BKS_BACKPAGESBR, BM_SETCHECK,
		     MPFROMSHORT(TRUE),	0L);
else
   if (	flStyle	& BKS_BACKPAGESBL )
       WinSendDlgItemMsg(hWnd, RB_BKS_BACKPAGESBL, BM_SETCHECK,
			 MPFROMSHORT(TRUE), 0L);
   else
       if ( flStyle & BKS_BACKPAGESTR )
	   WinSendDlgItemMsg(hWnd, RB_BKS_BACKPAGESTR, BM_SETCHECK,
			     MPFROMSHORT(TRUE),	0L);
       else
	   WinSendDlgItemMsg(hWnd, RB_BKS_BACKPAGESTL, BM_SETCHECK,
			     MPFROMSHORT(TRUE),	0L);

		       /* Show the tab location				*/

if ( flStyle & BKS_MAJORTABRIGHT )
   WinSendDlgItemMsg(hWnd, RB_BKS_MAJTABRIGHT, BM_SETCHECK,
		     MPFROMSHORT(TRUE),	0L);
else
   if (	flStyle	& BKS_MAJORTABLEFT )
       WinSendDlgItemMsg(hWnd, RB_BKS_MAJTABLEFT, BM_SETCHECK,
			 MPFROMSHORT(TRUE), 0L);
   else
       if ( flStyle & BKS_MAJORTABTOP )
	   WinSendDlgItemMsg(hWnd, RB_BKS_MAJTABTOP, BM_SETCHECK,
			     MPFROMSHORT(TRUE),	0L);
       else
	   WinSendDlgItemMsg(hWnd, RB_BKS_MAJTABBOT, BM_SETCHECK,
			     MPFROMSHORT(TRUE),	0L);

		       /* Show the tabs	type				*/

if ( flStyle & BKS_POLYGONTABS )
   WinSendDlgItemMsg(hWnd, RB_BKS_POLYGONTABS, BM_SETCHECK,
		     MPFROMSHORT(TRUE),	0L);
else
   if (	flStyle	& BKS_ROUNDEDTABS )
       WinSendDlgItemMsg(hWnd, RB_BKS_ROUNDEDTABS, BM_SETCHECK,
			 MPFROMSHORT(TRUE), 0L);
   else
       WinSendDlgItemMsg(hWnd, RB_BKS_SQUARETABS, BM_SETCHECK,
			 MPFROMSHORT(TRUE), 0L);

		       /* Show the status type				*/

if ( flStyle & BKS_STATUSTEXTCENTER )
   WinSendDlgItemMsg(hWnd, RB_BKS_STATSCENTER, BM_SETCHECK,
		     MPFROMSHORT(TRUE),	0L);
else
   if (	flStyle	& BKS_STATUSTEXTRIGHT )
       WinSendDlgItemMsg(hWnd, RB_BKS_STATSRIGHT, BM_SETCHECK,
			 MPFROMSHORT(TRUE), 0L);
   else
       WinSendDlgItemMsg(hWnd, RB_BKS_STATSLEFT, BM_SETCHECK,
			 MPFROMSHORT(TRUE), 0L);

		       /* Show the tab type				*/

if ( flStyle & BKS_TABTEXTCENTER )
   WinSendDlgItemMsg(hWnd, RB_BKS_TABSCENTER, BM_SETCHECK,
		     MPFROMSHORT(TRUE),	0L);
else
   if (	flStyle	& BKS_TABTEXTRIGHT )
       WinSendDlgItemMsg(hWnd, RB_BKS_TABSRIGHT, BM_SETCHECK,
			 MPFROMSHORT(TRUE), 0L);
   else
       WinSendDlgItemMsg(hWnd, RB_BKS_TABSLEFT,	BM_SETCHECK,
			 MPFROMSHORT(TRUE), 0L);

		       /* Show the binding type				*/

if ( flStyle & BKS_SPIRALBIND )
   WinSendDlgItemMsg(hWnd, RB_BKS_SPIRALBIND, BM_SETCHECK,
		     MPFROMSHORT(TRUE),	0L);
else
   WinSendDlgItemMsg(hWnd, RB_BKS_SOLIDBIND, BM_SETCHECK,
		     MPFROMSHORT(TRUE),	0L);

EnableNoteBookCtrls(hWnd, flStyle);

}
#pragma	subtitle("   Super Notebook Control - Notebook Styles Update Function")
#pragma	page( )

/* --- UpdateNoteBookCtrls --------------------------------------------	*/
/*									*/
/*     This function is	used to	update the validity of the styles	*/
/*     for the note book control dialogue when an option is		*/
/*     selected	in the dialogue.					*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND hWnd;	  = Dialogue Window Handle			*/
/*     INT  iEnvironment; = Environment	Type Index			*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     Nothing								*/
/*									*/
/* --------------------------------------------------------------------	*/

VOID UpdateNoteBookCtrls(HWND hWnd, MPARAM mp1)

{
		       /* Process only button clicks on	the backpage	*/
		       /* orientation options				*/

if ( (SHORT2FROMMP(mp1)	== BN_CLICKED) &&
     ((SHORT1FROMMP(mp1) == RB_BKS_BACKPAGESBR)	||
      (SHORT1FROMMP(mp1) == RB_BKS_BACKPAGESTR)	||
      (SHORT1FROMMP(mp1) == RB_BKS_BACKPAGESBL)	||
      (SHORT1FROMMP(mp1) == RB_BKS_BACKPAGESTL)) )
   EnableNoteBookCtrls(hWnd, flGetNoteBookCtrls(hWnd));

}
#pragma	subtitle("   Super Notebook Control - Notebook Setup Function")
#pragma	page( )

/* --- flGetNoteBookCtrls ---------------------------------------------	*/
/*									*/
/*     This function is	used to	get the	controls for the notebook	*/
/*     dialogue	box.							*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND hWnd;	  = Dialogue Window Handle			*/
/*     INT  iEnvironment; = Environment	Type Index			*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     flGetNoteBookCtrls = Styles Selected				*/
/*									*/
/* --------------------------------------------------------------------	*/

ULONG flGetNoteBookCtrls(HWND hWnd)

{
ULONG flStyle =	0UL;		   /* Style Flags			*/


switch ( SHORT1FROMMR(WinSendDlgItemMsg(hWnd, RB_BKS_BACKPAGESBR,
					BM_QUERYCHECKINDEX,
					0L, 0L)) + RB_BKS_BACKPAGESBR )
   {
   case	RB_BKS_BACKPAGESBR :
       flStyle |= BKS_BACKPAGESBR;
       break;

   case	RB_BKS_BACKPAGESBL :
       flStyle |= BKS_BACKPAGESBL;
       break;

   case	RB_BKS_BACKPAGESTR :
       flStyle |= BKS_BACKPAGESTR;
       break;

   case	RB_BKS_BACKPAGESTL :
       flStyle |= BKS_BACKPAGESTL;
       break;
   }

if ( WinSendDlgItemMsg(hWnd, RB_BKS_MAJTABBOT, BM_QUERYCHECK, 0L, 0L) )
   flStyle |= BKS_MAJORTABBOTTOM;
else
   if (	WinSendDlgItemMsg(hWnd,	RB_BKS_MAJTABTOP, BM_QUERYCHECK, 0L, 0L) )
       flStyle |= BKS_MAJORTABTOP;
   else
       if ( WinSendDlgItemMsg(hWnd, RB_BKS_MAJTABLEFT, BM_QUERYCHECK, 0L, 0L) )
	   flStyle |= BKS_MAJORTABLEFT;
       else
	   flStyle |= BKS_MAJORTABRIGHT;

switch ( SHORT1FROMMR(WinSendDlgItemMsg(hWnd, RB_BKS_SQUARETABS,
					BM_QUERYCHECKINDEX,
					0L, 0L)) + RB_BKS_SQUARETABS )
   {
   case	RB_BKS_SQUARETABS :
       flStyle |= BKS_SQUARETABS;
       break;

   case	RB_BKS_ROUNDEDTABS :
       flStyle |= BKS_ROUNDEDTABS;
       break;

   case	RB_BKS_POLYGONTABS :
       flStyle |= BKS_POLYGONTABS;
       break;
   }

switch ( SHORT1FROMMR(WinSendDlgItemMsg(hWnd, RB_BKS_STATSLEFT,
					BM_QUERYCHECKINDEX,
					0L, 0L)) + RB_BKS_STATSLEFT )
   {
   case	RB_BKS_STATSLEFT :
       flStyle |= BKS_STATUSTEXTLEFT;
       break;

   case	RB_BKS_STATSRIGHT :
       flStyle |= BKS_STATUSTEXTRIGHT;
       break;

   case	RB_BKS_STATSCENTER :
       flStyle |= BKS_STATUSTEXTCENTER;
       break;
   }

switch ( SHORT1FROMMR(WinSendDlgItemMsg(hWnd, RB_BKS_TABSLEFT,
					BM_QUERYCHECKINDEX,
					0L, 0L)) + RB_BKS_TABSLEFT )
   {
   case	RB_BKS_TABSLEFT	:
       flStyle |= BKS_TABTEXTLEFT;
       break;

   case	RB_BKS_TABSRIGHT :
       flStyle |= BKS_TABTEXTRIGHT;
       break;

   case	RB_BKS_TABSCENTER :
       flStyle |= BKS_TABTEXTCENTER;
       break;
   }

if ( SHORT1FROMMR(WinSendDlgItemMsg(hWnd, RB_BKS_SOLIDBIND,
				    BM_QUERYCHECK, 0L, 0L)) )
   flStyle |= BKS_SOLIDBIND;
else
   flStyle |= BKS_SPIRALBIND;

return(flStyle);
}
#pragma	subtitle("   Super Notebook Control - Control Data Decoding Procedure")
#pragma	page ( )

/* --- InitNotebookPageData ---------------------------	[ Private ] ---	*/
/*									*/
/*     This function is	used to	decode the control data	for the		*/
/*     notebook	page and place it within the appropriate controls	*/
/*     within the styles dialogue.					*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND	      hWnd;  = Dialogue	Window Handle			*/
/*     PNOTEPAGECDATA pnpcd; = PM Message				*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     Nothing								*/
/*									*/
/* --------------------------------------------------------------------	*/

VOID InitNotebookPageData(HWND hWnd, PNOTEPAGECDATA pnpcd)

{
CHAR   szBuffer[256];		   /* Buffer				*/
INT    cLen;			   /* Text Length			*/
IPT    iptData;			   /* MLE Data Start Position		*/
PBYTE  pb;			   /* Byte Pointer			*/
PULONG pulIDs;			   /* ID's Array                        */
register INT i,	n;		   /* Loop Counters			*/

		       /* Check	to see if any pages have been		*/
		       /* requested in which case there	is probably	*/
		       /* data defined					*/
if ( pnpcd->cPages )
   {
		       /* Set the page count with the Pages entry field	*/

   WinSetDlgItemShort(hWnd, EF_PAGES, (USHORT)pnpcd->cPages, TRUE);

		       /* Set the text limit for the ID's MLE to be     */
		       /* 16KB and initialize the MLE before placing	*/
		       /* the dialogue ID's within it                   */

   WinSendDlgItemMsg(hWnd, MLE_DLGIDS, MLM_SETTEXTLIMIT,
		     MPFROMLONG(16384L), 0L);
   WinSendDlgItemMsg(hWnd, MLE_DLGIDS, MLM_DISABLEREFRESH, 0L, 0L);
   WinSendDlgItemMsg(hWnd, MLE_DLGIDS, MLM_RESETUNDO, 0L, 0L);
   WinSendDlgItemMsg(hWnd, MLE_DLGIDS, MLM_FORMAT,
		     MPFROMSHORT(MLFIE_NOTRANS), 0L);

		       /* Point	to the ID list				*/

   pulIDs = (PULONG)pnpcd->abList;

		       /* Walk the array and convert the ID to ASCII	*/
		       /* before placing the value on a	single line	*/
		       /* within the MLE				*/

   for ( i = 0,	iptData	= 0L; i	< pnpcd->cIDs; i++ )
       {
       WinSendDlgItemMsg(hWnd, MLE_DLGIDS, MLM_SETIMPORTEXPORT,
			 MPFROMP(szBuffer),
			 MPFROMLONG(cLen = (INT)strlen(strcat(_ltoa((LONG)pulIDs[i], szBuffer, 10),
							 "\n"))));
       WinSendDlgItemMsg(hWnd, MLE_DLGIDS, MLM_IMPORT, MPFROMP(&iptData),
			 MPFROMLONG(cLen));
       }
   WinSendDlgItemMsg(hWnd, MLE_DLGIDS, MLM_ENABLEREFRESH, 0L, 0L);

		       /* Check	to see if any status items defined	*/

   if (	pnpcd->cStatusItems )
       {
		       /* Set the text limit for the status text MLE to	*/
		       /* be 16KB and initialize the MLE before	placing	*/
		       /* the status text lines	within it		*/

       WinSendDlgItemMsg(hWnd, MLE_STATUSTEXT, MLM_SETTEXTLIMIT,
			 MPFROMLONG(16384L), 0L);
       WinSendDlgItemMsg(hWnd, MLE_STATUSTEXT, MLM_DISABLEREFRESH, 0L, 0L);
       WinSendDlgItemMsg(hWnd, MLE_STATUSTEXT, MLM_RESETUNDO, 0L, 0L);
       WinSendDlgItemMsg(hWnd, MLE_STATUSTEXT, MLM_FORMAT,
			 MPFROMSHORT(MLFIE_NOTRANS), 0L);

		       /* Point	to the status text list	block		*/

       pb = pnpcd->abList + pnpcd->cPages * sizeof(ULONG);

		       /* Walk the block and place each	status line	*/
		       /* on a single line within the MLE		*/

       for ( i = n = 0,	iptData	= 0L; i	< pnpcd->cStatusItems; i++ )
	   {
	   WinSendDlgItemMsg(hWnd, MLE_STATUSTEXT, MLM_SETIMPORTEXPORT,
			     MPFROMP(szBuffer),
			     MPFROMLONG(cLen = (INT)strlen(strcat(strcpy(szBuffer,
								    &pb[n]),
						      "\n"))));
	   WinSendDlgItemMsg(hWnd, MLE_STATUSTEXT, MLM_IMPORT, MPFROMP(&iptData),
			     MPFROMLONG(cLen));
	   n +=	(INT)strlen(&pb[n]) + 1;
	   }
       WinSendDlgItemMsg(hWnd, MLE_STATUSTEXT, MLM_ENABLEREFRESH, 0L, 0L);
       }

   if (	pnpcd->cTabItems )
       {
		       /* Set the text limit for the tab text MLE to	*/
		       /* be 16KB and initialize the MLE before	placing	*/
		       /* the tab text lines within it			*/

       WinSendDlgItemMsg(hWnd, MLE_TABTEXT, MLM_SETTEXTLIMIT,
			 MPFROMLONG(16384L), 0L);
       WinSendDlgItemMsg(hWnd, MLE_TABTEXT, MLM_DISABLEREFRESH,	0L, 0L);
       WinSendDlgItemMsg(hWnd, MLE_TABTEXT, MLM_RESETUNDO, 0L, 0L);
       WinSendDlgItemMsg(hWnd, MLE_TABTEXT, MLM_FORMAT,
			 MPFROMSHORT(MLFIE_NOTRANS), 0L);

		       /* Point	to the tab text	list block		*/

       pb = pnpcd->abList + pnpcd->cPages * sizeof(ULONG) + pnpcd->cStatus;

		       /* Walk the block and place each	tab text line	*/
		       /* on a single line within the MLE		*/

       for ( i = n = 0,	iptData	= 0L; i	< pnpcd->cTabItems; i++	)
	   {
	   WinSendDlgItemMsg(hWnd, MLE_TABTEXT,	MLM_SETIMPORTEXPORT,
			     MPFROMP(szBuffer),
			     MPFROMLONG(cLen = (INT)strlen(strcat(strcpy(szBuffer,
								    &pb[n]),
							 "\n"))));
	   WinSendDlgItemMsg(hWnd, MLE_TABTEXT,	MLM_IMPORT, MPFROMP(&iptData),
			     MPFROMLONG(cLen));
	   n +=	(INT)strlen(&pb[n]) + 1;
	   }
       WinSendDlgItemMsg(hWnd, MLE_TABTEXT, MLM_ENABLEREFRESH, 0L, 0L);
       }
   }
}
#pragma	subtitle("   Super Notebook Control - Control Data Save Procedure")
#pragma	page ( )

/* --- GetNotebookPageData ----------------------------	[ Private ] ---	*/
/*									*/
/*     This function is	used query the dialogue	controls containing	*/
/*     information for the notebook pages for their data and create	*/
/*     control data for	the control.					*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND	      hWnd;  = Dialogue	Window Handle			*/
/*     PNOTEPAGECDATA pnpcd; = Control Data Structure Pointer		*/
/*     PUSERSTYLE     pust;  = Control Styles Structure	Pointer		*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     Nothing								*/
/*									*/
/* --------------------------------------------------------------------	*/

VOID GetNotebookPageData(HWND hWnd, PNOTEPAGECDATA pnpcd, PUSERSTYLE   pust)

{
CHAR   szBuffer[256];		   /* Buffer				*/
INT    cItems;			   /* Items Count			*/
INT    cLen;			   /* Text Length			*/
INT    cTextLen;		   /* Text Length			*/
IPT    iptData;			   /* MLE Data Start Position		*/
LONG   cLines;			   /* Lines Count			*/
LONG   cStatus;			   /* Status Text Length		*/
LONG   cStatusItems;		   /* Status Item Count			*/
LONG   cTab;			   /* Status Text Length		*/
LONG   cTabItems;		   /* Tab Item Count			*/
LONG   cPages =	0L;		   /* Page Count			*/
PBYTE  pb;			   /* Byte Pointer			*/
PCHAR  pch;			   /* String Pointer			*/
PCHAR  pchStatus;		   /* Status Text Buffer		*/
PCHAR  pchTab;			   /* Tab Text Buffer			*/
PULONG pulIDs;			   /* ID's Array                        */
register INT i,	n;		   /* Loop Counters			*/

		       /* Get the number of pages that is to be		*/
		       /* created					*/

WinQueryDlgItemShort(hWnd, EF_PAGES, (PSHORT)(PVOID)&cPages, TRUE);

		       /* Get the number of lines within the dialogue	*/
		       /* ID's MLE                                      */

cLines = SHORT1FROMMR(WinSendDlgItemMsg(hWnd, MLE_DLGIDS,
		      MLM_QUERYLINECOUNT, 0L, 0L));

		       /* Allocate scratch memory for the dialogue ID	*/
		       /* array						*/

DosAllocMem((PPVOID)(PVOID)&pulIDs, (ULONG)(cPages < cLines ? cLines * sizeof(ULONG) : cPages *	sizeof(ULONG)),
	    PAG_READ | PAG_WRITE | PAG_COMMIT);

		       /* Get each line	from the MLE and convert the	*/
		       /* dialogue ID from ASCII to binary		*/

for ( i	= n = cItems = 0, iptData = 0L;	i < cLines; i++	)
   if (	(cLen =	(INT)(cTextLen = (LONG)WinSendDlgItemMsg(hWnd, MLE_DLGIDS,
							 MLM_QUERYLINELENGTH,
							 MPFROMLONG(iptData), 0L))) != 0 )
       {
		       /* Get the line from the	MLE			*/

       WinSendDlgItemMsg(hWnd, MLE_DLGIDS, MLM_SETIMPORTEXPORT,
			 MPFROMP(szBuffer), MPFROMLONG((IPT)cTextLen));
       WinSendDlgItemMsg(hWnd, MLE_DLGIDS, MLM_EXPORT,
			 MPFROMP(&iptData), MPFROMP(&cTextLen));

		       /* Terminate the	text at	the carriage return or	*/
		       /* line feed mark				*/

       szBuffer[cLen] =	0;
       if ( (pch = strchr(szBuffer, '\r')) != NULL )
	   *pch	= 0;
       else
	   if (	(pch = strchr(szBuffer,	'\n')) != NULL )
	       *pch = 0;

		       /* Convert the ASCII dialogue ID	to binary and	*/
		       /* save within the scratch ID array		*/

       if ( szBuffer[0]	)
	   pulIDs[cItems++] = (ULONG)atol(szBuffer);
       }
		       /* Get the number of lines within the status	*/
		       /* text MLE					*/

cLines = SHORT1FROMMR(WinSendDlgItemMsg(hWnd, MLE_STATUSTEXT,
		      MLM_QUERYLINECOUNT, 0L, 0L));

		       /* Allocate scratch memory for the status text	*/
		       /* block						*/

DosAllocMem((PPVOID)(PVOID)&pchStatus, 16384UL,
	    PAG_READ | PAG_WRITE | PAG_COMMIT);

		       /* Get each line	from the MLE and save the text	*/
		       /* within the status text block			*/

for ( i	= n = cStatusItems = 0,	iptData	= 0L; i	< cLines; i++ )
   if (	(cLen =	(INT)(cTextLen = (LONG)WinSendDlgItemMsg(hWnd, MLE_STATUSTEXT,
							 MLM_QUERYLINELENGTH,
							 MPFROMLONG(iptData), 0L))) != 0 )
       {
       WinSendDlgItemMsg(hWnd, MLE_STATUSTEXT, MLM_SETIMPORTEXPORT,
			 MPFROMP(szBuffer), MPFROMLONG((IPT)cTextLen));
       WinSendDlgItemMsg(hWnd, MLE_STATUSTEXT, MLM_EXPORT,
			 MPFROMP(&iptData), MPFROMP(&cTextLen));

		       /* Terminate the	text at	the carriage return or	*/
		       /* line feed mark				*/

       szBuffer[cLen] =	0;
       if ( (pch = strchr(szBuffer, '\r')) != NULL )
	   *pch	= 0;
       else
	   if (	(pch = strchr(szBuffer,	'\n')) != NULL )
	       *pch = 0;
		       /* Copy the text	into the status	text block	*/

       if ( szBuffer[0]	)
	   {
	   strcpy(&pchStatus[n], szBuffer);
	   n +=	(INT)strlen(szBuffer) +	1;
	   ++cStatusItems;
	   }
       }
		       /* Save the number of status items		*/
cStatus	= n;
		       /* Get the number of lines within the tab text	*/
		       /* MLE						*/

cLines = SHORT1FROMMR(WinSendDlgItemMsg(hWnd, MLE_TABTEXT,
		      MLM_QUERYLINECOUNT, 0L, 0L));

		       /* Allocate scratch memory for the tab text	*/

DosAllocMem((PPVOID)(PVOID)&pchTab, 16384UL,
	    PAG_READ | PAG_WRITE | PAG_COMMIT);

		       /* Get each line	from the MLE and save the text	*/
		       /* within the tab text block			*/

for ( i	= n = cTabItems	= 0, iptData = 0L; i < cLines; i++ )
   if (	(cLen =	(INT)(cTextLen = (LONG)WinSendDlgItemMsg(hWnd, MLE_TABTEXT,
							 MLM_QUERYLINELENGTH,
							 MPFROMLONG(iptData), 0L))) != 0 )
       {
       WinSendDlgItemMsg(hWnd, MLE_TABTEXT, MLM_SETIMPORTEXPORT,
			 MPFROMP(szBuffer), MPFROMLONG((IPT)cTextLen));
       WinSendDlgItemMsg(hWnd, MLE_TABTEXT, MLM_EXPORT,
			 MPFROMP(&iptData), MPFROMP(&cTextLen));

       szBuffer[cLen] =	0;
       if ( (pch = strchr(szBuffer, '\r')) != NULL )
	   *pch	= 0;
       else
	   if (	(pch = strchr(szBuffer,	'\n')) != NULL )
	       *pch = 0;
		       /* Copy the text	into the tab text block		*/

       if ( szBuffer[0]	)
	   {
	   strcpy(&pchTab[n], szBuffer);
	   n +=	(INT)strlen(szBuffer) +	1;
	   ++cTabItems;
	   }
       }
		       /* Save the number of tab items			*/
cTab = n;
		       /* Reallocate the memory	for the	control	data	*/
		       /* based	upon the needs of the data just		*/
		       /* retrieved from the MLE's                      */

if ( !(pust->pbCtlData = (PBYTE)pust->pfnRealloc(pust->pbCtlData,
						 cTab +	cStatus	+ cItems * sizeof(ULONG) +
						 sizeof(NOTEPAGECDATA) - 1L)) )
   {
   WinMessageBox(HWND_DESKTOP, hWnd,
		 "Memory error on reallocating control data!",
		 "Super Notebook Control", 0UL,	MB_OK |	MB_ICONEXCLAMATION);
   return;
   }
		       /* Save the number of bytes within the control	*/
		       /* data within the user styles info		*/

pust->cbCtlData	= (ULONG)(cTab + cStatus + cItems * sizeof(ULONG) +
			  sizeof(NOTEPAGECDATA)	- 1L);

		       /* Point	to the control data block		*/

pnpcd =	(PNOTEPAGECDATA)pust->pbCtlData;

		       /* Save the size	of the control data block	*/
		       /* within the block start as required by	OS/2 PM	*/

pnpcd->cb = (ULONG)(cTab + cStatus + cItems * sizeof(ULONG) +
		    sizeof(NOTEPAGECDATA) - 1L);

		       /* Save the number of items and item sizes	*/

pnpcd->cIDs	    = (ULONG)cItems;
pnpcd->cTabItems    = (ULONG)cTabItems;
pnpcd->cStatusItems = (ULONG)cStatusItems;
pnpcd->cTab	    = (ULONG)cTab;
pnpcd->cStatus	    = (ULONG)cStatus;
pnpcd->cPages	    = (ULONG)cPages;

		       /* Copy the dialogue ID's to the control data    */
		       /* block						*/

memcpy(pnpcd->abList, pulIDs, (UINT)(cPages * sizeof(ULONG)));

		       /* Point	to the area where the status text is to	*/
		       /* be placed which is immediately after the	*/
		       /* dialogue ID array and	copy the status	text	*/
		       /* block	to the control data block		*/

pb = pnpcd->abList + cItems * sizeof(ULONG);
memcpy(pb, pchStatus, (UINT)cStatus);

		       /* Point	to the area where the tab text is to be	*/
		       /* placed which is immediately after the	status	*/
		       /* text block and copy the tab text block to the	*/
		       /* control data block				*/

pb = pnpcd->abList + cItems * sizeof(ULONG) + cStatus;
memcpy(pb, pchTab, (UINT)cTab);

		       /* Release the scratch memory used for the	*/
		       /* dialogue ID's, status text and tab text       */
		       /* blocks					*/

DosFreeMem((PVOID)pulIDs);
DosFreeMem((PVOID)pchTab);
DosFreeMem((PVOID)pchStatus);
}
#pragma	subtitle("   Super Notebook Control - Control Styles Dialogue Procedure")
#pragma	page ( )

/* --- NotePageStyles ---------------------------------- [ Public ] ---	*/
/*									*/
/*     This function is	used for the custom control's styles dialogue   */
/*     box procedure.							*/
/*									*/
/*     When the	dialogue is invoked from Resource Editor, the		*/
/*     address of the user style information is	contained in message	*/
/*     parameter 2.  The dialogue is responsible for saving the		*/
/*     address.	 The best method to do this is to save the pointer	*/
/*     in the dialogue's reserved memory where it can be retrieved as   */
/*     needed.								*/
/*									*/
/*     Upon Entry:							*/
/*									*/
/*     HWND   hWnd; = Dialogue Window Handle				*/
/*     ULONG  msg;  = PM Message					*/
/*     MPARAM mp1;  = Message Parameter	1				*/
/*     MPARAM mp2;  = Message Parameter	2				*/
/*									*/
/*     Upon Exit:							*/
/*									*/
/*     NotePageStyles =	Message	Handling Result				*/
/*									*/
/* --------------------------------------------------------------------	*/

MRESULT	EXPENTRY NotePageStyles(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)

{
PUSERSTYLE   pust;		   /* User Style Pointer		*/
SWP	     swp;		   /* Screen Window Position Holder	*/

switch ( msg )
   {
		       /* Perform dialogue initialization		*/
   case	WM_INITDLG :
		       /* Save the pointer to user style information	*/
		       /* within the dialog's reserved memory           */

       WinSetWindowPtr(hWnd, QWL_USER, (PVOID)mp2);

		       /* Get the pointer to the user style information	*/

       if ( (pust = (PUSERSTYLE)mp2) !=	NULL )
	   {
		       /* Set the text,	ID symbol and value for	the	*/
		       /* control					*/

	   pust->pfnSetSymbolID(hWnd, IDBX_SYMBOLVALUE,	pust);

	   InitNotebookPageData(hWnd, (PNOTEPAGECDATA)pust->pbCtlData);

	   SetNoteBookCtrls(hWnd, pust->flStyle);

	   if (	pust->flStyle &	WS_VISIBLE )
	       WinSendDlgItemMsg(hWnd, CB_VISIBLE, BM_SETCHECK,
				 MPFROMSHORT(TRUE), 0L);

	   if (	pust->flStyle &	WS_GROUP )
	       WinSendDlgItemMsg(hWnd, CB_GROUP, BM_SETCHECK,
				 MPFROMSHORT(TRUE), 0L);

	   if (	pust->flStyle &	WS_DISABLED )
	       WinSendDlgItemMsg(hWnd, CB_DISABLED, BM_SETCHECK,
				 MPFROMSHORT(TRUE), 0L);

	   if (	pust->flStyle &	WS_TABSTOP )
	       WinSendDlgItemMsg(hWnd, CB_TABSTOP, BM_SETCHECK,
				 MPFROMSHORT(TRUE), 0L);
	   }
		       /* Centre dialog	on the screen			*/

       WinQueryWindowPos(hWnd, (PSWP)&swp);
       WinSetWindowPos(hWnd, HWND_TOP,
		       (WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN) - swp.cx) /	2L,
		       (WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - swp.cy) /	2L,
		       0L, 0L, SWP_MOVE);
       break;

   case	WM_CONTROL :
       UpdateNoteBookCtrls(hWnd, mp1);
       break;
		       /* Process push button selections		*/
   case	WM_COMMAND :
       switch (	SHORT1FROMMP(mp1) )
	   {
		       /* Presentation push button selected		*/

	   case	DID_FONTCLR :

		       /* Get the pointer to the user style information	*/

	       if ( (pust = PDATAFROMDLG(hWnd))	!= NULL	)

		       /* Get the address of the look up function from	*/
		       /* user style information structure and display	*/
		       /* the dialog.  The value selected within the	*/
		       /* dialog will be automatically placed within	*/
		       /* the required entry fields			*/

		   pust->pfnGetFontClr(hWnd);
	       break;
		       /* Enter	pushbutton selected get	the definitions	*/
		       /* for the control				*/
	   case	DID_OK :

		       /* Get the pointer to the user style information	*/

	       if ( (pust = PDATAFROMDLG(hWnd))	!= NULL	)
		   {
		       /* Get the address of the symbol	validation	*/
		       /* function from	the user style information	*/
		       /* structure.  The function will	validate the	*/
		       /* symbol and will check	for duplications of	*/
		       /* values.  A return value of TRUE from the	*/
		       /* validation function indicates	that the symbol	*/
		       /* and value are	acceptable.  Conversely, a	*/
		       /* FALSE	return value indicates that symbol or	*/
		       /* value	was not	acceptable.  In	this case,	*/
		       /* the dialog should not	be exited from and the	*/
		       /* values within	the entry fields should	not be	*/
		       /* saved.					*/

		   if (	!pust->pfnGetSymbolID(hWnd, IDBX_SYMBOLVALUE, pust) )
		       break;
		   else
		       {
		       pust->cText = 0;

		       GetNotebookPageData(hWnd, (PNOTEPAGECDATA)pust->pbCtlData, pust);

		       pust->flStyle = flGetNoteBookCtrls(hWnd);

		       if ( WinSendDlgItemMsg(hWnd, CB_VISIBLE,
					      BM_QUERYCHECK, 0L, 0L) )
			   pust->flStyle |= WS_VISIBLE;

		       if ( WinSendDlgItemMsg(hWnd, CB_GROUP,
					      BM_QUERYCHECK, 0L, 0L) )
			   pust->flStyle |= WS_GROUP;

		       if ( WinSendDlgItemMsg(hWnd, CB_DISABLED,
					      BM_QUERYCHECK, 0L, 0L) )
			   pust->flStyle |= WS_DISABLED;

		       if ( WinSendDlgItemMsg(hWnd, CB_TABSTOP,
					      BM_QUERYCHECK, 0L, 0L) )
			   pust->flStyle |= WS_TABSTOP;
		       }
		   }
		       /* Exit the dialogue indicating changes made	*/

	       WinDismissDlg(hWnd, TRUE);
	       break;
		       /* Cancel selected, exit	the dialogue without	*/
		       /* changing anything				*/

	   case	DID_CANCEL :
	       WinDismissDlg(hWnd, FALSE);
	       break;
	   }
       break;
		       /* Close	received, exit dialog			*/
   case	WM_CLOSE :
       WinDismissDlg(hWnd, FALSE);
       break;
		       /* Pass through unhandled messages		*/
   default :
       return(WinDefDlgProc(hWnd, msg, mp1, mp2));
   }
return(0L);

}
