home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-12 | 43.3 KB | 1,272 lines |
- _WINDOWS 3.0 APPLICATION DEVELOPMENT_
- by Walter Knowles
-
- [LISTING ONE]
-
- /********************************************************
- * FILE: chekmate.ddl
- * DESCRIPTION: db_Vista database definition language schema
- *********************************************************/
-
- database chekmate {
- /* File definition section */
- data file checks1 = "chekmate.d01" contains system, payor, payee,
- tranPayee, account;
- data file checks2 = "chekmate.d02" contains transaction, actual;
- data file checks3 = "chekmate.d03" contains budget, distribution;
-
- key file checkKey = "chekmate.k01" contains strPayorName, strAccountName,
- strAccountCode, strPayeeCode,
- strPayeeName;
- /* Ewcord definition section */
- record payor {
- unique key char strPayorName [35];
- char strPayorAddr1 [35];/* single element fields */
- char strPayorAddr2 [35];/* are easier in toolbook */
- char strPayorCity [20];
- char strPayorState [3];
- char strPayorZip [10];
- char strPayorCtry [10];
- char strPayorTel [15];
- char cPayorRegAdd; /* values are (a)D(d) and */
- char cPayorAccAdd; /*(a)S(k) on exception processing */
- char cPayorPayeeAdd;
- char cPayorAccess; /* values are C(ode) and N(ame) */
- int nPayorYear;
- db_addr dbaPayorCurrBank;
- int nPayorNextRecur;
- }
-
- /* Account covers both balance sheet and income statement accounts. */
- record account {
- key char strAccountName [35];
- key char strAccountCode [15];
- char strAccountNumber [15];
- char cAccountType; /* A L E I E */
- int bAccountTax; /* T= tax related */
- int bAccountIsRegister;
- }
- /* Payee */
- record payee {
- key char strPayeeName [35];
- key char strPayeeCode [15];
- char strPayeeAddr1 [35];
- char strPayeeAddr2 [35];
- char strPayeeCity [20];
- char strPayeeState [3];
- char strPayeeZip [10];
- char strPayeeCtry [10];
- char strPayeeTel [15];
- /* default account is a set */
- char strPayeeMemo [35];
- char strPayeeType [10];
- }
- /* Budget records are owned by the account. */
- record budget {
- int nBudgetMonth; /* number from 1 to 12 */
- long lBudgetAmount;
- }
- /* Actuals are maintained in order; speeds process of updating register.*/
- record actual {
- int nActualMonth;
- long lActualAmount;
- }
- /* Transactions are headers for distributions. */
- record transaction {
- char cTranType; /* check, deposit, etc */
- char strTranMemo [35];
- int bTranClear; /* T = cleared */
- int nTranNumber; /* Check number */
- long lTranDate; /* Transaction date as a
- "COBOL" date: ccyymmdd */
- long lTranAmount;
- }
- /* Distributions are the balancing entries for transactions. */
- record distribution {
- long lDistrAmount;
- }
- /* Set definition section -- Sets with system as parent */
- set system_payor {
- order ascending;
- owner system;
- member payor by strPayorName;
- }
- set system_payeecode {
- order ascending;
- owner system;
- member payee by strPayeeCode;
- }
- set system_payeename {
- order ascending;
- owner system;
- member payee by strPayeeName;
- }
- set system_lastData {
- order next;
- owner system;
- member lastData;
- }
- /* Sets with payor as parent */
- set payor_accountcode {
- order ascending;
- owner payor;
- member account by strAccountCode;
- }
- set payor_accounttypecode {
- order ascending;
- owner payor;
- member account by cAccountType, strAccountCode;
- }
- set payor_accountname {
- order ascending;
- owner payor;
- member account by strAccountName;
- }
- /* Sets with account as parent */
- set account_budget {
- order ascending;
- owner account;
- member budget by nBudgetMonth;
- }
- set account_actual {
- order ascending;
- owner account;
- member actual by nActualMonth;
- }
- set account_distribution {
- order next;
- owner account;
- member distribution;
- }
- /* account_payee implements default distribution account for payees. */
- set account_payee {
- order next;
- owner account;
- member payee;
- }
- /* sets with payee as owner */
- set payee_transaction {
- order next;
- owner payee;
- member transaction;
- }
- /* sets with actual as owner. */
- set actual_transaction_date {
- order ascending;
- owner actual;
- member transaction by lTranDate;
- }
- set actual_transaction_number {
- order ascending;
- owner actual;
- member transaction by nTranNumber;
- }
- set actual_transaction_type {
- order ascending;
- owner actual;
- member transaction by cTranType, lTranDate;
- }
- set actual_distribution {
- order next;
- owner actual;
- member distribution;
- }
- /* sets with transaction as owner */
- set transaction_distribution {
- order next;
- owner transaction;
- member distribution;
- }
- set transaction_tranPayee {
- order next;
- owner transaction;
- member tranPayee;
- }
-
- }
-
-
- [LISTING TWO]
-
- to handle LINKDLLS
-
- -- use the Windows kernel for memory management
- linkdll "kernel.exe"
- word globalAlloc (word,dword)
- word globalFree (word)
- pointer globalLock (word)
- word globalReAlloc(word,dword,word)
- dword globalSize(word)
- word globalUnlock(word)
- end
-
- --use ToolBook's file dll for file system access
- linkdll "tbkfile.dll"
- string getCurrentDirectory(string)
- string getCurrentDrive()
- end
-
- -- use Raima's db_VISTA dll for database functionality
- linkdll "vista.dll"
- --except for close,closetask, and opentask, functions are as
- --in the db_vista docs (dt_ = d_). The last args are *currenttask,dbn
-
- int dt_close (pointer)
- int dt_closetask(pointer)
- int dt_connect (int,pointer,int)
- int dt_crget (pointer,pointer,int)
-
- --other calls ommitted here
-
- int dt_setro (int,pointer,int)
- end
-
- --chekmate.dll is the helper dll for the checking account system
- linkdll "chekmate.dll"
- --other calls ommitted here
- word dbv_EditRegister (word,int,long,int,word,int)
- word dbv_GetRegister (word,int,word)
- end
-
- end
-
- [LISTING THREE]
-
- to handle InitGlobals
- system svhControl, svPtrControl
- system svhDBBuffer, svPtrDBBuffer
- system svhCurrTask, svPtrCurrTask
- set svhControl to GlobalAlloc (66,64) --GHND is 66, size is 64 bytes
- set svhDBBuffer to GlobalAlloc (66,256)
- set svhCurrTask to GlobalAlloc (66,64)
- if svhControl <= 0 or svhDBBuffer <= 0 or svhCurrTask <= 0
- --clean up, since allocation failed
- send FreeGlobals
- send Exit -- shutdown the system
- else
- --get pointers
- set svPtrControl to GlobalLock (svhControl)
- set svPtrDBBuffer to GlobalLock (svhDBBuffer)
- set svPtrCurrTask to GlobalLock (svhCurrTask)
- end
- end
- to handle FreeGlobals
- system svhControl, svPtrControl
- system svhDBBuffer, svPtrDBBuffer
- system svhCurrTask, svPtrCurrTask
- if svhControl is not null and svhControl > 0
- get GlobalUnlock (svhControl)
- get GlobalFree (svhControl)
- end
- if svhDBBuffer is not null and svhDBBuffer > 0
- get GlobalUnlock (svhDBBuffer)
- get GlobalFree (svhDBBuffer)
- end
- if svhCurrTask is not null and svhCurrTask > 0
- get GlobalUnlock (svhCurrTask)
- get GlobalFree (svhCurrTask)
- end
- --clean up globals to make ToolBook suspend rather than GP Fault
- set svhControl to null
- set svhDBBuffer to null
- set svhCurrTask to null
- set svPtrControl to null
- set svPtrDBBuffer to null
- set svPtrCurrTAsk to null
- end
-
- [LISTING FOUR]
-
- typedef struct Control {
- HANDLE hCurrentTask; //current task structure (DB_TASK)
- HANDLE hDataBaseBuffer; //db_Vista's control buffer
-
- // Offscreen image / database address pairs
- HANDLE hRegisterImage; //offscreen image of the register field
- HANDLE hRegisterDBAArray; //array of database addresses, 1 for each line
- //in the register image
- // Selector fields storage
- HANDLE hPayeeCodeArray; //offscreen image of the payee selector field
- HANDLE hPayeeCodeDBAArray; //array of database addresses - payee selector
- HANDLE hPayeeNameArray; //offscreen image of the payee selector field
- HANDLE hPayeeNameDBAArray; //array of database addresses - payee selector
- HANDLE hAccountCodeArray; //offscreen image of account selector field
- HANDLE hAccountCodeDBAArray;//array of database addresses - accts. selector
- HANDLE hAccountNameArray; //offscreen image of account selector field
- HANDLE hAccountNameDBAArray;//array of database addresses - accts selector
- HANDLE hRegisterNumbers; //array of deposit, payments, balances
-
- // Database addresses for active records
- DB_ADDR dbaCurrPayor; //address of the current payor record
- DB_ADDR dbaCurrRegister; //address of the current active register record
- DB_ADDR dbaCurrRegisterActual; //address of current month's register
-
- // Database number for concurrency operations
- int nDatabaseNumber; //normally 0
- } CONTROL;
-
- [LISTING FIVE]
-
- --------------------------
- --CONTROL BLOCK ACCESSOR--
- --------------------------
- to get hControl fField
- system svPtrControl
- set vOffset to ControlOffset(fField)
- set retval to -1
- conditions
- when char 1 of fField is "h" --handles
- set retval to pointerWord(vOffset,svPtrControl)
- when chars 1 to 3 of fField is "dba" --db_addrs
- set retval to pointerlong(vOffset,svPtrControl)
- when char 1 of fField is "n"
- set retval to pointerint(vOffset,svPtrControl)
- end
- return retval
- end
-
- to set hControl fField to fVal
- system svPtrControl
- set vOffset to ControlOffset(fField)
- conditions
- when char 1 of fField is "h" --handles
- get pointerWord(vOffset,svPtrControl,fVal)
- when chars 1 to 3 of fField is "dba" --db_addrs
- get pointerlong(vOffset,svPtrControl,fVal)
- when char 1 of fField is "n"
- get pointerint(vOffset,svPtrControl,fVal)
- end
- end
-
- to get ControlOffset fField
- conditions
- when char 1 of fField is "h" --handles
- conditions
- when fField is hCurrentTask
- set vOffset to 0
- when fField is hDatabaseBuffer
- set vOffset to 1
- when fField is hRegisterImage
- set vOffset to 2
- when fField is hRegisterDBAArray
- set vOffset to 3
- when fField is hRegisterCodeArray
- set vOffset to 4
- when fField is hRegisterCodeDBAArray
- set vOffset to 5
- when fField is hRegisterNameArray
- set vOffset to 6
- when fField is hRegisterNameDBAArray
- set vOffset to 7
- when fField is hPayeeCodeArray
- set vOffset to 8
- when fField is hPayeeCodeDBAArray
- set vOffset to 9
- when fField is hPayeeNameArray
- set vOffset to 10
- when fField is hPayeeNameDBAArray
- set vOffset to 11
- when fField is hAccountCodeArray
- set vOffset to 12
- when fField is hAccountCodeDBAArray
- set vOffset to 13
- when fField is hAccountNameArray
- set vOffset to 14
- when fField is hAccountNameDBAArray
- set vOffset to 15
- when fField is hRegisterNumbers
- set vOffset to 16
- end
- return vOffset*2
- when chars 1 to 3 of fField is "dba" --db_addrs
- set vbase to 34 -- max(vOffset*2)+2
- conditions
- when fField is dbaCurrPayor
- set vOffset to 0
- when fField is dbaCurrRegister
- set vOffset to 1
- when fField is dbaCurrRegisterActual
- set vOffset to 2
- end
- return vbase+vOffset*4
- when char 1 of fField is "n"
- set vbase to 46 --vbase + dbaentries * 4
- conditions
- when fField is "nDatabaseNumber"
- set vOffset to 0
- end
- return vbase+vOffset*2
- end
- end
-
-
- [LISTING SIX]
-
- -- Fill selector loads selector text from global memory into selector field
-
- to handle FILLSELECTOR fComboName,fObjectName
- set vCurdba to dbv_currentrecord()
- set vHText to hControl("h" & fComboName & "Array")
- if vhText = 0
- get createSelectorList (fComboName)
- set vHText to hControl("h" & fComboName & "Array")
- end
- get globalLock (vHText)
- if fObjectName is null
- set fObjectName to fComboName
- end
- set text of (pListID of group fObjectName) to\
- pointerString(0, it)
- get globalUnLock (vHText)
- set dbv_currentrecord() to vCurdba
- end
- -- createSelectorList loads global memory block with values from appropriate
- -- set member fields
- to get createSelectorList fArray
- system svPtrDbBuffer, svPtrCurrTask
- -- first determine what all the database constants are
- conditions
- when fArray is "RegisterName"
- get dt_findfm(20000,svPtrCurrTask,0)
- set vSet to 20006
- get dt_setom(vSet,20000,svPtrCurrTask,0)
- set vField to 1000
- -- cases for "RegisterCode", "PayeeCode", "PayeeName", "AccountCode",
- -- and "AccountName" are similar
- else
- return false
- end
- set vArray to "h" & fArray
- --check if the memory is already allocated
- if hControl(vArray & "Array") = 0
- set vhTextBuffer to globalAlloc(66,1000)
- set vhDBABuffer to globalAlloc(66,500)
- set hControl(vArray & "Array") to vhTextBuffer
- set hControl(vArray & "DBAArray") to vhDBABuffer
- else
- set vhTextBuffer to hControl(vArray & "Array")
- set vhDBABuffer to hControl(vArray & "DBAArray")
- end
-
- set vPtrTextBuffer to globalLock(vhTextBuffer)
- set vPtrDBABuffer to globalLock(vhDBABuffer)
- set vDBAOffset to 0
- set vcharCount to 0
- get dt_findfm(vSet,svPtrCurrTask,0)
- while it = 0
- --build the text buffer
- get dt_crread(vField,svPtrDbBuffer,svPtrCurrTask,0)
- set vline to pointerstring(0,svPtrDbBuffer)
- put CRLF after vLine
- get pointerstring(vCharCount,vPtrTextBuffer,vLine)
- increment vCharCount by charcount(vLine)
- --build the db_addr buffer
- get dt_crget(svPtrDbBuffer,svPtrCurrTask,0)
- get pointerlong(0,svPtrDbBuffer)
- get pointerlong(vDBAOffset,vPtrDBABuffer,it)
- increment vDBAOffset by 4 -- because DBAs are longs
- --get next record
- get dt_findnm(vSet,svPtrCurrTask,0)
- end
- return true
- get globalunLock(vhTextBuffer)
- get globalunLock(vhDBABuffer)
- end
-
- [LISTING SEVEN]
-
- /*****************************************************************************
- * dbv_CreateSelectorList--Purpose: Obtains list of available selections for
- * a particular chekmate field and save them along with database addresses
- * in the chekmate control block.
- * Parameters: hControl, HANDLE to the database control block; nSetID, numeric
- * identifier for set containing selection list; lField, LONG database field
- * number; nHandleOffset, integer offset into the Control block of handle for
- * memory where data should be stored.
- * Return Value: 0, if no errors; -n, if errors reading database
- */
- extern WORD FAR PASCAL dbv_CreateSelectorList(
- HANDLE hControl, // Control Block
- int nSetID, // database set identifier
- LONG lField, // database field number
- int hHandleOffset) // offset in Control Block for memory handle
- {
- int i;
- int iError=-1; // error return code
- LPCONTROL lpControl=NULL; // control block
- DB_TASK DB_FAR *lpTask=NULL; // task pointer
- LPHANDLE lpHandle; // handle pointer
- if (NULL==hControl)
- {
- return -1; // control block not initialized
- }
-
- // Lock control block so task block can be locked for database call.
- lpControl = (LPCONTROL) GlobalLock (hControl);
- lpTask = (DB_TASK DB_FAR *) GlobalLock (lpControl->hCurrentTask);
-
- // point to handle in control block for list text.
- lpHandle = ((LPHANDLE) lpControl) + hHandleOffset;
- iError = LoadSelectorList (lpHandle,lpHandle+1,nSetID,lField,lpTask,
- lpControl->nDatabaseNumber);
- CleanUp:
- GlobalUnlock (lpControl->hCurrentTask);
- GlobalUnlock (hControl);
- return (iError);
- }
-
- /******************************************************************************
- * LoadSelectorList--Purpose: Reads database for specified set and transfer
- * data from lField into text buffer. Each record a separate text line in
- * buffer and database addresses for each record will also be saved.
- * Parameters: lphListText, handle to memory for list text; lphListDBA, handle
- * to memory for list database addresses; nSetID, numeric identifier for
- * database set containing the selection list; lField, LONG database field
- * number; lpTask, pointer to database task; nDatabase, database number
- * Return Value: 0, if no errors; -n, if errors reading database
- */
- int PASCAL LoadSelectorList (
- LPHANDLE lphListText, // handle to memory for list text
- LPHANDLE lphListDBA, // memory handle for list database adr.
- int nSetID, // database set ID
- LONG lField, // database field number for list text
- DB_TASK DB_FAR *lpTask, // database task
- int nDatabase) // database number
- {
- int iError=-1; // error return code
- int nDBA=0; // number of DBA's
- int nMaxDBA=0; // maximum number of DBA's used
- int nMaxBytes=0; // maximum bytes allowed
- LPSTR lpText=NULL; // current text line
- DB_ADDR FAR *lpDBA=NULL; // database address value
- HANDLE hMem; // handle to reallocated memory block
- DB_ADDR lCurDBA; // current database record
-
- // save the current database record
- dt_crget ((DB_ADDR FAR *)&lCurDBA,lpTask,nDatabase);
-
- // initialize the text and DBA memory blocks.
- if (*lphListText == NULL)
- {
- *lphListText = GlobalAlloc (DLL_ALLOC,SELECTOR_TEXT_SIZE);
- }
- if (*lphListDBA == NULL)
- {
- *lphListDBA = GlobalAlloc (DLL_ALLOC,(LONG)(SELECTOR_DBA_COUNT*sizeof
- (DB_ADDR)));
- }
- if (*lphListText == NULL || *lphListDBA == NULL)
- {
- goto CleanUp;
- }
-
- // initial allocations to set the maximum values and lock the memory blocks.
- nMaxDBA = GlobalSize (*lphListDBA) / sizeof(DB_ADDR);
- nMaxBytes = GlobalSize (*lphListText);
-
- lpText = GlobalLock (*lphListText);
- lpDBA = (DB_ADDR FAR *) GlobalLock (*lphListDBA);
-
- // read the database and fill in the text values
- for (iError = dt_findfm (nSetID,lpTask,nDatabase);
- iError==S_OKAY;
- iError = dt_findnm (nSetID,lpTask,nDatabase))
- {
- if (nMaxBytes<=MIN_SELECTOR_TEXT_SIZE)
- {
- // need to allocate more text memory.
- lpText = NULL;
- GlobalUnlock (*lphListText);
- hMem = GlobalReAlloc (*lphListText,
- GlobalSize(*lphListText)+SELECTOR_TEXT_SIZE,
- GMEM_ZEROINIT);
- if (hMem==NULL)
- {
- iError = -2;
- goto CleanUp; // not enough memory
- }
- *lphListText = hMem; // new handle
- lpText = GlobalLock (*lphListText);
- nMaxBytes = GlobalSize(*lphListText) - lstrlen (lpText);
- lpText += lstrlen(lpText);
- }
- // read the field contents into the text buffer
- dt_crread(lField,lpText,lpTask,nDatabase);
- lstrcat (lpText,"\r\n");
- lpText += lstrlen(lpText);
-
- // save the DBA of the record
- if (nDBA >= nMaxDBA)
- {
- // need to allocate more DBA memory.
- lpDBA = NULL;
- GlobalUnlock (*lphListDBA);
- hMem = GlobalReAlloc (*lphListDBA,
- GlobalSize(*lphListDBA)+SELECTOR_DBA_COUNT*sizeof(DB_ADDR),
- GMEM_ZEROINIT);
- if (hMem==NULL)
- {
- iError = -2;
- goto CleanUp; // not enough memory
- }
- *lphListDBA = hMem; // new handle
- lpDBA = (DB_ADDR DB_FAR *)GlobalLock (*lphListDBA);
- nMaxDBA = GlobalSize(*lphListDBA) - nDBA;
- lpDBA += nDBA;
- }
- dt_crget (lpDBA,lpTask,nDatabase);
- lpDBA++;
- nDBA++;
- }
- CleanUp:
- // restore the address of the current record
- dt_crset ((DB_ADDR far *)&lCurDBA,lpTask,nDatabase);
- if (lpText!=NULL)
- {
- GlobalUnlock (*lphListText);
- }
- if (lpDBA!=NULL)
- {
- GlobalUnlock (*lphListDBA);
- }
- if (iError==S_EOS)
- {
- iError = S_OKAY;
- }
- return (iError);
- }
-
-
-
- [BALANCE MAINTENACE CODE]
-
- typedef struct RegisterNumbers {
- long lDeposit; //value of the deposit (may be 0)
- long lPayment; //value of the payment (may be 0)
- long lBalance; //value of the balance
- } REGISTERNUMBERS;
-
- /*******************************************************************************
- * UpdateRegisterNumbers
- *
- * Purpose:
- * This routine will update the register payments, deposits and balance
- * arrays. Additonally it will copy the information into the register
- * text arrays and add the final zero byte to the register text
- *
- * Parameters:
- * lpControl pointer to the control block
- *
- * Return Value:
- * 0 if no errors
- *
- */
- int PASCAL UpdateRegisterNumbers(
- LPCONTROL lpControl) // pointer to the Control block
- {
- int i;
- char cPayment[20], cDeposit[20], cBalance[20];
- LONG lBegBal; // begining balance
- LPREGISTERNUMBERS lpNumbers; // register numbers
- LPREGISTERIMAGE lpImage; // register image block
- LPSTR lpLine; // register line image
- LONG lPrevBal; // previous balance
-
- lpImage = (LPREGISTERIMAGE) GlobalLock (lpControl->hRegisterImage);
- lpNumbers = (LPREGISTERNUMBERS) GlobalLock (lpControl->hRegisterNumbers);
- lpLine = (LPSTR) &(lpImage->Text[0]);
-
- // we first go thru the list of numbers and set the balances and then
- // we convert the values to strings and place them into the register
- // line. Note the register lines are assumed to be blank filled and
- // terminated with a CRLF.
-
- for (i=0,lPrevBal=lpNumbers->lBalance;i<lpImage->nLines;i++,lpNumbers++)
- {
- lPrevBal =
- lpNumbers->lBalance = lPrevBal +
- lpNumbers->lDeposit - lpNumbers->lPayment;
-
- // convert the values to zero terminated strings
- Long2Money (lpNumbers->lPayment,(LPSTR) &(cPayment[0]));
- Long2Money (lpNumbers->lDeposit,(LPSTR) &(cDeposit[0]));
- Long2Money (lpNumbers->lBalance,(LPSTR) &(cBalance[0]));
- wsprintf (lpLine+50," %10s %10s %10s",
- (LPSTR) &(cPayment[0]),
- (LPSTR) &(cDeposit[0]),
- (LPSTR) &(cBalance[0]));
-
- // now add the CRLF to the lines the current zero byte placed in
- // the lpLine will be overwritten and no zero byte will be used.
- lpLine += lstrlen(lpLine); // positioned at the zero byte
- *lpLine++ = '\r';
- *lpLine++ = '\n';
- // lpLine now positioned correctly for begining of next line
- }
- // add the final empyt line and a zero byte to terminate the register text field
- lstrcat (lpLine,"\r\n");
-
- GlobalUnlock (lpControl->hRegisterImage);
- GlobalUnlock (lpControl->hRegisterNumbers);
- return (0);
- }
-
-
- /*******************************************************************************
- * Long2Money
- *
- * Purpose:
- * convert a long number into a money text string. The numeric value
- * is in terms of cents.
- *
- * Parameters:
- * lValue LONG value to be converted
- * lpText LPSTR to the text string
- *
- * Return Value:
- * LPSTR pointer to the text string
- *
- */
- LPSTR PASCAL Long2Money(
- LONG lValue, // long value to be converted
- LPSTR lpDecimalText) //
- {
- LPSTR lpStr = lpDecimalText;
-
- // Take care of the sign of the number so that the conversion
- // will only have to deal with positive values.
- if (lValue <0)
- {
- lValue = -lValue;
- *lpStr++ = '-';
- }
- // convert the number to characters - note if the value is less
- // than 100 then we will want the number to be be converted as
- // 0.nn Therefore 100 will be added to the value and then later
- // the '1' will be replaced with a '0'.
-
- wsprintf (lpStr,"%li",(LONG) ((lValue<100)?lValue+100:lValue));
-
- // now make room for the decimal point
- lpStr += lstrlen(lpStr); // lpStr points to the end of the string
- *(lpStr+1) = *lpStr; lpStr--; // terminating character
- *(lpStr+1) = *lpStr; lpStr--; // units digit
- *(lpStr+1) = *lpStr; // tens digit
- *lpStr-- = '.'; // add in the decimal point
- if (lValue < 100)
- {
- *lpStr = '0'; // replace the '1' with a '0' forces leading zero
- }
- return (lpDecimalText);
- }
-
- [REGISTER MAINTENANCE CODE]
-
- /*******************************************************************************
- * dbv_GetRegister
- *
- * Purpose:
- * This routine will read the transactions associated with the current
- * account for a given month and generates a checkbook register image.
- * The image is saved in memory and also set into the toolbook fields
- * specified in hFldTable.
- *
- * Parameters:
- * hControl HANDLE to the database control block
- * nSetID numeric identifier for database set
- * hFldTable HANDLE to the ToolBook field table list
- *
- * Return Value:
- * 0 if no errors
- * 1 if error in setting field
- * -1 control block not initialized
- *
- */
- extern WORD FAR PASCAL dbv_GetRegister(
- HANDLE hControl, // Control Block
- int nSetID) // database set identifier
- {
- int i;
- int iError=0; // error return
- LPCONTROL lpControl=NULL; // control block
- int nDatabase; // database number
- LPREGISTERIMAGE lpImage=NULL; // pointer to the register image block
-
- // Lock the control block so that the task block and the database
- // buffer can be obtained. The database buffer will be used to contain
- // the individual field values for the current record.
-
- if (NULL==hControl)
- {
- return -1; // control block not initialized
- }
-
- // Lock the control block so that the task block can be locked for the
- // database call. Then lock the field table so that we can access
- // which ToolBook fields are to be set.
-
- lpControl = (LPCONTROL) GlobalLock (hControl);
- lpFldTable = (LPFLDTABLE) GlobalLock(hFldTable);
-
- // Initialize the memory blocks that will be used for the register
- // information.
- if (0!=(iError=InitRegisterImage(lpControl)))
- {
- goto CleanUp;
- }
-
- // Now we load the register image
- if (0!=(iError=LoadRegisterImage (lpControl,nSetID)))
- {
- goto CleanUp;
- }
-
- GlobalUnlock (lpControl->hRegisterImage);
-
-
- CleanUp:
-
- // all done - now unlock all the allocations
- GlobalUnlock (lpFldTable->hBookName);
- GlobalUnlock (hFldTable);
- GlobalUnlock (hControl);
- return 0;
- }
-
- /*******************************************************************************
- * InitRegisterImage
- *
- * Purpose:
- * This routine will initialize the memory blocks that will contain the
- * chekmate register image, the database addresses and the array of the
- * deposits, payments and balances for the register.
- *
- * Parameters:
- * lpControl pointer to the control block
- *
- * Return Value:
- * 0 if no errors
- * -1 if error allocating the memory
- *
- */
- int PASCAL InitRegisterImage(
- LPCONTROL lpControl) // pointer to the Control block
- {
- LPREGISTERIMAGE lpImage; // pointer to the register image
-
- // if the handles are currently pointing to memory blocks then we free
- // them and re-allocate. This is done just to make life a little easier
-
- if (NULL!=lpControl->hRegisterImage)
- {
- GlobalFree (lpControl->hRegisterImage);
- lpControl->hRegisterImage = NULL;
- }
- if (NULL!=lpControl->hRegisterDBAArray)
- {
- GlobalFree (lpControl->hRegisterDBAArray);
- lpControl->hRegisterDBAArray = NULL;
- }
- if (NULL!=lpControl->hRegisterNumbers)
- {
- GlobalFree (lpControl->hRegisterNumbers);
- lpControl->hRegisterNumbers = NULL;
- }
-
- // now allocate the space for the register image array
- lpControl->hRegisterImage = GlobalAlloc (DLL_ALLOC,
- (LONG) sizeof(REGISTERIMAGE)+
- (INITIALREGISTERLINES*REGISTERLINESIZE));
- if (NULL==lpControl->hRegisterImage)
- {
- return -1;
- }
- // now allocate the database address lists
- lpControl->hRegisterDBAArray = GlobalAlloc (DLL_ALLOC,
- ((long) sizeof(DB_ADDR))*((long) INITIALREGISTERLINES));
- if (NULL==lpControl->hRegisterDBAArray)
- {
- return -1;
- }
-
- // now allocate the register payments, deposits and balance columns
- lpControl->hRegisterNumbers = GlobalAlloc (DLL_ALLOC,
- ((long) sizeof(REGISTERNUMBERS))*((long)
- INITIALREGISTERLINES));
- if (NULL==lpControl->hRegisterNumbers)
- {
- return -1;
- }
-
- // initialize the image structure to contain the header information
- lpImage = (LPREGISTERIMAGE) GlobalLock (lpControl->hRegisterImage);
- lpImage->nMaxLines = INITIALREGISTERLINES;
- lpImage->nLines = 0;
-
- GlobalUnlock (lpControl->hRegisterImage);
- return (0);
- }
-
-
-
- /*******************************************************************************
- * LoadRegisterImage
- *
- * Purpose:
- * This routine will load the register data from the database.
- *
- * Parameters:
- * lpControl pointer to the control block
- * nSetID transaction set id
- *
- * Return Value:
- * 0 if no errors
- * -1 if error reading the database
- *
- */
- int PASCAL LoadRegisterImage(
- LPCONTROL lpControl, // pointer to the Control block
- int nSetID) // set containing the transaction members
- {
- int i;
- int iError=0; // error return
- DB_ADDR lCurDBA; // current database address
- actual Actual; // current months value
- payee Payee; // current transactions payee
- transaction Transaction; // current transaction
- int nDatabase; // database number
- DB_ADDR lTranDBA; // transaction dba
- DB_TASK DB_FAR *lpTask=NULL; // task pointer
- DB_ADDR FAR *lpDBA; // database address array
- LPREGISTERNUMBERS lpNumbers; // register numbers
- LPREGISTERIMAGE lpImage; // register image block
- LPSTR lpLine; // line for the register image
-
- // lock the task, the register image, the database addresses array
- // and the register number array.
-
- lpTask = (DB_TASK DB_FAR *) GlobalLock (lpControl->hCurrentTask);
- nDatabase = lpControl->nDatabaseNumber;
-
- // save the current database record
- dt_crget ((DB_ADDR FAR *)&lCurDBA,lpTask,nDatabase);
-
- // now we load up the register data. The fist line in the register is
- // the begining balance. We "Fake out" the first line by creating
- // a psudeo transaction record for the actual month record.
-
- dt_crset ((DB_ADDR far *)&(lpControl->dbaCurrRegisterActual),lpTask,nDatabase);
- dt_setor (nSetID,lpTask,nDatabase);
- if (S_OKAY!=(iError=dt_recread((DB_ADDR FAR *)&Actual,lpTask,nDatabase)))
- {
- goto CleanUp;
- }
- lpImage = (LPREGISTERIMAGE) GlobalLock (lpControl->hRegisterImage);
- lpDBA = (DB_ADDR FAR *) GlobalLock (lpControl->hRegisterDBAArray);
- lpNumbers = (LPREGISTERNUMBERS) GlobalLock (lpControl->hRegisterNumbers);
-
- Transaction.cTranType = BBAL; // begining balance
- Transaction.lTranDate = 19000001 + (Actual.nActualMonth)*100; // date
- Transaction.nTranNumber = 0; // transaction number
- Transaction.bTranClear = 0;
- Transaction.lTranAmount = Actual.lActualAmount;
- lpNumbers->lBalance = Actual.lActualAmount;
- dt_crget (lpDBA++,lpTask,nDatabase);
- GenerateRegisterLine ((LPTRANSACTION) &Transaction,(LPPAYEE) &Payee,&(lpImage->Text[0]));
- lpImage->nLines++;
- lpNumbers++;
-
- GlobalUnlock (lpControl->hRegisterImage);
- GlobalUnlock (lpControl->hRegisterDBAArray);
- GlobalUnlock (lpControl->hRegisterNumbers);
-
- // now step thru the database reading the members of the set and
- // generating register lines for them.
- for (iError=dt_findfm (nSetID,lpTask,nDatabase),i=1;
- iError==S_OKAY;
- iError=dt_findnm (nSetID,lpTask,nDatabase),i++)
- {
- dt_crget ((DB_ADDR FAR *) &lTranDBA,lpTask,nDatabase);
- EditRegisterImage (lpControl,i,lTranDBA,nSetID,ADD_TRAN);
- }
-
- // now fill in the payment, deposit and balance fields
- UpdateRegisterNumbers (lpControl);
-
- CleanUp:
- // restore the address of the current record
- dt_crset ((DB_ADDR far *)&lCurDBA,lpTask,nDatabase);
-
- GlobalUnlock (lpControl->hCurrentTask);
-
- return (((iError==S_EOS)?S_OKAY:iError));
-
- }
-
-
- [DB_VISTA SHELL CODE]
-
- -- composite functions for adding and editing records
-
- to get dbv_AddRecord fHDbControl, ftbFields, fRecordID
- system svPtrCurrTask,svPtrDbBuffer
-
- get dt_fillnew(fRecordID,svPtrDbBuffer,svPtrCurrTask,0)
- get last char of fRecordID
- set vStartingField to it *1000 --starting fields of VISTA records are on 1000 boundries
- return dbv_EditRecord(fHDbControl, fTbFields, vStartingField)
- end
-
-
- to get dbv_EditRecord fHDbControl, ftbFields, fStartingField
- system svPtrCurrTask,svPtrDbBuffer
- set vFldCount to itemcount( fTbFields )
- step i from 1 to vFldCount
- get item i of fTbFields
- get pointerstring(0,svPtrDbBuffer,text of field id it)
- get dt_crwrite(fStartingField+i,svPtrDbBuffer,svPtrCurrTask,0)
- end
- return true
- end
-
-
- to get dbv_GetTBFieldArray fhDBControl, fSet, fFieldID, fTbFields
- system svPtrDbBuffer,svPtrCurrTask, svCurrAccountDBA
-
- set vCurDBA to dbv_currentrecord()
- get dt_findfm(fSet,svPtrCurrTask,0)
- if it = 0
- set vFldCount to itemcount( fTbFields)
- step i from 1 to vFldCount
- get dt_crread(fFieldID,svPtrDbBuffer,svPtrCurrTask,0)
- set vID to item i of fTbFields
- set text of field id vID\
- to pointerLong(0,svPtrDbBuffer)/10
- format text of field id vID as "0.00"
- if dt_findnm(fSet,svPtrCurrTask,0) <> 0
- break step
- end
- end
- end
- set dbv_currentrecord() to vCurDBA
- return true
- end
-
- to get dbv_EditTBFieldArray fhDBControl, fhFldTable, fSet, fTbFields
- system ,svPtrDbBuffer,svPtrCurrTask, svCurrAccountDBA
-
- set vCurDBA to dbv_currentrecord()
- get dt_findfm(fSet,svPtrCurrTask,0)
- if it = 0
- set vFldCount to itemcount( fTbFields )
- step i from 1 to vFldCount
- get text of field id (item i of fTbFields)
- format it as "0"
- get pointerLong(0,svPtrDbBuffer,it)
- get dt_crwrite(fFieldID,svPtrDbBuffer,svPtrCurrTask,0)
- if dt_findnm(fSet,svPtrCurrTask,0) <> 0
- break step
- end
- end
- end
- set dbv_currentrecord() to vCurDBA
- return true
- end
-
- to get dbv_field fType,fFieldNumber
- system svhControl,svPtrCurrTask,svPtrDbBuffer
- get dt_crread(fFieldNumber,svPtrDbBuffer,svPtrCurrTask,0)
- if fType is "CHAR"
- set vVal to pointerByte(0,svPtrDbBuffer)
- set vVal to ansitochar(vVal)
- else
- execute "set vVal to pointer" & fType & "(0,svPtrDbBuffer)"
- end
- return vVal
- end
-
- to set dbv_field fType,fFieldNumber to fVal
- system svhControl,svPtrCurrTask,svPtrDbBuffer
- if ftype is "CHAR"
- get chartoansi(fVal)
- get pointerbyte (0,svPtrDbBuffer,it)
- else
- execute "get pointer" & fType & "(0,svPtrDbBuffer,fVal)"
- end
- get dt_crwrite(fFieldNumber,svPtrDbBuffer,svPtrCurrTask,0)
- end
-
-
-
-
- -- db_vISTA shell functions
-
- to get dbv_connectSet fSet
- system svPtrCurrTask
- get dt_connect(fSet,svPtrCurrTask,0)
- end
-
- to get dbv_currentOwnerField fSet, fType, fFieldNumber
- system svhControl,svPtrCurrTask,svPtrDbBuffer
- get dt_csoread(fSet,fFieldNumber,svPtrDbBuffer,svPtrCurrTask,0)
- if fType is "CHAR"
- set vVal to pointerByte(0,svPtrDbBuffer)
- set vVal to ansitochar(vVal)
- else
- execute "set vVal to pointer" & fType & "(0,svPtrDbBuffer)"
- end
- return vVal
- end
-
- to set dbv_currentOwnerField fSet, fType, fFieldNumber to fVal
- system svhControl,svPtrCurrTask,svPtrDbBuffer
- if ftype is "CHAR"
- get chartoansi(fVal)
- get pointerbyte (0,svPtrDbBuffer,it)
- else
- execute "get pointer" & fType & "(0,svPtrDbBuffer,fVal)"
- end
- get dt_csowrite(fSet,fFieldNumber,svPtrDbBuffer,svPtrCurrTask,0)
- end
-
- to get dbv_memberCount fSet
- system svPtrCurrTask,svPtrDbBuffer
- get dt_members(fSet,svPtrDbBuffer,svPtrCurrTask,0)
- return (pointerLong(0,svPtrDbBuffer))
- end
-
- to get dbv_findFirstMember fSet
- system svPtrCurrTask
- return dt_findfm(fSet,svPtrCurrTask,0)
- end
-
- to get dbv_setOwnerToCurrRec fSet
- system svPtrCurrTask
- return dt_setor(fSet,svPtrCurrTask,0)
- end
-
-
- to get dbv_currentOwner fSet
- system svPtrCurrTask,svPtrDbBuffer
- set verror to dt_csoget(fSet,svPtrDbBuffer,svPtrCurrTask,0)
- set vdba to pointerlong(0,svPtrDbBuffer)
- set sysError to vError
- return vdba
- end
-
- to set dbv_currentOwner fSet to fDBA
- system svPtrCurrTask,svPtrDbBuffer
- if fDBA is null or fDBA is 0
- get dbv_currentOwner(fSet)
- if sysError = 0
- get dt_discon(fSet,svPtrCurrTask,0)
- end
- else
- get pointerlong(0,svPtrDbBuffer,fDBA)
- get dt_csoset(fSet,svPtrDbBuffer,svPtrCurrTask,0)
- end
- end
-
-
-
- to set dbv_connectOwner fSet to fDBA
- system svPtrCurrTask,svPtrDbBuffer
- set vCurrDBA to dbv_currentRecord()
- if dt_ismember(fSet,svPtrCurrTask,0) = 0
- get dt_discon(fSet,svPtrCurrTask,0)
- end
- if not(fDBA is null or fDBA is 0 )
- get pointerlong(0,svPtrDbBuffer,fDBA)
- get dt_csoset(fSet,svPtrDbBuffer,svPtrCurrTask,0)
- get dbv_currentmember(fSet)
- get dbv_currentrecord()
- get dbv_currentType()
- get dbv_currentOwner(fset)
-
- --get dt_csmset(fSet,)
- get dt_connect(fSet,svPtrCurrTask,0)
- end
- end
-
- to get dbv_currentMember fSet
- system svPtrCurrTask,svPtrDbBuffer
- set verror to dt_csmget(fSet,svPtrDbBuffer,svPtrCurrTask,0)
- set vdba to pointerlong(0,svPtrDbBuffer)
- set sysError to vError
- return vdba
- end
-
- to get dbv_currentType
- system svPtrCurrTask,svPtrDbBuffer
- get dt_crtype(svPtrDbBuffer,svPtrCurrTask,0)
- return pointerint(0,svPtrDbBuffer)
- end
-
- to get dbv_currentRecord
- system svPtrCurrTask,svPtrDbBuffer
- set verror to dt_crget(svPtrDbBuffer,svPtrCurrTask,0)
- set vdba to pointerlong(0,svPtrDbBuffer)
- set sysError to vError
- return vdba
- end
-
- to set dbv_currentRecord to fDBA
- system svPtrCurrTask,svPtrDbBuffer
- get pointerlong(0,svPtrDbBuffer,fDBA)
- get dt_crset(svPtrDbBuffer,svPtrCurrTask,0)
- end
-
-
- --dbv_findKey finds the key that matches fKeyVal, or the next higher key that
- --contains fKeyVal
-
- to get dbv_findkey fField, fKeyVal, fType
- system svPtrDbBuffer,svPtrCurrTask
- execute ("get pointer" & fType & "(0,svPtrDbBuffer,fKeyVal)")
- get dt_keyfind(fField, svPtrDbBuffer, svPtrCurrTask,0)
- if it <> 0
- get dt_keynext(fField,svPtrCurrTask,0)
- if it <> 0
- return -2
- end
- execute ("get pointer" & fType & "(0,svPtrDbBuffer)")
- if fKeyVal is in it
- return 0
- else
- return -1
- end
- end
- end
-
- -- dbv_findrecord navigates through a set to find the nearest member of a set
- -- that matches or exceeds fVal
- to get dbv_findrecord fSet,fField,fVal,fType
- system svPtrDbBuffer,svPtrCurrTask
- set vCurrDBA to dbv_currentrecord()
- set sysError to -1
- set retval to 0
- set dbv_currentowner (fSet) to vCurrDBA
- get dt_findfm(fSet,svPtrCurrTask,0)
- if it = 0
- get dt_crread(fField, svPtrDbBuffer, svPtrCurrTask, 0)
- execute ("set vdbVal to pointer" & fType &"(0,svPtrDbBuffer)")
- while vdbval <= fVal as text
- if vdbval is fval
- set retval to dbv_currentrecord()
- break while
- end
- get dt_findnm(fSet,svPtrCurrTask,0)
- if it <> 0
- break while
- end
- get dt_crread(fField, svPtrDbBuffer, svPtrCurrTask, 0)
- set it to "set vdbVal to pointer" & fType &"(0,svPtrDbBuffer)"
- execute it
- end
- end
- set dbv_currentrecord() to vCurrDBA
- return retval
- end
-
-