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

📄 floatfld.c

📁 CD_高级PALM编程
💻 C
📖 第 1 页 / 共 2 页
字号:
/********************************************************************* FILE:					FloatFld.c** DESCRIPTION:	Floating Point fields project.** VERSION:			1.0**********************************************************************/#include <PalmOS.h>#include <PalmCompatibility.h>#include "FloatFld.h"#include "FloatFldRsc.h"#include "Utils.h"#include "UtilsRsc.h"/************************************ * FUNCTION:    	SetPopup * * DESCRIPTION: 	Set a popup list's value. * * RETURNED:    	Nothing ************************************/ static void  SetPopup(	UInt16 		popID, 	// ( in ) the popup trigger ID	UInt16 		listID, 		// ( in ) the popup list ID	Int16 			val			// ( in ) the value to set the list too){	ControlPtr 	triggerP;	ListPtr			listP;	Char * 		labelP;		FormPtr		frmP = FrmGetActiveForm ();	if ( frmP )	{	// Get the trigger and list pointers		triggerP	= GetObjectPtr 	( popID );		listP			= GetObjectPtr 	( listID );		if ( triggerP && listP )		{		// Get the current list text and set the trigger label 			LstSetSelection ( listP, val );			labelP = LstGetSelectionText  ( listP, val );			CtlSetLabel ( triggerP, labelP );		}	}}/************************************ * FUNCTION:    	HandlePopup * * DESCRIPTION: 	Handle a popup list control select event *                              by getting the user's new selection and *                              setting the list to it. This routine requires that *                              the popup List ID value is one greater than *                              the popup trigger ID. * * RETURNED:    	nothing ************************************/static void	HandlePopup(	UInt16		popID		// ( in ) the popup trigger ID){	Int16		oldval;	Int16		newval;		ListPtr		lstP = GetObjectPtr ( popID + 1 );	if ( lstP != NULL )	{		oldval 	= LstGetSelection ( lstP );		newval 	= LstPopupList ( lstP );		if ( newval != noListSelection && oldval != newval )		{			SetPopup ( popID, popID + 1, newval );		}	}}/************************************ * FUNCTION:    	MoveToNextField * * DESCRIPTION: 	Change the focus to the next or previous field. * * RETURNED:    	nothing ************************************/static	void 	MoveToNextField(	FormPtr				frmP,	// ( in ) active form pointer	UInt8					key		// ( in) next/prev field character){   	FieldPtr				fldP;   	FieldAttrType  	attr;		Int8						direction = key == nextFieldChr? ( Int8 ) 1: ( Int8 ) -1;// Get the current focus	UInt16		focusIdx = FrmGetFocus ( frmP );	Int16		newFocusIdx = ( Int16 ) focusIdx;		// If there is a focus, loop thru the form objects for another editable field	if ( focusIdx != noFocus )	{		Int16		numObjs = ( Int16 ) FrmGetNumberOfObjects ( frmP );		UInt8		i;		for ( i = 0; i < numObjs; i ++ )		{			// Point to the next/prev field			newFocusIdx = newFocusIdx + direction;			if ( newFocusIdx < 0 ) 				newFocusIdx = numObjs - 1;			if ( newFocusIdx >= numObjs )				newFocusIdx = 0;					// Check the current field to see if it's editable and visible			fldP = FrmGetObjectPtr ( frmP, ( UInt16 ) newFocusIdx );			FldGetAttributes ( fldP, &attr );			if ( attr.editable && attr.visible )			{// Yes it is, set the focus				FrmSetFocus ( frmP, ( UInt16 ) newFocusIdx );				break;			} 		}		}}#pragma mark ----------------/************************************ * FUNCTION:    	StringToDouble * * DESCRIPTION: 	Extract a double-size floating point number from a string. *                              The string may have a leading negative sign and a *                              decimal point. Non-numeric characters are ignored. * * RETURNED:    	The converted result ************************************/static double		StringToDouble	// ( out ) the converted result(	Char * 		strP		// ( in ) the string to convert){	double		result;	double		divisor = 1.0;	UInt8 			srcP = 0;	// Strip off and convert everything to the left of the decimal point		while ( strP [ srcP ] != '\0' && strP [ srcP ] != gDSep )	{		if ( TxtCharIsDigit ( strP [ srcP ] ))		{			result = result * 10.0 + ( strP [ srcP ] - '0' );		}		srcP++;	}// Strip off and convert everything to the right of the decimal	while ( strP [ srcP ] != '\0' )	{		if ( TxtCharIsDigit ( strP [ srcP ] ))		{			divisor = divisor / 10.0;			result = result + (( strP [ srcP ]  - '0' ) * divisor );		}		srcP++;	}// Adjust for negative result if necessary	if ( strP [ 0 ] == '-' )	{		result = - result;	}	return  result;}/************************************ * FUNCTION:    	DoubleToString * * DESCRIPTION: 	Convert a double floating point # to a localized string.  *							The string may have a leading negative sign *							and one decimal point. The result is undefined if *							either the lefthand or righthand side of the incoming *							value has more than MAX_LHS_DIGITS digits or *                              MAX_RHS_DIGITS. If the resulting string is greater *                              than maxLen, it's filled wih an overflow character (">") *                              and truncated to maxLen. The right-hand side is *                              zero filled up to precision digits. The caller is responsible for *                              making sure the destination char array is large enough. *                               Maxiumum useful precision is about 16 digits. * * RETURNED:    	Result put in parameter dstP. **************************************************/static void DoubleToString(	double 		val, 				// ( in ) double to convert	Char *			dstP,			// ( out ) place to put the result	Boolean		localize,		// ( in ) localize with decimal separator?	UInt8 			precision, 	// ( in ) max # of digits on RHS	UInt8  			maxLen		// ( in ) max # chars that can appear in result){	Char			str [ MAX_LHS_DIGITS + 7 ];	// for LHS + punctuation	UInt8			strIdx = sizeof ( str )  - 1;		// index into str	UInt8			digitCnt = 0;							// digit counter	UInt8			len;											// string/substring length			double 		LHSd;		// the left-hand side value	double		RHSd;		// the right-hand side value	double		digitd;		// the current digit ( double )	long long	digitll;		// the current digit ( long long )	Char			digit;		// the current digit ( char )	Char *			altDstP = dstP;	// Negative. Mark final as negative & switch to absolute value// to make computations easier.	if ( val < 0.0 ) {		*dstP++ = '-';		// start final string with "-"		val = - val;			// work with abs value	}	// Split out the left and right-hand sides of the number	LHSd 	= ( double ) ( long long ) val;	RHSd 	= val - LHSd;	str [ strIdx-- ] = '\0';// Strip off everything to the left of the decimal first,// inserting decimal separator characters as needed.// Store from the rightmost char to the leftmost in temp char array.// The result of grabbing digitll using a (long long ) conversion// is less than 100% accurate if digitCnt > 15.	while ( LHSd >= 1.0 && digitCnt < MAX_LHS_DIGITS  )	{	// Insert a decimal separator if appropriate		if ( localize && digitCnt % 3 == 0 && digitCnt > 0 )			str [ strIdx-- ] = gKSep;			// Get the next digit		digitll	= ( long long ) ( LHSd / 10.0 );		digitd	= (( double ) digitll ) * 10.0;		digit	= ( Char ) ( '0' + ( Char ) ( LHSd - digitd ));		// Stuff it in a temporary char array		digitCnt++, str [ strIdx-- ] = digit;		LHSd = ( double ) digitll;	}	// Finished left-hand side, store the result in the destination array	StrCopy ( dstP, &str [ strIdx + 1 ] );	// adds terminating NULL	// get the fractional part if required, adding trailing zeroes if space.// Store the picked off digits right in the destination array.		if ( precision > 0 )	{	// Prep destination pointer and termination check values		dstP 		= dstP + StrLen ( dstP );			len			= ( UInt8 ) StrLen ( altDstP );		digitCnt 	= 0;		// Add a decimal point to the destionation buffer		len++, *dstP++ 	= gDSep;		// Pick off digits until the remainder is very small. Zero fill to// precision. Stop zero filling if maxLen is reached to avoid// triggering overflow indication merely by zero filling.		while ( digitCnt < precision )		{			digitCnt++;			// Get the next digit if there's still a significant portion of the// number available. The (long long) conversion makes digits past// VERY_SMALL_NUM most likely inaccurate, so why bother?			if ( RHSd > VERY_SMALL_NUM )			{			// Get the digit				RHSd 	= RHSd * 10.0;				digitll	= ( long long ) RHSd;				digit 	= ( Char ) (( Char ) ( digitll ) + '0');				// Stuff it in the destination array				len++, *dstP++ = digit;				RHSd = RHSd - ( double ) digitll;			}// No significant digit, zero fill out to maxLen			else if ( len < maxLen )			{				len++, *dstP++ = '0';			} else			// Zero filled to maxLen, get out of here. We're done.			{				break;		}	}// Terminate the result.		*dstP++ = '\0';	}			// If the number is too large for displaying, fill it with// overflow indicators and cut it off so it fits.	len = ( UInt8 ) StrLen ( altDstP );	if ( len > maxLen )	{		UInt8	i;		for ( i = 0; i  < maxLen; i++ )		{		// Only convert digits, leave punctuation alone			if (( altDstP [ i ] >= '0' ) && ( altDstP [ i ] <= '9' ))			{				altDstP [ i ] = '>';		}	}		// Terminate the string at the proper length		altDstP [ maxLen ] = '\0';}	}#pragma mark ----------------/************************************ * FUNCTION:    	CheckValidNumChar * * DESCRIPTION: 	Check for valid numeric characters. * * RETURNED:    	true if the character was handled ************************************/static	Boolean 	CheckValidNumChar	// ( out ) handled?(	FieldPtr 	fldP,				// ( in ) pointer to the current field	UInt8		key,				// ( in ) the current keystroke	UInt8		precision	// ( in ) precision of current numeric field){	Boolean handled 	= false;	Char *		hyphen 	= "-";	Char * 	textP = FldGetTextPtr ( fldP );// Allow a hyphen if in the first character position and there isn't one.	if  ( key == '-' &&  FldGetInsPtPosition ( fldP ) == 0 )	{		if ( ! textP || StrStr ( textP, hyphen) == NULL )		{			FldInsert ( fldP, hyphen, 1 );			handled = true;	}	}					// Filter out decimal separator if an integer ( precision == 0 )	else if ( key == gDSep && precision == 0 )	{		handled = true;	}	// Don't let the user enter more than MAX_DIGITS digits on either side of the decimal point	else if ( TxtCharIsDigit ( key ) && textP )	{		UInt8		LHSLen, RHSLen = 0;		UInt16		insertPt = FldGetInsPtPosition ( fldP );		LHSLen = ( UInt8 ) StrLen ( textP );			// Get right and left-hand side lengths of the current string		if ( StrChr ( textP, gDSep ))		{			RHSLen = ( UInt8 )  ( StrLen ( textP ) - (( UInt32 ) StrChr ( textP, gDSep ) - ( UInt32 ) ( textP )) - 1 );			LHSLen = ( UInt8 ) ( LHSLen - RHSLen - 1 );		}		// Ignore excess digits on left-hand side		if ( insertPt <= LHSLen && LHSLen >= MAX_LHS_DIGITS )		{			handled = true;		}		// Ignore excess digits on right-hand side		else if ( insertPt > LHSLen && RHSLen >= MAX_RHS_DIGITS )		{			handled = true;	}	}		return handled;}/*********************************************************************** * FUNCTION:    	DisplayNumber * * DESCRIPTION: 	Fetch a user-entered number from one field, convert *                              it to a double precision number, convert the double to *                              a fully-formatted displayable string, and assign it

⌨️ 快捷键说明

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