Property values can be read from a record using the CeReadRecordPropsEx function. You can choose to read all or some of the properties associated with a record. Listing 4.8 shows how to read all properties from all the records written in the previous section. Listing 4.8 Reads a recordvoid ReadNextDBRecord(HANDLE hDB) { CEOID ceoidRec; DWORD dwBuf; CEPROPVAL *props = NULL; unsigned short lProps; ceoidRec = CeReadRecordPropsEx(hDB, CEDB_ALLOWREALLOC, &lProps, NULL, (LPBYTE*)&props, &dwBuf, NULL); if(ceoidRec == 0) cout _T("Could not read record") endl; else { for (int i =0; i < lProps; i++) { switch (props[i].propid) { case propCompany: cout _T(" Company: ") props[i].val.lpwstr; break; case propCompanyID: cout _T(" Company ID: ") props[i].val.lVal; break; case propCompanyTel: cout _T(" Company Tel: ") props[i].val.lpwstr; break; } } cout endl; LocalFree(props); } } void Listing4_8() { HANDLE hDB = Listing4_4(); // open database if(hDB != INVALID_HANDLE_VALUE) { ReadNextDBRecord(hDB); ReadNextDBRecord(hDB); ReadNextDBRecord(hDB); Listing4_5(hDB); // close database } } CeReadRecordPropsEx reads properties from the current database record. Each call to CeReadRecordpropsEx moves the current record pointer tothe next record, since the flag CEDB_AUTOINCREMENT was used when the database was opened. Without this flag the code would continuously read the first record in the database.
The major complexity in calling CeReadRecordPropsEx is deciding how to allocate the buffer in which the property data will be returned. The easiest way is to get CeReadRecordPropsEx to do the work: Specify the CEDB_ ALLOWREALLOC flag and pass in a NULL pointer for lplpBuffer, and CeReadRecordPropsEx will do the allocation. However, in this case you must ensure you call LocalFree to free the memory when you have finished. In Listing 4.8 all properties are being read from the record since lpcPropID is passed as NULL. Note that the order of properties in the returned buffer is not necessarily the same as the order in which they were written. In Listing 4.8 a loop is used to examine each property, matching the property identifiers to the known property identifiers. Once the property identifier has been matched, its data type is known. You should try to reduce the number of calls you make to CeReadRecordPropsEx. It is much more efficient to read all the properties you need in a single call. Listing 4.9 shows a call to CeReadRecordPropsEx where a single property identifier is specified and the function returns a buffer containing the property data for that one property. The variable lProps is initialized with the number of properties to read (which is one), and propsToRead is set to the property identifier of the property to read (the company's name). The properties are returned in the buffer pointed to by props in the same order in which they are specified in propsToRead. Listing 4.9 Reads a single propertyvoid ReadOneProp(HANDLE hDB) { CEOID ceoidRec; DWORD dwBuf; CEPROPVAL *props = NULL; unsigned short lProps = 1; // # properties to read CEPROPID propsToRead; propsToRead = propCompany; // only read company name ceoidRec = CeReadRecordPropsEx(hDB, CEDB_ALLOWREALLOC, &lProps, &propsToRead, (LPBYTE*)&props, &dwBuf, NULL); if(ceoidRec == 0) cout _T("Could not read record") endl; else { cout _T(" Company: ") props[0].val.lpwstr endl; LocalFree(props); } }
|