⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 quiklist.c

📁 CD_高级PALM编程
💻 C
字号:
/********************************************************************* FILE:				QuikList.c** DESCRIPTION:	The QuikList project module. This version of QuikList (1) *					shows you how to implement a list with multi-character*					Graffiti lookup. The list data is stored in a string array.** VERSION:		1.0**********************************************************************/#include <PalmOS.h>#include <TxtGlue.h>#include "QuikList.h"#include "QuikListRsc.h"#include "Utils.h"#include "UtilsRsc.h"/*********************************************************************** * FUNCTION:    	StartGraffitiLookup * * DESCRIPTION: 	Initiate a record lookup using a user-entered keystroke, *							The lookup uses a two-part timing mechanism: one setting *							for the EvtGetEvent timeout value, and a secondary counter. * * RETURNED:    	Nothing.  * *SIDE EFFECT: 	sets three global variables: *							gFindStr (the lookup string), the EvtGetEvent timeout setting, *							and the lookup counter. ***********************************************************************/static void  StartGraffitiLookup(	Char	chr	// ( in )  The next char to put in the lookup string.){	Int32		gFindStrLen = StrLen ( gFindStr );		// Turn on lookup indicator so user knows a lookup is taking place	FrmShowObject ( 		FrmGetActiveForm (), FrmGetObjectIndex ( 		FrmGetActiveForm (), MainLookupIndicatorLabel ));	// Set up the lookup string	gFindStr [ gFindStrLen ]        = chr;	gFindStr [ gFindStrLen + 1 ] = NULL;		// Arm (rearm) the nilEvent timer and its counter. We need a value > 1 in// gNilEventCnt because nilEvents may appear for reasons other than// the timer. 	gEventTimeout	= LOOKUP_TIMER_CNT;	gNilEventCnt 		= NIL_EVENT_CNT;}/*********************************************************************** * FUNCTION:    	StopGrafftiLookup * * DESCRIPTION: 	Check to see if there's an active Graffiti lookup going on. *							If so, check for termination. This gets called every *							LOOKUP_TIMER_CNT ticks until gNilEventCnt is zero. * * RETURNED:    	Nothing.  ***********************************************************************/static void  StopGrafftiLookup(	void){	gNilEventCnt--;	if ( gNilEventCnt == 0 )	{// Hide the lookup indicator,  clear the lookup string, and // turn off nilEvent generation.		FrmHideObject ( FrmGetActiveForm (), 			FrmGetObjectIndex ( 			FrmGetActiveForm (), MainLookupIndicatorLabel ));		gFindStr [ 0 ] = NULL;		gEventTimeout = evtWaitForever;	}}/*********************************************************************** * FUNCTION:    	CompareNameAndFindString * * DESCRIPTION: 	The binary search callback function. Compare two strings *							for equality. The second string parameter is actually *							a pointer to a string, so we have to fetch it indirectly. * * RETURNED:    	0 if they match, non-zero otherwise. ***********************************************************************/static Int16  CompareNameAndFindString(	void const * gFindStr,		// ( in )  The string we're looking for	void const * name,		// ( in )  The item to check for a match	Int32	/* other */		// unused){	Char**	listNameP = ( Char ** ) name;	UInt16		gFindStrLen = ( UInt16 ) StrLen ( gFindStr );		return ( TxtCaselessCompare (		gFindStr, gFindStrLen, NULL, * listNameP, gFindStrLen, NULL ));}#pragma mark ----------------/*********************************************************************** * FUNCTION:    	MainFormDrawList ** DESCRIPTION:	Draw the main form list. In between each line,* 							check for a new incoming keystroke. If there is one, do* 							another Graffiti lookup.  * * RETURNED:    	nothing ***********************************************************************/static void MainFormDrawList(	void){#define	NUM_REDRAWS	1	UInt16			i, j;	Coord			x, y;	EventType 	event;// Erase the list's rectangle	WinEraseRectangle ( &gListBounds, 0 );	for ( i = 0; i < VIS_ITEMS; i++ )	{	// Check for keystroke in middle of list redraw.// If there is one, do a lookup to see if there is a new list location// match. If so, stop redrawing until the next redraw kicks in.// StopRedraw is set in ProcessKeystroke. 		if ( ! gStopDrawing )		{			if ( EvtSysEventAvail ( false ))			{				EvtGetEvent ( &event, 0 );				SysHandleEvent ( &event );				if ( event.eType == keyDownEvent )				{					Boolean handled = MainFormProcessKeystroke (						( UInt8 ) event.data.keyDown.chr, true );					if ( gStopDrawing ) return;			}	}// No event available, keep drawing the current list			x = ( Coord ) ( gListBounds.topLeft.x + 2 );			y = ( Coord ) ( gListBounds.topLeft.y + ( i * FONT_HEIGHT ));			// Draw more than once to slow things down for testing			for ( j = 0; j < NUM_REDRAWS; j++ )				WinDrawChars ( gNames [ gTopItem + i ], StrLen ( gNames [ gTopItem + i ]), x, y );		}	}}/*********************************************************************** * FUNCTION:    	FitToListBoundaries * * DESCRIPTION: 	Check an incoming list position to make sure it* 							it fits within the legal boundaries for the list. * * RETURNED:    	A valid list position ***********************************************************************/static Int16 FitToListBoundaries(	Int16		topItem		// ( in )  the list item to check){	Int16		result = topItem;		if ( result < 0 )		result = 0;	if ( result > LIST_SIZE - VIS_ITEMS )		result = LIST_SIZE - VIS_ITEMS;	return ( result );}/*********************************************************************** * FUNCTION:    	MainFormProcessKeystroke * * DESCRIPTION: 	Process a keystroke event for the Main form. That typically means *							to see if there is a record that starts with a specific string. * * RETURNED:    	A boolean set to True if the keystroke was handled. It also set *							the global gStopDrawing ***********************************************************************/static Boolean MainFormProcessKeystroke(	UInt8			chr,			// ( in )  keystroke to process	Boolean		drawing	// ( in )  Currently drawing a list?){	Boolean		handled	= false;// First, check for scroll up/down buttons		if ( chr == vchrPageUp )	{		if ( gTopItem != 0 )		{			gTopItem = FitToListBoundaries ( gTopItem - VIS_ITEMS + 1 );			MainFormDrawList ();		}		handled = true;	}	else	if ( chr == vchrPageDown )	{		if ( gTopItem != LIST_SIZE - VIS_ITEMS )		{			gTopItem = FitToListBoundaries ( gTopItem + VIS_ITEMS - 1 );			MainFormDrawList ();		}		handled = true;	}	else 		// If it's a valid char, start Graffiti lookup		if ( TxtGlueCharIsPrint ( chr ))	{		Int32 	recLoc 	= -1;		handled 				= true;// Only do the lookup if there's room in the lookup string				if ( StrLen ( gFindStr ) < MAX_MATCH_CHAR )		{			StartGraffitiLookup (( Char ) chr );		// Lookup started, check for a record that starts with the string					if ( SysBinarySearch ( gNames, LIST_SIZE, sizeof ( Char* ),				CompareNameAndFindString, gFindStr, 0, &recLoc, true ))			{		// Found a record, redraw the list so the matched record is the topmost// visible item. If this is a redraw for a multi-char match (if drawing == true),// this redraw takes place before the previous list drawing completes. 				gTopItem = FitToListBoundaries (( Int16 ) recLoc );				MainFormDrawList ();					// If a previous list is being drawn, stop it. If not, enable drawing// in case a multi-char match previously disabled drawing.				gStopDrawing = drawing;			}		}	}	return handled;}#pragma mark ----------------/*********************************************************************** * FUNCTION:    	MainFormInit * * DESCRIPTION: 	This routine initializes the main form. It should be used to *							execute code that must be done _before_ the form is *							drawn using FrmDrawForm. * * RETURNED:    	nothing ***********************************************************************/static void MainFormInit(	FormPtr	frmP		// ( in )  Pointer to the main form){	if ( frmP != NULL )	{		RctSetRectangle ( &gListBounds, TOP_LEFT_X, TOP_LEFT_Y, EXTENT_X, EXTENT_Y );	}}/*********************************************************************** * FUNCTION:    	MainFormDraw * * DESCRIPTION: 	This routine draws the non-form contents of the main form. * * RETURNED:    	nothing ***********************************************************************/static void MainFormDraw(	FormPtr	frmP		// ( in )  Pointer to the main form.){	if ( frmP != NULL )	{		WinDrawRectangleFrame ( simpleFrame, &gListBounds );		MainFormDrawList ();	}}/*********************************************************************** * FUNCTION:    	MainFormDone * * DESCRIPTION: 	This routine cleans up after the main form. * * RETURNED:    	nothing ***********************************************************************/static void MainFormDone(	FormPtr	frmP		// ( in )  Pointer to the main form){	if ( frmP != NULL )	{		FrmEraseForm ( frmP );		FrmDeleteForm ( frmP );	}}/*********************************************************************** * FUNCTION:    	MainFormDoMenuCommand * * DESCRIPTION: 	This routine handles menu commands. * * RETURNED:    	true if command event handled ***********************************************************************/static Boolean MainFormDoMenuCommand(	UInt16 	command	// ( in )  The ID of menu command to do){	Boolean	handled = false;	FormPtr	frmP;	switch ( command )	{		case MainOptionsAboutQuikList:					MenuEraseStatus ( 0 );			frmP = FrmInitForm ( AboutForm );			FrmDoDialog ( frmP );			FrmDeleteForm ( frmP );			handled = true;			break;	}	return handled;}/*********************************************************************** * FUNCTION:    	MainFormHandleEvent * * DESCRIPTION: 	This routine is the event handler for the main form. * * RETURNED:    	true if the event is handled. ***********************************************************************/static Boolean MainFormHandleEvent(	EventPtr eventP		// ( in )  Pointer to the event to handle){	Boolean 	handled	= false;	FormPtr	frmP		= FrmGetActiveForm ();	switch ( eventP->eType ) 	{// Form events			case frmOpenEvent:				MainFormInit ( frmP );	// ***** WARNING  - falls thru to next case *****					case frmUpdateEvent:			FrmDrawForm ( frmP );			MainFormDraw ( frmP );			handled = true;			break; 					case frmCloseEvent:			MainFormDone ( frmP );			handled = true;				break;			// Menu events		case menuEvent:			handled = MainFormDoMenuCommand ( eventP->data.menu.itemID );			break;			// Keystroke events					case keyDownEvent:			handled = MainFormProcessKeystroke (( UInt8 ) eventP->data.keyDown.chr, false );			break;	}	return handled;}#pragma mark ----------------/*********************************************************************** * FUNCTION:    	AppHandleEvent * * DESCRIPTION: 	Loads a form's resources and set its event handler. * * RETURNED:    	true if the event is handled. ***********************************************************************/static Boolean AppHandleEvent(	EventPtr eventP		// ( in )  Pointer to the event to handle){    Boolean 	handled = false;	if ( eventP->eType == frmLoadEvent )	{	// Form load event--initialize the form and make it the active form.		UInt16 	formId 	= eventP->data.frmLoad.formID;		FormPtr	frmP 		= FrmInitForm ( formId );		if ( frmP )		{			FrmSetActiveForm ( frmP );// Set the event handler for the form.			switch ( formId )			{				case MainForm:						FrmSetEventHandler ( frmP, MainFormHandleEvent );					handled = true;					break;					// Set other cases as needed			}		}	}	return handled;}/*********************************************************************** * FUNCTION:    	AppEventLoop * * DESCRIPTION: 	The main event loop for the application.   * * RETURNED:    	nothing ***********************************************************************/static void AppEventLoop(	void){	UInt16 		error;	EventType 	event;	do	{	// Get the next event		EvtGetEvent ( &event, gEventTimeout );// Check the starndard default handlers		if (! SysHandleEvent ( &event))			if (! MenuHandleEvent ( 0, &event, &error ))				if (! AppHandleEvent ( &event ))				// Nobody wanted the event. Check for a nil event to turn off Graffiti lookup timing					if ( event.eType == nilEvent &&						gNilEventCnt > 0  &&						FrmGetActiveFormID () == MainForm)					{						StopGrafftiLookup ( );					}// None of the above, take the default handler					FrmDispatchEvent ( &event );	} while ( event.eType != appStopEvent );}/*********************************************************************** * FUNCTION:     	AppStart * * DESCRIPTION:  	Do whatever is necessary to get started, like read the app preferences. * * RETURNED:     	Err value or 0 if nothing went wrong ***********************************************************************/static UInt32 AppStart	// ( out )  zero or an error code(	void){	return 0;				// Return an error code if necessary. }/*********************************************************************** * FUNCTION:    	AppStop * * DESCRIPTION: 	Do whatever you need to do, like save the preferences. * * RETURNED:    	nothing ***********************************************************************/static void AppStop(	void){	FrmCloseAllForms ();}#pragma mark ----------------/*********************************************************************** * FUNCTION:    PilotMain * * DESCRIPTION: The application main entry point. * * RETURNED:    0 if launch & execution are successful, non-zero otherwise. ***********************************************************************/ UInt32 PilotMain(	UInt16		cmd,					// ( in )  The launch code	MemPtr	/* cmdPBP*/,		// ( in )  Pointer to the launch code structure	UInt16		launchFlags		// ( in )  Extra launch info){	UInt32 error = 0;// Check the ROM version for compatibility.	error = RomVersionCompatible ( MIN_ROM_VERSION, launchFlags);	if ( error == 0 ){// ROM OK, check for the various launch codes as needed.			switch (cmd)		{			case sysAppLaunchCmdNormalLaunch:							error = AppStart ();				if ( error == 0 )				{					FrmGotoForm ( MainForm );					AppEventLoop ();					AppStop ();				}				break;		}	}	return error;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -