/*========================================================================== * FILE: XFORM.C *========================================================================== * DATE: October 1, 1990 * DESCRIPTION: Form Skeleton CPX * COMPILER: TURBO C Version 2.0 */ /* INCLUDE FILES *========================================================================== */ #include "sample.h" #pragma warn -apt /* 1 Non-portable pointer assignment */ #pragma warn -rpt /* 1 Non-portable pointer conversion */ #include "sample.rsh" #pragma warn .apt #pragma warn .rpt #include "..\cpxdata.h" /* Our CPX Data Structures */ /* PROTOTYPES *========================================================================== */ CPXINFO *cdecl cpx_init( XCPB *Xcpb ); BOOLEAN cdecl cpx_call( GRECT *rect ); /* DEFINES *========================================================================== */ /* EXTERNALS *========================================================================== */ extern int save_vars; /* Save_vars is where our default data * is stored. */ /* GLOBALS *========================================================================== */ XCPB *xcpb; /* XControl Parameter Block */ CPXINFO cpxinfo; /* CPX Information Structure */ /* FUNCTIONS *========================================================================== */ /* cpx_init() *========================================================================== * cpx_init() is where a CPX is first initialized. * There are TWO parts. * * PART ONE: cpx_init() is called when the CPX is first 'booted'. This is * where the CPX should read in its defaults and then set the * hardware based on those defaults. * * PART TWO: The other time cpx_init() is called is when the CPX is being * executed. This is where the resource is fixed up and current * cpx variables are updated from the hardware. In addition, * this is where the CPXINFO structure should be filled out. * * IN: XCPB *Xcpb: Pointer to the XControl Parameter Block * OUT: CPXINFO *ptr: Pointer to the CP Information Structure */ CPXINFO *cdecl cpx_init( XCPB *Xcpb ) { xcpb = Xcpb; if( xcpb->booting ) { /* Only those CPXs with their 'Booting' flag or 'Set-only' flag * set will be initialized here. * * Read in your defaults from 'save_vars' and slam them into * the hardware where appropriate. * * Return TRUE to tell XCONTROL that the header should be retained * so that the cpx may be executed. * * Return FALSE to tell XCONTROL NOT to retain our header. * An example of this would be a 'Set-Only' CPX. */ return( ( CPXINFO *)TRUE ); } else { /* Fixup the resource... * The flag prevents rsh_fix() from being called more than once. * If executing from disk, rsh_fix() is called every time. However, * If the CPX is 'resident', rsh_fix() will be called only once. */ if( !xcpb->SkipRshFix ) (*xcpb->rsh_fix)( NUM_OBS, NUM_FRSTR, NUM_FRIMG, NUM_TREE, rs_object, rs_tedinfo, rs_strings, rs_iconblk, rs_bitblk, rs_frstr, rs_frimg, rs_trindex, rs_imdope ); /* Get current hardware attributes here and store them away */ /* Initialize the CPXINFO structure */ cpxinfo.cpx_call = cpx_call; cpxinfo.cpx_draw = NULL; cpxinfo.cpx_wmove = NULL; cpxinfo.cpx_timer = NULL; cpxinfo.cpx_key = NULL; cpxinfo.cpx_button = NULL; cpxinfo.cpx_m1 = NULL; cpxinfo.cpx_m2 = NULL; cpxinfo.cpx_hook = NULL; cpxinfo.cpx_close = NULL; /* Return the pointer to the CPXINFO structure to XCONTROL */ return( &cpxinfo ); } } /* cpx_call() *========================================================================== * Called ONLY when the CPX is being executed. Note that it is CPX_INIT() * that returned the ptr to cpx_call(). * CPX_CALL() is the entry point to displaying and manipulating the * dialog box. * * IN: GRECT *rect: Ptr to a GRECT that describes the current work * area of the XControl window. * * OUT: * FALSE: The CPX has exited and no more messages are * needed. XControl will either return to its * main menu or close its windows. * This is used by XForm_do() type CPXs. * * TRUE: The CPX requests that XCONTROL continue to * send AES messages. This is used by Call-type CPXs. */ BOOLEAN cdecl cpx_call( GRECT *rect ) { OBJECT *tree = (OBJECT *)rs_trindex[ SAMPLE ]; int button; int quit = 0; WORD msg[8]; ObX( ROOT ) = rect->g_x; ObY( ROOT ) = rect->g_y; Objc_draw( tree, ROOT, MAX_DEPTH, NULL ); do { button = (*xcpb->Xform_do)( tree, 0, msg ); switch( button ) { /* Resource objects should be checked for here... * * ie... * * case OK: * break; * * case CANCEL: * break; * etc... * */ /* Xform_do() normally returns the object selected. * In certain cases, it may return a '-1' instead. * This means that the CPX should check for either * WM_REDRAW: window redraw messages * AC_CLOSE: Close Desk Accessory messages * and * WM_CLOSED: Close Window Messages * * WM_REDRAW: Xform_do() will handle object redraws. Non-object * graphics must be redrawn by yourself. To properly * redraw the CPX, you must walk down the rectangle * list. XControl supplies two routines for you to * do this. They are: * GetFirstRec() and GetNextRec() * * AC_CLOSE: When the CPX receives the Close Desk Accessory * message, the CPX should free up any malloc'ed * memory and then exit the CPX. * * WM_CLOSED: When a Close Window message is received, * free up any malloc'ed memory and exit the CPX. * * CT_KEY: A key was pressed. msg[3] contains the keycode * of the key pressed as returned from an 'evnt_keybd()'. * Note that we return non-printable keys only, such as * F1-F10, HELP and UNDO. However the 'Arrow' keys are * not supported because they are handled by Xform_do() * for editable text fields. */ default: if( button == -1 ) { switch( msg[0] ) { case WM_REDRAW: break; case AC_CLOSE: break; case WM_CLOSED: break; case CT_KEY: break; default: break; } } break; } }while( !quit); return( FALSE ); }