home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
desqview
/
api_exam.arc
/
REQUEST.C
< prev
next >
Wrap
Text File
|
1988-04-28
|
8KB
|
314 lines
/****************************************************************
*
* Name: REQUEST
*
* Function: Provides a front-end for the SERVER program.
* Takes a string entered by the user and sends
* requests to the SERVER to either add the string
* to the database or find all records that contain
* the string.
*
* Shows how to: 1. find a named mailbox.
* 2. read a key-at-a-time from the keyboard.
* 3. use an asynchronous notify function to
* detect attempts to close the window.
*
****************************************************************/
#include <stdio.h>
#include "dvapi.h"
/* minimum API level required */
#define required 0x201
/* public name of file server mailbox */
char mbname[] = "Example File Server";
int lmbname = sizeof(mbname);
/* status values for messages to the server */
#define LOGON 1
#define LOGOFF 2
#define ADDREC 3
#define QUERY 4
/* status values for messages from the server */
#define LOGGED_ON 1
#define LOGGED_OFF 2
#define READY 3
#define FOUND 4
/* keyboard codes returned by key_getc() */
#define BACKSPACE 8
#define ENTER_KEY 13
#define F1_KEY 0x3B+256
#define F2_KEY 0x3C+256
/* object handles */
ulong win,kbd,mal,server,obj;
/* variables used to receive mail */
char *mptr;
int mlng,status;
/* user input buffer and character counter */
char inbuf[80],*inptr;
int nchars;
/* message displayed if the server is not present */
char need_server_msg[] = "Please load the SERVER program.\n";
/* message displayed once the server acknowledges logon */
char logged_on_msg[] = "\
File server is ready.\n\
To query: type a search string followed by ENTER.\n\
To add a record: type the record followed by F1.\n\
To auto-query: type F2.\n";
/* other variables */
int version,auto_query = 0;
int notify_function();
/**********************************************************************
* main - check for DESQview present and enable required extensions.
***********************************************************************/
main () {
/* initialize C interfaces and get API version number */
version = api_init();
/* if DESQview is not running or version is too low, display a message */
if (version < required) {
printf ("This program requires DESQview version %d.02%d or later.\n",
required/256,required%256);
}
/* tell DESQview what extensions to enable and start application */
else {
api_level (required);
program_body();
}
/* disable C interfaces and return from program */
api_exit();
}
/********************************************************************
/* program_body
/*
/* Locate the file server. Sit in a loop sending requests and
/* processing responses. Ask for notification when the user tries
/* to close the window and notify the server before actually closing.
/********************************************************************/
program_body () {
/* get handles of default objects */
win = win_me();
kbd = key_me();
mal = mal_me();
/* find the server's named mailbox. If it is not present, prompt the
/* user to load SERVER. Loop until found. */
server = mal_find (mbname,lmbname);
if (server == 0) win_swrite (win,need_server_msg);
while (server == 0) {
api_pause();
server = mal_find (mbname,lmbname);
}
/* ask for asynchronous notification on CLOSE requests */
win_async (win,notify_function);
win_notify (win,NTF_CLOSE);
/* ask server for logon, wait for reply, and display instructions */
mal_addto (server,NULL,0,LOGON);
status = mal_read (mal,&mptr,&mlng);
win_swrite (win,logged_on_msg);
/* send a request to the server. Display each message received from the
/* server until one is received with the READY status. Loop. */
while (1) {
send_request();
while (1) {
status = mal_read (mal,&mptr,&mlng);
if (status == READY) break;
win_write (win,mptr,mlng);
win_swrite (win,"\n");
}
}
}
/********************************************************************
/* send_request
/*
/* This function writes a prompt and processes user input. The easiest
/* way to take user input is to use an input field and let DESQview
/* handle entry editing. We do it manually here to show how keystroke
/* mode can be used in situations where fields are inappropriate (such
/* as when writing a text editor).
/********************************************************************/
send_request () {
int k,req,row,col;
/* write the prompt and display the cursor */
win_swrite (win,"\n? ");
win_hcur (win);
/* initialize the input buffer variables */
inptr = inbuf;
nchars = 0;
/* gather keys until "break" or until 80 characters have been typed */
while (nchars < 80) {
/* if in auto_query mode and there is no pending keyboard input,
/* fake a query for the string "time" */
if (auto_query) {
if (key_sizeof (kbd) == 0) {
win_swrite (win,"time");
strcpy (inbuf,"time\0");
req = QUERY;
break;
}
/* any key typed while in auto_query mode terminates the mode
/* and is dropped */
else {
auto_query = 0;
k = key_getc (kbd);
}
}
/* wait for next key */
k = key_getc(kbd);
/* if normal key - add to buffer, display, and update cursor */
if ((k>31) && (k<256)) {
*inptr++ = k;
nchars += 1;
win_putc (win,k,7);
win_hcur (win);
}
/* if ENTER - terminate input string and setup to send QUERY message */
else if (k == ENTER_KEY) {
*inptr = 0;
req = QUERY;
break;
}
/* if F2 - enter auto_query mode */
else if (k == F2_KEY) {
auto_query = 1;
}
/* if F1 - terminate input string and setup to send ADDREC message */
else if (k == F1_KEY) {
*inptr = 0;
req = ADDREC;
break;
}
/* if BACKSPACE - backup one char in input buffer and in the window */
else if (k == BACKSPACE) {
qry_cursor (win,&row,&col);
if (col > 2) {
nchars -= 1;
inptr -= 1;
win_cursor (win,row,col-1);
win_blanks (win,1);
win_cursor (win,row,col-1);
win_hcur (win);
}
}
}
/* send the resulting request to the server and write a carriage return
/* to the window */
mal_addto (server,inbuf,strlen(inbuf)+1,req);
win_swrite (win,"\n");
}
/********************************************************************
/* notify_function
/*
/* This function is called as a "software interrupt" whenever the
/* window manager sends a notify message. Since we have only requested
/* notification on CLOSE requests, we do not need to check the type
/* of notify. All we do is send a message to the server requesting
/* a logoff and wait for confirmation. Any mail received in the
/* meantime is ignored. When confirmation arrives, we free our task
/* window.
/********************************************************************/
notify_function () {
mal_addto (server,NULL,0,LOGOFF);
while (mal_read (mal,&mptr,&mlng) != LOGGED_OFF) {};
api_exit();
win_free (win);
}