March 4, 2021
Hot Topics:

Manipulating Data Records in Win CE

  • By Nancy Nicolaisen
  • Send Email »
  • More Articles »

We are going to continue in our exploration of CE native database functionality by learning how to manipulate specific individual records. To this end, we'll be looking at a bit more of the code from "BetterBirthdays," the example program provided with the last lesson.

Editor's note: Check out Nancy's last article, Flexible Data Access, Powerful Subtleties, for more on the "BetterBirthdays" example.

Deleting a Record from the Database

To begin, let's examine the ways in which we can use a record's CEOID, which is returned by a successful call to CeSeekDatabase(). (Note that in the example code, we saved this value in the global variable globalRecOID.)

Deleting a record is a straightforward operation, so we will start there. Below is a fragment of code from the message switch of the BirthdayDlgProc() function:

   //open the database
   globalHDB = CeOpenDatabase (&globalCEOID, NULL, 0, 0, NULL);
   //delete the record
   CeDeleteRecord(globalHDB, globalRecOID );
   //close the database
   CloseHandle( globalHDB );
   globalHDB = 0;
   //re-init dialog ctrls

To delete a record, we use athe simplest form of the CeOpenDatabase() function, identifying the database with the previously saved CEOID, globalCEOID, and setting all remaining parameters to zero. Using the handle to the database returned by CeOpenDatabase(), and the record CEOID saved after the prior call to FindBirthday(), we delete the record with a call to FindBirthday(), we delete the record with a call to CeDeleteRecord(), and then close the database.

Modifying an Existing Record

We also can access a record by CEOID in order to make modifications. Implementing this capability requires only a few enhancements to the AddBirthdayReminder() function. We used AddBirthdayReminder() in the first example program, BirthdayReminder. Because this new version of the function is similar in many ways to the original version, we'll just highlight the changes here.

First, notice that we have added an item to the original function's parameter list. The new parameter, an int, is used as a flag. It can assume one of two values: ADD_REC or UPDATE_REC. The value of this flag determines whether the function adds a new record or updates an existing record.

BOOL AddBirthdayReminder( HWND hDlg, 
                               int iAddUpdateFlag ){

Another change is that in this version of the program, we no longer store the birth date as the SYSTEMTIME structure that is returned by the dialog's Date Picker control:

//retrieve birthdate from the date time control
   hwndWhen = GetDlgItem(hDlg,IDC_WHEN);
   memset( &SysTime, 0x0, sizeof(SysTime));


   //translate to filetime format
   SystemTimeToFileTime( &SysTime, &ftBirthday );

Rather, we convert the SYSTEMTIME value to a FILETIME. The FILETIME format is much more efficient, for two reasons. First, it encodes all the information in the SYSTEMTIME structure in a single DWORD, saving a great deal of storage space. Second, the CE native database type CEVT_FILETIME directly supports FILETIME values, so its translated value can be stored directly in the CEVALUNION member val.filetime. Here's the new CEPROPVAL structure initialization for this property:

//next, we write the "when" value into a property
    //write the prop id : ce type + index
    pRecord[1].propid = MAKELONG(CEVT_FILETIME , 1) ;
    //now put the FILETIME structure in the value
    //union for this property.
    pRecord[1].val.filetime = ftBirthday;

When we write the record to the database, one of two circumstances will prevail: Either we will be creating a new record at the end of the database, or we will be updating an existing record that we can precisely and immediately locate by CEOID. For this reason, we can do a simple database open operation:

//open the database
   globalHDB = CeOpenDatabase (&globalCEOID, NULL, 0, 0, NULL);
   rc = GetLastError();

If we detect that this is a record addition, we seek to the end of the database and write the record:

if( iAddUpdateFlag == ADD_REC )
      //set oid parm to 0 to create a new rec
      CeWriteRecordProps(globalHDB, 0, NUMBER_BIRTHDAY_PROPS,

If, instead, this is an update, we don't have to seek at all. We simply reference the existing record through its previously retrieved and saved CEOID, and write the new values directly into it:

   //set oid parm to value set by "Find"
   CeWriteRecordProps(globalHDB, globalRecOID,

Page 1 of 2

This article was originally published on May 5, 2004

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date