www.pudn.com > HIM.zip > WNDEMO1.C
/***************** Program Source Module ***********************/
#ifdef AUTOPDOC
MODULE: wndemo1.c
DESCRIPTION:
Demo and test program for the HIM Window Manager wninput() function.
Will create 2 windows. One for explaining what is going on, and the other to
input ALL contortions possible of the various input types the wninput function
can handle. This is a tester program as well as a demo.
#endif
/*
*
* Allsoft (tm)
* 100 Calle Playa Del Sol NE
* Albuquerque, NM 87109
*
*
* Use any or all of this code in your applications.
*
*/
/********** Filled by Polytron Version Control System **********
$Author: james borders $
$Date: 01 Dec 1988 12:07:46 $
$Revision: 1.0 $
$Log: D:/C/FMLIB/WN/VCS/WNDEMO1.C $
*
* Rev 1.0 01 Dec 1988 12:07:46 james borders
* Initial revision.
****************************************************************/
/*** Include Files ***/
#include "stdio.h"
#include "ctype.h"
#ifdef MSC
#include "malloc.h"
#endif
#ifdef TURBOC
#include "alloc.h"
#endif
#include "stdarg.h"
#include "string.h"
#include "lm.h"
#include "km.h"
#include "wn.h"
/*** Global Vars ***/
/*
We need to give the wninput function somewhere to read and write the data
so we'll point the fielddef_s dptr to one of these global variables.
In a normal application you would probably want to create a structure of
data items for each data entry screen (name, address, city, state...) and
set the dptr field in your fielddef_s structure to point to the appropriate
field in your application structure.
*/
char gchar;
char gcharstr[500];
int gint;
unsigned int guint;
long int glint;
unsigned long int gulint;
float gfloat;
double gdouble;
/*** Typedefs ***/
/*
This structure will be used by the wnprocessscr() function found in this
file. Create 1 array of this structure for each screen in your application
and you've got all of your data entry done!
If you need even more powerful data validation or display capabilities,
just use the HIM Forms Manager.
*/
struct fielddef_s { /* complete data prompt and input field spec */
char *desc; /* what to print in status window */
char *dptr; /* where does the data live */
char *prompt; /* what to ask */
int row,col; /* where to ask it */
int dtype; /* complete data type of input */
int len; /* mix some too small, default, and too big */
int precision; /* if float or double, make sure to mix. */
char *charset; /* do some unsigned inputs with dtype == WNINT */
int (*action)(); /* do our own action for some fields */
};
/*
NOTE: the *desc field above is only used by the wnprocessscr() function
to display the data type that is being input. Modify the
wnprocessscr() function to NOT display this info if you use it in
your programs.
*/
/*** Constants ***/
int inaction1();
int inaction2();
int swnum; /* screen window number */
int dwnum; /* description window number */
struct fielddef_s fdefs1[] = {
/*
All the Default inputs...
*/
{ "Default WNCHAR..", &gchar,
"Char : ", 1,2, WNCHAR, 0, 0, "", WNACTIONNULL
},
{ "Default WNCHARSTR, w/WNCRCHOP..", gcharstr,
"Charstr : ", 2,2, WNCHARSTR | WNCRCHOP, 0, 0, "", WNACTIONNULL
},
{ "Default WNINT, w/WNWIPE..", (char *)&gint,
"Integer : ", 3,2, WNINT | WNWIPE, 0, 0, "", WNACTIONNULL
},
{ "Default WNUINT..", (char *)&guint,
"Unsigned Integer : ", 4, 2, WNUINT, 0, 0, "", WNACTIONNULL
},
{ "Default WNLINT..", (char *)&glint,
"Long Integer : ", 5,2, WNLINT, 0, 0, "", WNACTIONNULL
},
{ "Default WNULINT..", (char *)&gulint,
"Unsigned Long Integer : ", 6, 2, WNULINT, 0, 0, "", WNACTIONNULL
},
{ "Default WNFLOAT.., 0 precision", (char *)&gfloat,
"Float : ", 7, 2, WNFLOAT, 0, 0, "", WNACTIONNULL
},
{ "Default WNDOUBLE.., 1 precision", (char *)&gdouble,
"Double : ", 8, 2, WNDOUBLE, 0, 1, "", WNACTIONNULL
}
};
struct fielddef_s fdefs2[] = {
/*
Now do it again with short and extra input field lengths, charsets
and our own action routine.
*/
{ "WNCHAR with input = 5..", &gchar,
"Char : ", 1,2, WNCHAR, 5, 0, "", WNACTIONNULL
},
{ "WNCHARSTR with input = 10, charset == ABC xyz..", gcharstr,
"Charstr : ", 2,2, WNCHARSTR, 10, 0, "ABC xyz", inaction1
},
{ "WNINT with input == 15..", (char *)&gint,
"Integer : ", 3,2, WNINT, 15, 0, "", WNACTIONNULL
},
{ "WNUINT with input == 3..", (char *)&guint,
"Unsigned Integer : ", 4, 2, WNUINT, 3, 0, NULL, inaction1
},
{ "WNLINT with input == 27, digits 0123789..", (char *)&glint,
"Long Integer : ", 5,2, WNLINT, 27, 0, "0123789", inaction1
},
{ "WNULINT with input == default, digits 01..", (char *)&gulint,
"Unsigned Long Integer : ", 6, 2, WNULINT, 0, 0, "01", WNACTIONNULL
},
{ "WNFLOAT with input == 6, precision == 2.., no minus sign", (char *)&gfloat,
"Float : ", 7, 2, WNFLOAT, 6, 2, "0123456789+.eE ", WNACTIONNULL
},
{ "WNDOUBLE with input == default, precision == 5, no plus/minus..", (char *)&gdouble,
"Double : ", 8, 2, WNDOUBLE, 0, 5, "0123456789. e E", WNACTIONNULL
}
};
struct fielddef_s fdefs3[] = {
/*
Use prefilled default data...
The global data holders will have to be filled in before fdefs3
is processed.
*/
{ "WNCHAR with default == Y, charset == 'ynYN'", &gchar,
"Char : ", 1,2, WNCHAR | WNDPTRDISPLAY, 0, 0, "ynYN", inaction2
},
{ "WNCHARSTR with input = 11, default == hello world, wipe active", gcharstr,
"Charstr : ", 2,2, WNCHARSTR | WNDPTRDISPLAY | WNWIPE, 11, 0, "", inaction2
},
{ "WNINT with default == -12345", (char *)&gint,
"Integer : ", 3,2, WNINT | WNDPTRDISPLAY, 0, 0, "", inaction2
},
{ "WNUINT with default == 65432", (char *)&guint,
"Unsigned Integer : ", 4, 2, WNUINT | WNDPTRDISPLAY, 0, 0, NULL, inaction2
},
{ "WNLINT with default == 9873210, charset == 0123789", (char *)&glint,
"Long Integer : ", 5,2, WNLINT | WNDPTRDISPLAY, 0, 0, "0123789", inaction2
},
{ "WNULINT with default == 4294967295", (char *)&gulint,
"Unsigned Long Integer : ", 6, 2, WNULINT | WNDPTRDISPLAY, 0, 0, NULL, inaction2
},
{ "WNFLOAT with default == -123456.12 , precision == 2", (char *)&gfloat,
"Float : ", 7, 2, WNFLOAT | WNDPTRDISPLAY, 0, 2, NULL, inaction2
},
{ "WNDOUBLE with default == -9999999999.98765, len == 20, precision == 5", (char *)&gdouble,
"Double : ", 8, 2, WNDOUBLE | WNDPTRDISPLAY, 20, 5, "", inaction2
}
};
#define numdefs(a) ( sizeof(a) / sizeof(struct fielddef_s) )
/*** Macros ***/
main()
/****/
{
int kbhit(), getch();
lminit((char *(*)())malloc,free,0); /* init list manager with debug off */
wninit(0,0,NULL,0,(char *(*)())malloc,free); /* window manager saves to memory */
kminit(kbhit,getch); /* keyboard manager */
wninputtest();
};
wninputtest()
/***********/
/*
assumes that the list, keyboard, and window manager have been initialized.
*/
{
if ((swnum = wncreate(0,0,80,13,WNBLUE,WNCYAN,WNBLUE,WNCYAN)) < 0){
printf("\nCan't create window..");
return(-1);
}
wnswscroll(swnum,0); /* so last line printing won't scroll window */
if ((dwnum = wncreate(13,0,80,12,WNBLACK,WNCYAN,WNBLACK,WNCYAN)) < 0){
printf("\nCan't create window..");
return(-1);
}
wnttitle(dwnum,"[ WNINDEMO V1.0 ]");
explaintest(); /* explain this program */
wnprintf(dwnum,"\nTesting input fields with default len, precision, charset, & action");
wnprocessscr(swnum,fdefs1,numdefs(fdefs1));
checkkey("Hit a key for next screen, ESC to quit...");
wncls(dwnum);
wnprintf(dwnum,"\nTesting input fields with different display lengths and options..");
wnprocessscr(swnum,fdefs2,numdefs(fdefs2));
checkkey("Hit a key for next screen, ESC to quit...");
wncls(dwnum);
wnprintf(dwnum,"\nTesting input fields with different display lengths, options, ");
wnprintf(dwnum,"\nand default data.");
wnprintf(dwnum,"\n\nThe action routine supplied for these fields will interpret");
wnprintf(dwnum,"\nUp/Down arrows as \"bad characters\" and cause processing to move");
wnprintf(dwnum,"\nbetween fields..");
fillglobalsdef3();
wnprocessscr(swnum,fdefs3,numdefs(fdefs3));
checkkey("Hit a key to end demo/test of wninput()...");
wndestroy(swnum);
wndestroy(dwnum);
return(0);
};
explaintest()
/************/
{
wnprintf(dwnum,"\nThe HIM Window Manager wninput() function is a powerful, easy to use routine");
wnprintf(dwnum,"\nfor obtaining data from a user of your application. The code contained in");
wnprintf(dwnum,"\nthis demo is sufficient to allow your application to input almost any type");
wnprintf(dwnum,"\nof data. Feel free to modify any part of it for your own use.");
checkkey("Press a key to see wninput synopsis, ESC to quit..");
wncls(dwnum);
wnprintf(dwnum,"\nint wninput(wnum,dtype,dptr,len,precision,charset,badinaction);\n");
wnprintf(dwnum,"\nint wnum; window number to input from");
wnprintf(dwnum,"\nint dtype; data type to input");
wnprintf(dwnum,"\nchar *dptr; pointer to data");
wnprintf(dwnum,"\nint len; size of data if char, else input buffer size");
wnprintf(dwnum,"\nint precision; decimal precision if float or double");
wnprintf(dwnum,"\nchar *charset; allowable characters, NULL for default");
wnprintf(dwnum,"\nint (*badinaction)(); routine to call if bad input attempted");
checkkey("Press a key to continue, ESC to quit..");
wncls(dwnum);
wnprintf(dwnum,"\nAll of the C data types can be input as well as precision if getting");
wnprintf(dwnum,"\nfloating point data. The len parameter gives you control over the size");
wnprintf(dwnum,"\nof the input area. The charset string you supply determines what");
wnprintf(dwnum,"\ncharacters are valid for input.");
wnprintf(dwnum,"\n\nBefore we test the wninput() function remember, if you can't do");
wnprintf(dwnum,"\nthe EXACT validation you would like using the code in this demo,");
wnprintf(dwnum,"\ncheck out the HIM Forms Manager. It WILL handle any data entry");
wnprintf(dwnum,"\njob you have in mind.");
checkkey("Press a key to continue, ESC to quit..");
wncls(dwnum);
wnprintf(dwnum,"\nSome of the inputs have action routines which will");
wnprintf(dwnum,"\ntell you the current type, code, and current buffer.");
wnprintf(dwnum,"\n\nYou must press ESC when done reading the action routine");
wnprintf(dwnum,"\ntext.");
checkkey("Press a key to continue, ESC to quit..");
wncls(dwnum);
return(0);
};
checkkey(msg)
/***********/
char *msg;
{
char buf[80];
sprintf(buf,"[ %s ]",msg);
wnbtitle(dwnum,buf);
if (kmgetch() == KESC){
wndestroy(swnum);
wndestroy(dwnum);
exit(0);
};
wnbtitle(dwnum,"");
return(0);
};
wnprocessscr(wnum,fdefs,ndefs)
/******************************/
int wnum, ndefs;
struct fielddef_s *fdefs;
{
int i, code;
wncls(wnum);
for (i = 0; i < ndefs; i++){ /* display the prompts */
switch(fdefs[i].dtype & WNDTYPEMASK){
case WNCHAR: case WNCHARSTR: case WNINT: case WNUINT:
case WNLINT: case WNULINT: case WNFLOAT: case WNDOUBLE:
break;
default:
wnprintf(wnum,"\nIllegal dtype in fielddef structure. Press a key...");
kmgetch();
return(0);
}
wnlputs(wnum, fdefs[i].row, fdefs[i].col, fdefs[i].prompt);
code = wninput(wnum, fdefs[i].dtype | WNDISPLAYONLY, fdefs[i].dptr,
fdefs[i].len, fdefs[i].precision, fdefs[i].charset,
fdefs[i].action);
}
i = 0;
while (i < ndefs){
/*
Take out this wnprintf() line for your application...
*/
wnprintf(dwnum,"\n%s",fdefs[i].desc);
wnlputs(wnum,fdefs[i].row,fdefs[i].col,fdefs[i].prompt); /* to place cursor */
code = wninput(wnum, fdefs[i].dtype, fdefs[i].dptr, fdefs[i].len,
fdefs[i].precision, fdefs[i].charset, fdefs[i].action);
/*
take out this switch if using wnprocessscr() in your code
*/
switch(fdefs[i].dtype & WNDTYPEMASK){
case WNCHAR: wnprintf(dwnum,"\nRcode is [%d], Data is [%c]",code,*fdefs[i].dptr); break;
case WNCHARSTR: wnprintf(dwnum,"\nRcode is [%d], Data is [%s]",code,fdefs[i].dptr); break;
case WNINT: wnprintf(dwnum,"\nRcode is [%d], Data is [%d]",code,*(int *)fdefs[i].dptr); break;
case WNUINT: wnprintf(dwnum,"\nRcode is [%d], Data is [%u]",code,*(unsigned int *)fdefs[i].dptr); break;
case WNLINT: wnprintf(dwnum,"\nRcode is [%d], Data is [%ld]",code,*(long int *)fdefs[i].dptr); break;
case WNULINT: wnprintf(dwnum,"\nRcode is [%d], Data is [%lu]",code,*(unsigned long int *)fdefs[i].dptr); break;
case WNFLOAT: wnprintf(dwnum,"\nRcode is [%d], Data is [%f]",code,*(float *)fdefs[i].dptr); break;
case WNDOUBLE: wnprintf(dwnum,"\nRcode is [%d], Data is [%lf]",code,*(double *)fdefs[i].dptr); break;
}
/*
now check the return code to see what should be done next..
*/
switch(code){
case WNOK:
case WNCR: /* user entered CR with data */
i++;
if (i == ndefs)
return(0);
break;
case KUP: /* up arrow */
i = (i > 0)?i-1:i;
break;
case KDOWN: /* down arrow */
i = (i < (ndefs -1))?i+1:i;
break;
case KESC: /* returned by action routine on ESC */
case WNESC: /* returned by default action on ESC */
return(0);
}
};
return(0);
};
fillglobalsdef3()
/***************/
/*
This routine is called before the processing of field screen 3 in order
to demonstrate that the fields can be filled with data prior to display
and input.
*/
{
gchar = 'Y';
strcpy(gcharstr,"hello world");
gint = -12345;
guint = 65432;
glint = 9873210L;
gulint = 1431655765L * 3L; /* msc problem, constant too big. */
gfloat = -123456.12;
gdouble = -9999999999.98765;
return(0);
};
inaction1(wnum,dtype,code,key,curbuf)
/*******************************/
/*
One of the action routines that will get called when bad input is seen
by the wninput function.
*/
int wnum, dtype, code, key;
char *curbuf;
{
char buf[80];
char *chartype;
char *codetype;
switch(dtype & WNDTYPEMASK){
case WNCHAR: chartype = "WNCHAR "; break;
case WNCHARSTR: chartype = "WNCHARSTR "; break;
case WNINT: chartype = "WNINT "; break;
case WNUINT: chartype = "WNUINT "; break;
case WNLINT: chartype = "WNLINT "; break;
case WNULINT: chartype = "WNULINT "; break;
case WNFLOAT: chartype = "WNFLOAT "; break;
case WNDOUBLE: chartype = "WNDOUBLE "; break;
}
switch(code){
case WNCR: codetype = "WNCR "; break;
case WNESC: codetype = "WNESC "; break;
case WNBADCHAR: codetype = "WNBADCHAR "; break;
}
/*
Display the parameters to the user and wait for a key. ESC will cause
editing to resume, anything else will abort the field.
*/
sprintf(buf,"[ %s %s %s ]",chartype,codetype,curbuf);
wnbtitle(wnum,buf);
code = kmgetch();
wnbtitle(wnum,"");
if (code == KESC)
return(-1);
else
return(code);
};
inaction2(wnum,dtype,code,key,curbuf)
/*******************************/
/*
This action routine is used by the 3rd field screen group. Since we want
the wnprocessscr() routine to be able to see the KUP and KDOWN keys we
need to supply this action routine. Otherwise the default action would
be to beep at the user and continue editing.
*/
int wnum, dtype, code, key;
char *curbuf;
{
switch(code){
case WNCR:
wnprintf(wnum,"\007");
return(-1);
case WNESC:
return(KESC);
case WNBADCHAR:
if ((key == KUP) || (key == KDOWN) || (key == KESC))
return(key);
else{
wnprintf(wnum,"\007");
return(-1);
}
}
return(-1);
};