ToDoにデータを追加してみる

標準アプリのToDoにデータを追加するコードを書いてみた。今回も、SDKに付属のサンプルコードを参考にしています。

// ToDoのレコード構造
typedef struct {
	DateType dueDate;	// 終了日なしはToDoNoDueDateを指定
	UInt8 priority;		// 最上位ビット(0x80)は、終了フラグ
	char description;	// description文字列('\0'終端) と note文字列('\0') の連結が続く
} ToDoDBRecord;

// 終了日なし
#define ToDoNoDueDate	0xffff

// descriptionとnoteが空('\0'のみ)のときのサイズ
#define ToDoDBRecordSize (sizeof(ToDoDBRecord) + 1)

#define DefaultPriority		1

/**
 * 文字列bufferのoffsetで指定された位置からバイト数sizeの文字列を、ToDoに追加する。
 * 終端ヌル文字は追加するので、バイト数sizeの中にはヌル文字を含めない。
 */
Err AddToDo(Char* buffer, UInt32 offset, UInt32 size, UInt16 category) {
	UInt16 index = dmMaxRecordIndex, attr;
	Char zero = chrNull;
	MemHandle recordH;
	ToDoDBRecord newRecord;
	ToDoDBRecord* recordP;
	ToDoDBRecord* nullP = 0; // オフセット計算用のダミー
	
	// 完了日と優先度の設定
	(*(UInt16 *) &newRecord.dueDate) = ToDoNoDueDate;
	newRecord.priority = DefaultPriority;

	// 新規レコードの作成	
	recordH = DmNewRecord(ToDoDBRef, &index, ToDoDBRecordSize + size);
	if(!recordH) {
		return DmGetLastErr();
	}
	
	// newRecordの値を、recordPに書き込み
	recordP = MemHandleLock(recordH);
	DmWrite(recordP, (UInt32)&nullP->dueDate, &newRecord.dueDate, sizeof(nullP->dueDate));
	DmWrite(recordP, (UInt32)&nullP->priority, &newRecord.priority, sizeof(nullP->priority));
	DmWrite(recordP, (UInt32)&nullP->description, buffer + offset, size);
	DmWrite(recordP, (UInt32)&nullP->description + size,
				&zero, sizeof(Char)); // descriptionの終端ヌル文字
	DmWrite(recordP, (UInt32)&nullP->description + size + sizeof(Char),
				&zero, sizeof(Char)); // noteの終端ヌル文字
	MemHandleUnlock(recordH);
	DmReleaseRecord(ToDoDBRef, index, true);
	
	// カテゴリの設定
	DmRecordInfo(ToDoDBRef, index, &attr, NULL, NULL);
	attr |= category;
	DmSetRecordInfo(ToDoDBRef, index, &attr, NULL);
	
	return errNone;
}

注意点として、上記のコードはデータベースの最後尾にレコードを追加しているので、ToDoアプリで表示したときに、表示順が設定したソート順と一致しないことがあります。サンプルコードだと、設定されたソート順で挿入すべき場所を探して、ちゃんと適切な位置にレコードを挿入してますが、上のコードはその処理を手抜きしてます。

これで、メモ帳のデータを読み込んだり、ToDoにデータを追加したりするプログラムが書けるようになった。普段はPalm上の操作でできることがプログラムでできるようになると、なんだか楽しい。