Tech Note 27: NS Basic/Palm を Microsoft .NET と共に使う Part 1

September 18, 2003


[本稿はRobert Chartier氏が15seconds.comに書かれた記事を翻訳したものです]

概略

このシリーズの最初のパートは、Blogを管理する実際のPalmアプリケーションを作る行程です。アプリケーションの機能、ユーザーインターフェース、操作性に重点が置かれています。メニューシステム、ポップアップ、ボタンや他のユーザーインターフェースの作り方、及びデータベースの作成と編集を行う一般的なシンタックスが学べます。

アプリケーションの目的

このアプリケーションの目的は、Web Log (blog) 項目を作成し編集することです。blogが何か良く分からない人はhttp://www.webopedia.com/TERM/b/blog.htmlhttp://www.hotwired.co.jp/news/news/culture/story/3780.htmlを参考にして下さい。Microsoft Community (.NET) の良く知られるblogサイトの1つはhttp://weblogs.asp.net/です(私のパブリックblogも含まれていますhttp://weblogs.asp.net/rchartier)。

アプリケーションを開発する前に、計画を練ることが常に大事です。最初に、必要な機能と理想的な機能を全て挙げてみます。「理想的」なものとは、あったらいいなと思うもので、「必要」なものとは、なくてはならないものです。

以下は我々のアプリケーションの「必要」と「理想的」のリストです。

必要:

  1. 現在のblog項目をリストにする
  2. blog項目を追加/編集/消去する
       a. サブジェクトライン
       b. 日付/時刻
       c. 項目
       d. アップロード設定
  3. アップロード設定をリストにする
  4. アップロード設定を追加/編集/消去する
  5. WebLogApi* をサポートする

理想的:

  1. blog項目をソート/フィルターする
  2. FTP, HTTPアップロードをサポートする
  3. WebLogApiを通してカテゴリーを引き出し、項目をこれらのカテゴリーにソート/クラス分けする

*WebLogApi: WebLogApi は、アプリケーションとblogsの融合を目的とした取り組みです。詳細はこちらをご覧下さい(英語)。 http://www.xmlrpc.com/discuss/msgReader$2198.

「必要」は本稿のサンプルアプリケーションとしては、十分すぎる必須リストのように見えます。「理想的」は時間がある時に実装されると良いでしょう。

Palmアプリケーションを作るために、手に入る全てのツールを調べた結果、私はNS Basic (http://www.nsbasic.com/palm/)を選びました。私は素早く市場に出すことを考え、多くのC言語を基本にしたツール(http://www.metrowerks.com/products/palm/, http://www.orbworks.com/pcpalm/download.html)には悲観的です。C言語を基本にしたツールを使いたい場合やC言語を使ってPalmアプリケーションを作りたい場合、この記事はお薦めしません。

Visual Basic IDEおよびプログラミング言語に精通している場合、非常に短期間でNS Basicを学んで使うことができます。次のセクションでは、Palmエミュレータを使った我々の進捗をテストする環境を整えます。

テスト環境をセットアップする

まず最初にNS Basicのデモ版(http://www.nsbasic.com/palm/Japanese/demo.html)とPalmエミュレータ(http://www.palmsource.com/jp/dev/tools/emulator/)をダウンロードします。次にあなたのデバイス用にROMイメージを取得する必要があります。設定につきましては、エミュレータのページに説明があります。

NS Basicのダウンロードとインストールが済み、エミュレータをセットして動作したら、NS BasicのRumtimeをエミュレータに同期します。NS Basicのデフォルトインストールを選んだ場合、NSBRuntime.prcがC:\NSBasic\Download\ディレクトリに入っているはずです。このPRCファイルをエミュレータの上にドラッグして離して下さい。このRuntimeとは、全てのNS Basicアプリケーションが必要とする、繰り返し使うライブラリ(メソッドや定数等を集めたパッケージ)だと思って下さい。ですから、あなたのPalmデバイスにも必要となります。また、NS BasicアプリケーションはRuntimeの要素だけに制限されているわけではなく、容易にPalmデバイス上の他のシステム関数やCライブラリを呼ぶことができます。

時々、NS Basicを起動する時、ユーザーインターフェースが現れません。もしこれが起こったら、Task Managerを開き、プロセスを殺してから再度起動して下さい。通常は2回以上は起こりません。また、NS BasicからPalmデバイスへの同期中は、ダイアログの内容に注意を払って下さい。 「リセットが完了したらOKをクリックしてください。」のメッセージが現れたら、リセットが終了するまで必ず待つようにして下さい。これを怠ると、エミュレータがハングしますので、エミュレータを殺し、再起動し、Runtimeを同期しなおす必要があります。プロジェクトを頻繁に保存することを忘れないで下さい。

次のセクションでは、「必要」を実際のアプリケーションに作り上げていきます。

スクリーンレイアウトと操作性

我々のアプリケーションが起動した時、データベースに持っている全てのblog項目をリストにするとことから始めます。これによって、ユーザーは、どの項目を既に作ってあって、どれが編集または消去できるかの判断が簡単にできます。Figure 1 の左上のフォームを見ると、アイテムのリスト、ボタン、およびポップアップリストがあります。ここで、NS Basicの新しいプロジェクトを作り、最初のフォームにこれらのオブジェクトを配置してみましょう。現時点では、実際のコードに関しては、あまり気にしないで下さい。それらは次のセクションで行います。


Figure 1 アプリケーションのフォーム

ユーザーが"Manage Blogs"スクリーン上のリストのアイテムを選ぶと、 "Edit Blog"スクリーンへ移り、そのアイテムが表示されます。ユーザーが"New"ボタンをタップした場合は、"Edit Blog"スクリーンへ移りますが、フォームは空欄です。ここで新しく"Edit Blog"フォームをプロジェクトへ追加し、全てのボタン、ラベル、フォールド、ポップアップを配置しましょう。

最後の2つのスクリーンは設定用です。これを使ってユーザーは、どのサイト(およびユーザー名、パスワード等)に項目をアップロードするかをアプリケーションに伝えます。ご覧になって分かる通り、有効な設定のリスト、及び個別の設定アイテムの作成、編集、消去の機能が必要になります。この2つのフォームが完成したら、次のセクションへ進みます。次のセクションでは、実際にフォームアイテムを機能させるためのコードを書き、さらにデータベースを作ります。

実際にコードを書く前に、ここで"Creator ID"に関して簡単な説明をしたいと思います。NS BasicのIDE上で、プロジェクトエクスプローラのツリーの一番上のレベルをクリックすると、プロジェクトのプロパティーを見ることができます。プロパティーウィンドウでは、Creator IDを入力することができます。これはあなたのPalmアプリケーションとデータベースが持つことができる特有の識別記号です。これは、シリーズの次のパートで説明する、アプリケーションがデスクトップと同期してデータをやり取りする際に、もっとハッキリと分かるでしょう。今回のアプリケーションでは、私は"PBlg"(大文字/小文字は重要)をCreator IDに選びました。このアプリケーションそのものと、それに使われるデータは"PBlg"として認識されます。詳細はPalmの開発者サイト(http://dev.palmos.com/creatorid/)をご覧下さい。

コーディング

ユーザー定義のデータタイプ - User Defined Types (UDTs):

どんなアプリケーションを開発する時でも、わたしはデータが保管され形成される構造の作成から始めるのが好きです。NS Basicでは、簡単にUDTを使うことができます。基本的には、これは定義、インスタンスの生成、削除ができるクラスやカスタムタイプのミニチュア版だと思ってもらえれば結構です。 この前のセクションをしっかり理解して頂いていると、最低2つのUDTが作れることが直ぐに理解できると思います。1つは実際のblogの項目を保管するものと、もう1つはblog設定を保管するものです。下のFingure 2はBlogEntryとBlogSettingの2つのUDTです。


Type BlogEntry
    subject as String 'subject of the entry
    dDate as String  'date of the entry
    entry as String  'the actual full text entry
    settingsName as String 'matching settings name
End Type

Type BlogSetting
    Name as String  'name of the setting, key
    isDefault as Integer 'if this is the default setting
    sType as Integer    'type of setting it is
    username as String 'username to use during auth
    password as String 'password to use during auth
    port as Integer 'what port is the remote service running on
    domain as String 'what domain/ip is the remote server
    path as String 'file path to the save location
    filename as String 'ftp file name, 
                        'http variable post name For xml upload
                        'or url end point
End Type

Figure 2 UDTs

これらのUDTはプロジェクトのStartup Codeに入れます。これによって、プロジェクトのどこからでもこれらのUDTにアクセスすることが保証されます。Startup Codeを開くには、プロジェクトエクスプローラ中のプロジェクトを右クリックし、「Startup Codeを表示」を選びます。 私はこれらのUDTを既に定義されている"sub main()"の上に作りました。後でさらにこれらのUDTに触れます。

では、"sub main()"プロシージャに移りましょう。全てのアプリケーションがそうであるように、初期スタートポイントが必要です。NS Basicアプリケーションでは、"sub main()"プロシージャがそれです。

データベース:

このアプリケーションでは、データベースIOを非常に単純にしたいため、あるスコープ・ルールを無視しています。このプロジェクトでは2つのデータベースを使うことに決めました。既にアプリケーション用にグローバルで定義しましたが、1つはすべてのblog項目を保管し、もう1つは全てのblog設定を保管するものです。あなたのアプリケーションでは、必要な時だけデータベースを作成し開くようにしたいと思うかもしれませんが、私がこのやり方をするのは、アプリケーションを通してデータベースを作ったり開いたりする煩わしさを取りたいからです。Figure 3は2つのグローバル データベース変数の作り方を示しています。


Global blogdb as Database
Global settingsDB as Database

Figure 3 グローバルデータベースの作成

2つのデータベース変数を持ちましたので、データベースが実際に作られたのか調べてみましょう。作られていない場合は、作って下さい。データベースを開くと、アプリケーションで利用可能になります。Figure 4はblog設定データベースを、Figure 5はblog項目データベースを開くプロセスです。


res = dbopen(settingsDB, "blogSettings", 0)
If(res<>0) Then
    MsgBox "You have not created any local settings. Nothing will be uploaded until you do so."
    res = dbcreate(settingsDB, "blogSettings", 0, "PBlg")
    res = dbopen(settingsDB, "blogSettings", 0)
    jumptoSettings=1
End If

Figure 4: Blog設定データベースを開く

'open up the blogdb, else create a new one
res = dbopen(blogdb, "blogdb", 0)
If(res<>0) Then
    MsgBox "Default Database not found, creating a new one..."
    'failed, so we create a new one
    res = dbcreate(blogdb, "blogdb", 0, "PBlg")
    If(res<>0) Then 
        appActive=0
        MsgBox "Error creating/opening Database. " + str(res)
    Else
        res = dbopen(blogdb, "blogdb", 0)
        If(res<>0) Then 
            MsgBox "Error creating/opening Database. " + str(res)
        Else            
            Dim newEntry as BlogEntry
            newEntry.Subject="Welcome..."
            newEntry.dDate = DateMMDDYY(Today()) + " " + HourMinAMPM(now())
            newEntry.Entry="Welcome to the Palm Blog, Written by Robert Chartier (rob© santra.com)"    
            res=dbinsert (blogdb,newEntry.Subject,newEntry)
        End If    
    End If
End If

Figure 5 Blog項目データベースを開く

どちらのコードも dbopen() メソッドを呼んでいることに気がつくと思います。このメソッドは、NS BasicのRuntimeの中で定義されています。3つのパラメータを伴っていますが、最初の変数はデータベースのインスタンスを納めるために使われます。2番目はPalmデバイスの内部にあるデータベース名です。最後のパラメータは、データベースが保管されているカード番号です。もしあなたのデバイスが複数のカードを持っている場合は、これが有効に使えるかもしれません。このメソッドを呼ぶと、結果が返ってきます。結果が0の場合、データベースは問題なく開いたことを意味します。その他の結果はエラーを意味します。データベースが存在しない場合は、dbcreate()を使って作成します。Figure 6は全てのデータベース結果コードです。

 -1 DbGet実行時のEOF(End Of File)  
  0 オペレーション成功
  1 オペレーション失敗
  2 キーが見つからない  - 次に大きいキーが返還
  3 ファイルは読込みモードで開いている
513 メモリーエラー
514 インデックスが範囲外
515 無効パラメータ
516 読込みモード
517 データベースが開いている
518 開けない
519 見つからない
520 間違ったカードへの記録
521 不正なデータベース
522 レコードは削除されている
523 レコードは保管されている
524 レコード・データベースではない
525 リソース・データベースではない
526 ROMを基にしているか無効なデータベース名
527 レコード使用中
528 リソースが見つからない
529 開いているデータベースがない
530 無効なカテゴリー
531 有効なレコードでない
532 範囲外への書込み
533 検索の失敗
534 書込みモードで既に開いている
535 別のタスクによって開いている
536 ユニーク(特有な)IDが見つからない
537 既に存在する
538 無効なデータベース名
539 データベースがプロテクトされている
540 データベースがプロテクトされていない
Figure 6 データベース結果コード

dbCreate()を呼ぶ時、Creator IDを渡しているのに気付くと思います。これによって、同期プロセスをしている間に、データの確保ができます。

ではここで、上のコードにあるデータベースの他のコマンドも探究してみて下さい。Figure 7は各コマンドの概略です。

DbClose				開いているデータベースを閉じる
DbCreate			Palm OS デバイス上にデータベースを作成
DbCreateDatabasefromResource	プロジェクトに含まれるリソースからデータベースを作成。 
DbDelete			キー によってデータベースのレコードを削除
DbErase				Palm OSデバイスからデータベースを消去
DbFind				キー によってデータベースのレコードを探す
DbGet				データベースの現レコードから変数の値を読む
DbGetNoRecs			データベースのレコード数を戻す
DbInsert			キーを使用して新しいレコードをデータベースに挿入
DbOpen				処理を始める前にデータベースを開き初期化する
DbPosition			レコード番号によってレコードを位置する
DbPut				データベースの現レコードの変数に値を書く
DdbRea				キーを使用してデータベースのレコードを読む
DbReadNext			次のレコードを読む
DbReadPrev			一つ前のレコードを読む
DbReset				データベースを最初のレコードにリセット
DbUpdate			キーを使用してレコードの内容を更新
Figure 7: データベース コマンド

Startup Code:

データベースを作り、開いたら、sub main()プロシージャを正常に終らせ、デフォルトフォームを読込むようにします。"Startup Code"セクションの残りのコードも、理解しておくと良いでしょう。フォーム上のリストをアップデートするための、いくつかの便利なメソッドがあります。例えば、UDTの値を文字列に変換する等です。Figure 8は、完全な"Startup Code"セクションです。


Type BlogEntry
    subject as String 'subject of the entry
    dDate as String  'date of the entry
    entry as String  'the actuall full text entry
    settingsName as String 'matching settings name
End Type

Type BlogSetting
    Name as String  'name of the setting, key
    isDefault as Integer 'if this is the default setting
    sType as Integer    'type of setting it is
    username as String 'username to use during auth
    password as String 'password to use during auth
    port as Integer 'what port is the remote service running on
    domain as String 'what domain/ip is the remote server
    path as String 'file path to the save location
    filename as String 'ftp file name, 
                        'http variable post name For xml upload
                        'or url end point
End Type

Type sTypes
    WebLogApi as Integer
    Ftp as Integer
    Http as Integer
End Type



Sub main()

Global SettingTypes as sTypes
SettingTypes.WebLogApi=0
SettingTypes.Ftp=1
SettingTypes.Http=2

Dim jumptoSettings as Integer
jumptoSettings=0
Global blogdb as Database
Global settingsDB as Database

Global appActive as Integer
Global editID as String
editID=""
appActive=1

Dim res as Integer

res = dbopen(settingsDB, "blogSettings", 0)
If(res<>0) Then
    MsgBox "You have not created any local settings. Nothing will be uploaded until you do so."
    res = dbcreate(settingsDB, "blogSettings", 0, "PBlg")
    res = dbopen(settingsDB, "blogSettings", 0)
    jumptoSettings=1
End If

    
'open up the blogdb, else create a new one
res = dbopen(blogdb, "blogdb", 0)
If(res<>0) Then
    MsgBox "Default Database not found, creating a new one..."
    'failed, so we create a new one
    res = dbcreate(blogdb, "blogdb", 0, "PBlg")
    If(res<>0) Then 
        appActive=0
        MsgBox "Error creating/opening Datbase. " + str(res)
    Else
        res = dbopen(blogdb, "blogdb", 0)
        If(res<>0) Then 
            MsgBox "Error creating/opening Datbase. " + str(res)
        Else            
            Dim newEntry as BlogEntry
            newEntry.Subject="Welcome..."
            newEntry.dDate = DateMMDDYY(Today()) + " " + HourMinAMPM(now())
            newEntry.Entry="Welcome to the Palm Blog, Written by Robert Chartier (rob© santra.com)"    
            res=dbinsert (blogdb,newEntry.Subject,newEntry)
        End If    
    End If
End If    
If(appActive=1) Then
    Call UpdateList()
End If
    
If(jumptoSettings=1) Then NextForm "SettingsForm"
    
End Sub

Sub UpdateSettingsList()
        Dim x as Integer
        Dim res as Integer
        Dim key as String
        res =  dbReset(settingsDB)

        SettingsList.clear
        
        For x = 1 to dbGetNoRecs(settingsDB) 
           Dim existingEntry as BlogSetting
            res = DbReadNext(settingsDB, key, existingEntry)       
            If (res = 0) Then                
                SettingsList.add existingEntry.name  + " ("+GetTypeText(existingEntry.sType)+")"
            Else 
                MsgBox "err:" + str(x)
            End If            
        Next
End Sub

Sub UpdateSettingsListInEntry()
        Dim x as Integer
        Dim res as Integer
        Dim key as String
        res =  dbReset(settingsDB)

        SettingsPopup.clear
        
        For x = 1 to dbGetNoRecs(settingsDB) 
           Dim existingEntry as BlogSetting
            res = DbReadNext(settingsDB, key, existingEntry)       
            If (res = 0) Then                
                SettingsPopup.add existingEntry.name  + " ("+GetTypeText(existingEntry.sType)+")"
            Else 
                MsgBox "err:" + str(x)
            End If            
        Next
End Sub


Sub UpdateList()
        Dim x as Integer
        Dim res as Integer
        Dim key as String
        res =  dbReset(blogdb)

        List1012.clear
        
        For x = 1 to dbGetNoRecs(blogdb) 
           Dim existingEntry as BlogEntry
            res = DbReadNext(blogdb, key, existingEntry)       
            If (res = 0) Then                
                List1012.add existingEntry.subject + " ("+existingEntry.dDate+")"
            Else 
                MsgBox "err:" + str(x)
            End If            
        Next

End Sub

Function GetSelectedSettingsKey() as String
    Dim selectedName as String
    selectedName= SettingsList.text(SettingsList.selected)    
    Dim pos as Integer
    pos = instr(1,selectedName, "(",1 )
    selectedName = left(selectedName, pos-2)
    GetSelectedSettingsKey=selectedName
End Function

Function GetSelectedKey() as String
    Dim selectedName as String
    selectedName= List1012.text(List1012.selected)    
    Dim pos as Integer
    pos = instr(1,selectedName, "(",1 )
    selectedName = left(selectedName, pos-2)
    GetSelectedKey=selectedName
End Function

Function GetTypeText(TheType as Integer) as String
    Select Case TheType
        Case SettingTypes.WebLogApi:
            GetTypeText="WebLogApi"
        Case SettingTypes.Ftp:
            GetTypeText="Ftp"
        Case SettingTypes.Http:
            GetTypeText="Http"
        Case Else:
            GetTypeText=""
    End Select
End Function

Function GetTypeInteger(TheType as String) as Integer
    Select Case lcase(TheType)
        Case "weblogapi":
            GetTypeInteger=SettingTypes.WebLogApi
        Case "ftp":
            GetTypeInteger=SettingTypes.Ftp
        Case "http":
            GetTypeInteger=SettingTypes.Http
        Case Else:
            GetTypeInteger=-1
    End Select
End Function


Sub SelectEditBlogSettingsDrop(name as String)
If(name<>"") Then
    Dim count as Integer
    Dim x as Integer
    Dim pos as Integer
    Dim selectedName as String
    count = SettingsPopup.NoItems
    name = trim(name)
    For x = 0 to count
        selectedName = PullKey(SettingsPopup.ItemText(x))
        If(selectedName=name) Then
            SettingsPopup.Selected = x
            Exit For
        End If
    Next    
End If
End Sub

Function PullKey(selectedName as String) as String
Dim doneName as String
donename=selectedName
Dim pos as Integer
If(selectedName<>"") Then
    pos = instr(1,selectedName, "(",1 )
    If(pos>0) Then
        selectedName = trim(left(selectedName, pos-2))
        pos = instr(1,selectedName, "(",1 )
        doneName=selectedName
    End If
End If
PullKey=doneName
End Function

Figure 8: Startup Code

Manage Blogs フォーム:

このアプリケーションのデフォルトフォームは"Manage Blogs"です。既に見たように、これは"blogdb"データベースから抜き出したアイテムの単なるリストです。リストオブジェクトを右クリックし"View Code"を選ぶと、ユーザーがリストをクリックした時に発生するイベントを捕らえるためのサブルーチンが開きます。Figure 9は、リストの選択されたアイテムを処理するコードです。


Sub object1012()
If(List1012.selected>0) Then
    editID=GetSelectedKey()
    EditBlogForm.Clear
    NextForm "EditBlogForm"
Else
    MsgBox "Select an item to Edit first."
End If
End Sub

Figure 9: リストの選択を処理する

これのほとんどは明瞭だと思います。"GetSelectedKey()"はStartup Codeに入っています。ここではこのコードにある2つのアイテムに注意を払って下さい。1つ目はEditBlogForm.Clearのメンバーコールです。これはフォームに対し、全ての内部アイテムをクリアするように指示します。全てのフィールド、ポップアップ等の表示内容はきれいに消されます。次は"NextForm"コマンドです。これはアプリケーション内の別のフォームに移るように指示しています(名前を渡すだけです)。

 

メニューシステム:

プロジェクトエクスプローラ内のツリーに「メニュー」という項目があります。これを右クリックし、「メニューを追加」を選びます。ここであなたのアプリケーションに使われる、各メニューアイテムを入力し構成することができます。今回のアプリケーションでは、"MainMenu"と呼ばれるメニューシステムを作りました。これは実際のメニューの親になるものだと思って下さい。その中で、"Options"というメニューバーの項目を作り、さらにその下には"Settings"、"About"、"Reset"の3つのメニューを作りました。プロジェクトエクスプローラ内のこれらの各アイテムをダブルクリックすると、そのアイテムが選択された時に呼ばれるコードを作成することができます。

Managed Blogsフォーム(オブジェクトがない部分)を右クリックして「Events Codeを表示」を選ぶと、以下のコードを見ることができます。


Sub Form1004_Event()
  Dim res as Integer
  Dim c as String

  res=getEventType()
  If Not res=nsbKeyOrButton Then Exit Sub   'ignore penup/down events
  c=getKey()

  If c=&h5 Then
     MenuDraw "MainMenu"
     SetEventHandled
  EndIf
End Sub

Figure 10: Managed Blogs イベント ハンドラー、メニュー処理

フォーム上にイベントが発生すると、常にこのコードが実行されます。例えば、ユーザーがフォームをクリックした時や、左上のメニューを選んだ時、またはペン・イベントが起こった時などです。最初にgetEventType()メソッドを見てみます。これは単純に上がってきたイベントの番号を返します。この戻り値を見ることにより、どのイベントが起こったのか、何をしなくてはいけないのかが分かります。"getKey()"メソッドは最後に押されたキーまたはボタンの文字列を返します。Figure 11を見ると、 「シルクスクリーン領域上のメニュー・キー」 の5を捕らえる必要があり、これを捕らえた場合は、"MainMenu"を描画します。そしてシステムに対し、イベントが処理されたことを伝えます。

 1	デバイスの下方にあるボタン#1
 2	デバイスの下方にあるボタン#2
 3	デバイスの下方にあるボタン#3
 4	デバイスの下方にあるボタン#4
 5	シルクスクリーン領域上のメニュー・キー
 6	グラフィティ領域のコマンド
17	シルクスクリーン領域上のアプリケーション起動キー
 7	シルクスクリーン領域上の検索キー
16	シルクスクリーン領域上の計算機キー
11	'Up(上)ボタン
12	'Down(下)ボタン
14	電源(on/off)ボタン
15	クレードルHotsyncボタン
18	自動電源オフ
Figure 11: イベント キー

最後に残ったピースは"New"ボタンです。ボタンをダブルクリックするとイベントを処理するサブルーチンが開きます。Figure 12を見ると、単純にEditフォームをクリアし、そのフォームに移動しています。


Sub object1014()
EditBlogForm.clear
NextForm "EditBlogForm"
End Sub

Figure 12: New ボタン実装

Edit Blog Form:

最後にEdit Blogフォームを見てみます。プロジェクトのその他の部分は、私が行ったことを各自で確認して下さい。このフォームには、いくつかのユーザーが値を入力するフィールド、いくつかのアクションを行うボタン、及び、どの設定を使って項目をアップロードするかを選べるポップアップがあります。このフォームの本当の複雑な部分は各ボタンの裏側にあると言えるでしょう。ですから、そこをじっくり説明します。

"Cancel"ボタンは、 "ManageBlogsForm"に戻る以外は、基本的になんのアクションもとりません。"Delete"ボタンは、表示されている項目のSubjectラインを基に、blogsdbデータベースからそれを削除します。Figure 13は、ボタンイベントを処理するコードです。


Sub object1112()
    Dim key as String
    Dim res as Integer
    Dim be as BlogEntry
    key = SubjectField.Text
    res =  dbReset(blogdb)
    res=dbfind(blogdb, key)
    res=dbread(blogdb, key, be)
    
    If(res=0) Then
        res = dbdelete(blogdb, key)
        If(res=0) Then
            MsgBox key + " has been deleted."
        Else
            MsgBox key + " could not be deleted."
        End If
    Else
        MsgBox key + " could not be deleted."
    End If
res =  dbReset(blogdb)
editid=""

Call UpdateList()
NextForm "ManageBlogsForm"

End Sub

Figure 13: Deleted a Blog Entry

現時点までに知っておくべきことですが、dbResetはデータベースをスターティングポイントへとリセットし、 dbfind()はキーを使って、データベースを検索します。dbreadは、レコードを読んで、UDTに戻します。一般的なエラーを処理し、メッセージを表示するためのコンディションも含まれています。

最後に"Save"ボタンは、フォーム上の項目をわれわれのUDTにはめ込みます。そして、 dbInsert()を呼び、その項目をデータベースへ保存します。Figure 14は、ボタン イベントのハンドラーコードです。


Sub object1023()
If(SubjectField.Text<>"") Then
    Dim newEntry as BlogEntry
    newEntry.Subject=SubjectField.text
    newEntry.dDate = DateField.text
    newEntry.Entry=EntryField.text
    newEntry.settingsName = PullKey(SettingsPopup.ItemText(SettingsPopup.Selected))
    
    Dim newid as String
    Dim res as Integer
    If(editid="") Then
        newid = SubjectField.text
        res=dbinsert(blogdb, newid, newEntry)
    Else
        res=dbdelete(blogdb, editid)
        editid=SubjectField.text
        res = dbinsert(blogdb, editid, newentry)
        res =  dbReset(blogdb)
    End If
    If(res=0) Then
        editid=""
        Call UpdateList()
        MsgBox "Saved"
        NextForm "ManageBlogsForm"
    Else
        MsgBox "Not Saved:" + str(res)
    End If
Else
    MsgBox "You must enter a unique subject"
End If
EditBlogForm.Clear
End Sub

Figure 14: Blog項目を保存

最後に

本稿では、NS Basicを使ってPalmアプリケーションを作るための基本を学んだと思います。シリーズの次のパートでは、同期プロセスを行い、様々なサイトへデータの転送、インポート、アップロードの仕方を説明します。最後のパートでは、Palmアプリケーションとコンジットを配付するためのインストーラの作成です。

参照

NSBasic Reviewers Guide: http://www.nsbasic.com/palm/info/ReviewersGuide.htm
What is a blog? http://www.globeandmail.com/series/dot-com/blog02.html
WebLogAPI: http://www.xmlrpc.com/discuss/msgReader$2198
Palm: http://www.palm.com
Palm Creator ID Information: http://dev.palmos.com/creatorid/