トップ 新規 編集 差分 一覧 ソース 検索 ヘルプ RSS ログイン

ChannelExtensionPluginAPI仕様

ChannelExtensionPlugin概要編集

ChannelExtensionPluginとは、Heimdallrインストールフォルダ\plugin以下にあるDLLファイルのうち、チャンネルに関する機能を提供するDLLファイルのことです。
1.08alpha4時点では、KeywordChannel.dllとTopicChannel.dllがChannelExtensionPluginにあたります。

ChannelExtensionPluginの目指すところ編集

Webサービス、つまりサーバサイドアプリケーションでは真似のできないPlugin、というのを目指すべきだと思っています。

ChannelExtensionPluginAPI編集

ChannelExtensionPluginAPIとは、DLLとHeimdallrのインターフェースのことです。

見た方が早いですね。
こんなAPIです。

typedef BOOL (__stdcall *APP_GET_INFO)(BSTR strRequest, BSTR* pstrResponse);
BOOL __stdcall PluginGetInfo(BSTR* pstrInfo);
BOOL __stdcall PluginInit(APP_GET_INFO pAppGetInfo);
BOOL __stdcall PluginCreateChannel(HWND hWnd, BSTR strSourceId, BSTR strTemporaryId);
void __stdcall PluginDeleteChannel(BSTR strId);
void __stdcall PluginSetPermanentId(BSTR strTemporaryId, BSTR strId);
BOOL __stdcall PluginGetChannel(BSTR strId, BSTR* pstrOutput);
BOOL __stdcall PluginStoreChannelInfo(BSTR strId, BSTR* pstrInfo);
BOOL __stdcall PluginLoadChannelInfo(BSTR strId, BSTR strInfo);

こんな感じの関数を備えたDLLをpluginフォルダに置いておくと、
Heimdallrが起動時にそのDLLにアクセスし、ChannelExtensionPluginとして扱う訳です。

上記APIはC言語風ですが、DLLなので、もちろんC言語以外でも作れます。
C言語以外を使うときは、上記インターフェースをその言語に合わせて変えて下さい。

さて、もちろんこれだけの情報ではPluginを作れません。
これらの関数の役割はなにか、どのような処理を行えばいいのか、そうした情報が必要ですが・・・。長い目で、お待ち下さい。

とりあえず1.08の安定版が出せたらキーワードチャンネルのソースコードは公開する予定です。参考にはなると思われます。

概念編集

概念的なものを幾つか説明します。

チャンネル編集

チャンネルは、RSS Feedのchannel要素のように、複数の記事(item)を管理するものです。

プラグインは、複数のチャンネルを管理します。
例えば、
ユーザがHeimdallrのビュー設定ダイアログからキーワードチャンネルを追加し、
キーワードを「猫」とします。これで、チャンネルが1つ作成されます。
さらにキーワードチャンネルを追加し、
キーワードを「犬」とします。これでさらにチャンネルが1つ作成されます。

以上の操作によりチャンネルが2つ作成されますが、どちらもキーワードチャンネルのDLLが管理します。

そして、
これらのチャンネルは、IDにより区別されます。
例えば、キーワードが「猫」のチャンネルのIDは"AAAA"となり、「犬」のチャンネルのIDは"BBBB"となります。

ID編集

IDはチャンネルを識別するための文字列です。
Heimdallrが生成してプラグインに渡すので、プラグイン内部で生成する必要はありません。
但し、Heimdallrは、プラグインに対し、IDを指定して様々な要求を行うので、
プラグイン内部でIDを保持しておく必要はあります。

IDには2種類あります。テンポラリIDとパーマネントIDです。
テンポラリIDは一時的なものです。ビュー設定ダイアログでユーザがチャンネルを追加したときは、そのチャンネルのIDはテンポラリIDです。
ビュー設定ダイアログのOKボタンを押してそのチャンネルを追加することが確定したとき、テンポラリIDとは別に新しくパーマネントIDが割り当てられます。
一度パーマネントIDが割り当てられたら、その後別のIDが割り当てられることはありません。

チャンネルの処理の流れ編集

PluginGetInfoとPluginInitはチャンネルとは関係が無い関数なので、これらの呼び出しは省略します。

ビュー設定からチャンネルを追加→しばらく放っておく→Heimdallr終了、
という操作をユーザが行った場合、以下の順番で関数が呼び出されます。

  1. ビュー設定からチャンネルを追加したとき、PluginCreateChannel
  2. 続けてチャンネルのタイトルを取得するために、PluginGetChannel
  3. ビュー設定のOKボタンを押したとき、PluginSetPermanentId
  4. 最新の情報に更新する度、PluginGetChannel
  5. Heimdallr終了時に、PluginStoreChannelInfo

既にチャンネルが追加されている状態で、
Heimdallr起動→しばらく放っておく→Heimdallr終了、
という操作をユーザが行った場合、以下の順番で関数が呼び出されます。

  1. Heimdallr起動時に、PluginLoadChannelInfo
  2. 最新の情報に更新する度、PluginGetChannel
  3. Heimdallr終了時に、PluginStoreChannelInfo

API仕様詳細編集

PluginGetInfo編集

このプラグインの情報を取得するための関数です。
一番最初にHeimdallrから呼び出されます。

BSTR* pstrInfo
プラグインの情報をHeimdallrに返すための引数です。プラグイン側でSysAllocStringを呼び出して領域を確保し、そこにプラグインの情報を格納してHeimdallrに返します。
戻り値
成功した場合はTRUEを返し、失敗した場合はFALSEを返します。FALSEを返すと、Heimdallrはプラグインを無視します。

注意編集

TRUEを返す場合は、pstrInfoが示す領域に必ず値を格納して下さい。
FALSEを返す場合は、pstrInfoが示す領域に値を格納してはいけません。

補足編集

pstrInfoに格納する文字列の例を示します。

<Plugin 
class="http://www.sutosoft.com/applications/heimdallr/plugin/classes/channelextension" 
id="http://www.sutosoft.com/applications/heimdallr/plugin/id/keywordchannel">
  <Name>キーワードチャンネル</Name>
  <Productor>http://www.sutosoft.com/room/</Productor>
  <Copyright>(C) SutoSoft</Copyright>
  <Version>0.03</Version>
</Plugin>

重要なのは、Plugin要素のclass属性とid属性とName要素です。あとはおまけです。

Plugin要素のclass属性は、必ず

http://www.sutosoft.com/applications/heimdallr/plugin/classes/channelextension

として下さい。

Plugin要素のid属性は、他のPluginと重ならない文字列にして下さい。
本例の文字列はキーワードチャンネルが使っているので他のプラグインでは使えません。

Name要素は、ユーザがビュー設定ダイアログからチャンネルを追加するときに表示されますので、慎重に決めて下さい。

PluginInit編集

プラグインを初期化するための関数です。
特に何もする必要が無ければそのままTRUEを返しましょう。

APP_GET_INFO pAppGetInfo
関数ポインタです。これを使うことにより、Heimdallrと色々な情報をやり取りできます。
戻り値
成功した場合はTRUEを返し、失敗した場合はFALSEを返します。FALSEを返すと、Heimdallrはプラグインを無視します。

補足編集

pAppGetInfoは、使わなくてもそれなりのプラグインは作れます。
例えば、キーワードチャンネルはこれをまったく使っていません。

PluginCreateChannel編集

チャンネルを作成するために呼び出される関数です。
Heimdallrのビュー設定ダイアログからチャンネルの追加を行ったときと、
サイトの変更を行ったときにも呼び出されます。
この関数内でダイアログを表示し、チャンネルの設定を行うべきです。

HWND hWnd
この関数内でダイアログを表示するとき、そのダイアログの親ウィンドウとなるべきウィンドウハンドルです。
BSTR strSourceId
NULLあるいは有効な値が格納されています。チャンネルの追加を行った場合はNULL、サイトの変更を行ったときは変更前のチャンネルのIDが格納されています。
BSTR strTemporaryId
作成されるチャンネルのテンポラリIDです。大事に保存して下さい。
戻り値
成功したときはTRUEを返し、失敗したときはFALSEを返します。チャンネルの作成をキャンセルする場合はFALSEを返しましょう。

PluginDeleteChannel編集

チャンネルを削除するために呼び出されます。

BSTR strId
チャンネルのIDです。

PluginSetPermanentId編集

テンポラリIDを持ったチャンネルに対しパーマネントIDを与えるために呼び出されます。
ユーザがビュー設定ダイアログのOKボタンを押したときに呼び出されます。

BSTR strTemporaryId
チャンネルのID(テンポラリID)
BSTR strId
チャンネルに与えられるパーマネントID

PluginGetChannel編集

Heimdallrのビューに表示する記事のタイトルや概要を取得するために呼び出されます。
この関数がチャンネル拡張プラグインの中核になるはずです。

BSTR strId
チャンネルのIDです。
BSTR* pstrOutput
記事のタイトルや概要をHeimdallrに返すための引数です。プラグイン側でSysAllocStringを呼び出して領域を確保し、そこにRSS 1.0仕様に準拠した文字列を格納してHeimdallrに返します。エラーが発生した場合は、RSS1.0仕様に準拠した文字列の替わりにエラー要因を表す文字列を格納します。但しエラー要因については仕様が固まっておりませんので任意の文字列を入れて下さい。
戻り値
成功した場合はTRUEを返し、失敗した場合はFALSEを返します。

注意編集

TRUEを返す場合も、FALSEを返す場合も、pstrOutputが示す領域に必ず値を格納して下さい。

補足編集

エラー要因としては任意の文字列を入れて下さい。
"Error"でも良いですし、"Hoge"でも良いです。

RSS 1.0に準拠した文字列の例を以下に示します。
とりあえず本関数を動かしたい方はこれを使って下さい。

<?xml version="1.0" encoding="utf-8" ?>
<rdf:RDF
  xmlns="http://purl.org/rss/1.0/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xml:lang="ja">
  <channel rdf:about="http://www.example.com/">
    <title>チャンネルタイトル</title>
    <link>http://www.example.com/</link>
    <description>テスト用</description>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://www.example.com/item1.html"/>
      </rdf:Seq>
    </items>
  </channel>
  <item rdf:about="http://www.example.com/item1.html">
    <title>タイトル</title>
    <link>http://www.example.com/item1.html</link>
    <description>概要</description>
  </item>
</rdf:RDF>

PluginStoreChannelInfo編集

Heimdallr終了時に、プラグインの内部情報をファイルに保存するために呼び出されます。
ファイルのオープンなどを行うのはHeimdallrです。プラグイン側は、ファイルに保存する文字列をHeimdallrに返します。
本関数がHeimdallrに返した文字列は、次にHeimdallrを起動したときに呼び出されるPluginLoadChannelInfoの引数に渡されます。

BSTR strId
チャンネルのIDです。必ずパーマネントIDです。
BSTR* pstrInfo
プラグインの内部情報を文字列としてHeimdallrに返すための引数です。プラグイン側でSysAllocStringを呼び出して領域を確保し、そこに文字列を格納してHeimdallrに返します。
戻り値
成功した場合はTRUEを返し、失敗した場合はFALSEを返します。

注意編集

TRUEを返す場合は、pstrInfoが示す領域に必ず値を格納して下さい。
FALSEを返す場合は、pstrInfoが示す領域に値を格納してはいけません。

補足編集

pstrInfoに設定する文字列の形式は任意です。
しかし、Heimdallrの都合により、文字列の前後に空白があった場合、その空白が削られて保存される可能性があります。
文字列の保存先はsite.xmlファイルです。
どんな風に保存されるか知りたい方は、キーワードチャンネルを追加した後、Heimdallrを終了し、site.xmlを見てみて下さい。キーワードチャンネルの内部情報(結構大きいですが)が記録されていることが分かると思います。

文字列の形式は任意と書きましたが、一応以下の2つの形式を想定しています。何を使うか迷ったときは参考にして下さい。

XML形式
チャンネルの内部情報をXML形式の文字列としたものです。キーワードチャンネルもトピックチャンネルも内部情報をXML形式で記録しています。
BASE64形式
チャンネルの内部情報をBASE64エンコードして文字列に変換したものです。

PluginLoadChannelInfo編集

後で書きます

同期制御編集

Heimdallrは、本仕様に示す関数を呼び出した後、それが制御をHeimdallrに返す前に、他の関数を呼び出すこと、つまり非同期呼び出しを行う場合があります。
例えば、PluginGetChannelの実行中に、同じIDを指定してPluginDeleteChannelを呼び出す場合があります。
と言っても、ありとあらゆる関数を非同期に呼び出すわけではありません。
例えば、PluginGetChannelの実行中に、同じIDを指定してPluginGetChannelを呼び出すことはありません。また、PluginLoadChannelInfoの実行中は、他の関数は呼び出されません。

ここでは、関数毎に、その関数の実行中に呼び出される可能性のある他の関数を定義します。

こうした同期制御は、プラグインの開発をとても複雑にします。
しかし、その見返りとして、ユーザに軽快な使用感を与えます。
気合を入れて実装しましょう。(?)

PluginGetInfo編集

本関数実行中に、他の関数が呼び出されることはありません。

PluginInit編集

本関数実行中に、他の関数が呼び出されることはありません。

PluginCreateChannel編集

あとで書きます。

PluginDeleteChannel編集

あとで書きます。

PluginSetPermanentId編集

あとで書きます。

PluginGetChannel編集

あとで書きます。
たぶんここが一番複雑。

PluginStoreChannelInfo編集

あとで書きます。

PluginLoadChannelInfo編集

本関数実行中に、他の関数が呼び出されることはありません。

プラグインの作り方編集

最初に、全ての関数をエクスポートしましょう。

次に、
PluginGetInfo
PluginInit
の2つの関数を実装します。
これにより、Heimdallrはプラグインの存在を認識します。

次に、
えーと・・・
どうましょう。

お名前: コメント:
GooBlog.lzh HeimDLL_Src.lzh

この文章へのトラックバックはTrackback(0) です。




最終更新時間:2005年03月23日 14時35分35秒

bfl@w.sakage.ccには絶対にメールを送信しないでください。