| ホーム | WDIC | palmware開発 | 掲示板 | リンク |
Boolean newSearch;
DmSearchStateType state;
UInt16 cardNo;
LocalID dbID;
Char docName[dmDBNameLength];
newSearch = true; NumDocs = 0;
while (1) {
if (errNone != DmGetNextDatabaseByTypeCreator(newSearch, &state,
'TEXt', 'REAd', false, &cardNo, &dbID))
break;
DmDatabaseInfo(cardNo, dbID, docName, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
newSearch = false;
NumDocs ++;
}
ヘッダーレコードのフォーマット
typedef struct {
UInt16 version;
UInt16 reserved;
UInt32 length;
UInt16 numRecords;
UInt16 recordSize;
} DocHeaderType;
| ヘッダーレコードのフォーマット | ||
|---|---|---|
| version | 2 bytes | 0x0002:圧縮, 0x0001:非圧縮 |
| reserved | 2 bytes | 予約(0) |
| length | 4 bytes | 圧縮前の文書サイズ |
| numRecords | 2 bytes | 文書レコード数 |
| recordSize | 2 bytes | レコードサイズ(通常 4096) |
| データ(N) | 展開内容 |
|---|---|
| 0x01 - 0x08 | 続くNバイトをそのまま出力する |
| 0x09 - 0x7f | そのまま出力する |
| 0x80 - 0xbf | 続くもう一バイトを使用してUInt16としてスライド辞書コピーをする 得られた UInt16 の下位14bitの内、上位11ビットがコピー開始位置(1-2047bytes)、下位3ビット+3がコピーバイト数(3-10bytes)となる |
| 0xc0 - 0xff | スペース(' ') + N ^ 0x80 を出力する |
ソースを見てもらうのが一番早いと思うのでソースを提示します。 srcP が文書レコードのポインタ、dstPが出力する側のポインタです。 一つだけ注意しないといけないのは dstP 側に用意するメモリのサイズです。 ヘッダの recordSize より少し大きく用意しなければなりません。 恐らくスライドコピー分(10bytes)程度大きければよいと思っていますが、 念のため128bytes位多めに確保しておきます。
while (srcP < srcP + recordSize) {
UInt16 ch = * (UInt8 *) srcP;
if (ch < 0x09) {
/* 続くn(1〜8)文字をそのまま出力する */
srcP ++;
while (ch > 0) {
*(dstP++) = *(srcP++);
ch --;
}
} else if (ch < 0x80) {
/* ASCII文字列をそのまま出力 */
*(dstP++) = *(srcP++);
} else if (ch < 0xc0) {
/* スライド辞書コピー */
UInt16 slide; /* コピー開始位置 */
UInt16 count; /* コピー文字数 */
ch <<= 8; ch += * (UInt8 *) (++srcP); /* 2bytes を使用する */
slide = (ch & 0x3fff) >> 3;
count = (ch & 0x7) + 3;
while (count > 0) {
*dstP = *(dstP - slide);
dstP ++; count --;
}
srcP ++;
} else {
/* スペース + ch ^ 0x80 */
*(dstP++) = ' ';
*(dstP++) = *(srcP++) ^ 0x80;
}
}
「Programmer's Companion for Sony CLIE」のサンプルプログラムをそのまま使用可能です。
以下のようにアプリケーションのdbIDを獲得してSysNotifyUnregister()を呼んでやるだけです。
err = DmGetNextDatabaseByTypeCreator(true, &state, 'appl', appFileCreator, true, &cardNo, &dbID); if (!err) SysNotifyUnregister(cardNo, dbID, sysNotifyDisplayChangeEvent, sysNotifyNormalPriority);
通常使ってない(と思う)PalmMainの第二引数がSysNotifyParamTypeへのポインタとなっています。 Wdicでは手抜きしてここからすぐにFrmGotoForm()を呼んでしまってますが、 本当は画面のサイズが変わったかを調べて、 変わっていたら各フォームの再描画関数を呼ぶというふうにした方がよいはずです。
static UInt32 StarterPalmMain(UInt16 cmd, SysNotifyParamType *notifyP, UInt16 launchFlags)
{
switch (cmd) {
case sysAppLaunchCmdNormalLaunch:
error = AppStart();
if (error)
return error;
FrmGotoForm(MainForm);
AppEventLoop();
AppStop();
break;
case sysAppLaunchCmdNotify:
if (notifyP->notifyType != sysNotifyDisplayChangeEvent)
break;
formID = FrmGetActiveFormID();
if (formID)
FrmGotoForm(formID);
break;
}
WinGetDisplayExtent(NULL, &CurWinExtent);
void ClieSetWindowBounds(FormType *frmP, Coord extent)
{
WinHandle win;
RectangleType r;
Coord diff = extent - defaultDisplayExtent;
// extent form
win = FrmGetWindowHandle(frmP);
win = WinSetDrawWindow(win);
WinGetDrawWindowBounds(&r);
r.extent.y += diff;
WinSetWindowBounds(win, &r);
}
void ClieChangeObjectBounds(FormType *frmP, Int16 objID,
Coord extent, ClieChangeEnum type)
{
RectangleType r;
Coord diff = extent - defaultDisplayExtent;
Int16 index = FrmGetObjectIndex(frmP, objID);
FrmGetObjectBounds(frmP, index, &r);
if (type == clieChangeTop)
r.topLeft.y += diff;
else
r.extent.y += diff;
FrmSetObjectBounds(frmP, index, &r);
}
  Handspringの開発ホームページからダウンロード(登録が必要)できる「Developer Reference Guide: Handspring Treo 600 Communicator」に5-way Rockerについての記述がありますが、非常に厄介に見えます。
if (FtrGet(hsFtrCreator, hsFtrIDNavigationSupported, &version) == errNone) {
hasFiveWayRocker = true;
}
以下はその例です。 ソートはメモ帳を呼び出した時に行われるので考える必要はありません (Preferenceでレコード数を管理しており、レコードが追加された場合にソートしている)。
#define memoDBType 'DATA'
#define memoMaxLength 4096
static Err CopyToMemoPad(Char *note)
{
UInt16 index;
MemHandle memoRec;
Char *dstP;
UInt16 attr;
DmOpenRef memoDB;
UInt32 size;
memoDB = DmOpenDatabaseByTypeCreator(memoDBType, sysFileCMemo, dmModeReadWrite);
if (!memoDB) {
FrmCustomAlert(InformationAlert,
"メモ帳データベースのオープンに失敗しました", NULL, NULL);
return errNone;
}
size = StrLen(note);
if (size > memoMaxLength) {
if (FrmCustomAlert(ConfirmationAlert, "データが4096文字以上です。\n",
"4096文字以上は切り捨てられますがよろしいですか?", NULL)) {
DmCloseDatabase(memoDB);
return errNone;
}
size = memoMaxLength;
}
index = DmNumRecords(memoDB);
memoRec = DmNewRecord(memoDB, &index, size);
// If the allocate failed, display a warning.
if (!memoRec) {
ErrorMessage("データベースメモリの確保に失敗しました(%d bytes)", size);
DmCloseDatabase(memoDB);
return dmErrMemError;
}
dstP = MemHandleLock (memoRec);
DmWrite(dstP, 0, note, size);
MemHandleUnlock(memoRec);
// Set the category of the new record to the current category.
DmRecordInfo (memoDB, index, &attr, NULL, NULL);
attr &= ~dmRecAttrCategoryMask;
DmSetRecordInfo (memoDB, index, &attr, NULL);
DmReleaseRecord (memoDB, index, true);
DmCloseDatabase(memoDB);
return errNone;
}