目次


Lotus Notes/Domino のための C API プログラミング

Comments

はじめに

C API for Lotus Notes/Domino を使用した人は、スイス製のアーミーナイフを思い出すかもしれません。ハンディでさまざまな使い方ができる粋なツールセットです。この記事では、Lotus C API for Lotus Notes/Domino の機能に焦点を当て、その高い潜在能力を開発者向けに解説します。Lotus Notes/Domino の基本を理解し、プログラミング言語に慣れているものとして説明を進めます。また、C プログラミング言語の知識があると、説明されている概念の理解に役立ちます。

Lotus C API toolkit を入手する

Lotus C API toolkit for Lotus Notes/Domino は、Toolkits & Drivers ページからダウンロードできます。この記事では、Windows プラットフォームで Lotus Notes/Domino 6.5 用のツールキットを使用することにします。ダウンロードしたアーカイブ・ファイルを展開すると、マニュアル、ヘッダー・ファイル、ライブラリー・ファイル、コンパイル済み OBJ ファイル、サンプル・プログラム、およびサンプルで使用されるデータベースが得られます。

マニュアルはユーザーガイドとリファレンスガイドの 2 つで、どちらも Notes データベース形式で提供されます。マニュアルには多くの情報が含まれています。ユーザーガイドでは、ツールキットを使用してできることと、その方法が説明されています。また、リファレンスガイドには、使用できるすべての関数が記載されています。これらのデータベースに含まれる情報量を考慮すると、素早く正確な検索を行うために、データベースの全文索引を作成しておくとよいでしょう。

通常、ヘッダー・ファイルは Include フォルダーにあります。ヘッダー・ファイルには、ツールキットの一部として利用できるすべての定数、構造体、マクロ、およびパブリック関数の定義が含まれています。プログラム内で使用する API コールに応じて、対応するヘッダー・ファイルをソースにインクルードする必要があります。ライブラリー・ファイルとコンパイル済みの OBJ ファイルは、通常、オペレーティングシステムに固有なフォルダー下の Lib フォルダーにあります。LIB ファイルは、API プログラムをリンクするために必要な DLL インポート・ライブラリーです。OBJ ファイルは、NotesMain エントリー・ポイントを使用するプログラムまたはアドイン・サーバー・タスクに必要なブートストラップ・オブジェクトです (この点については、後で説明します)。

サンプル用のフォルダーには、数多くのサンプル・プログラムがあります。notedata フォルダーには、通常、サンプル・プログラムで使用されるすべてのデータベースがあります。リファレンスガイドに記載されている各関数またはシンボリック値ごとに、少なくとも 1 つのサンプル・プログラムが用意されていて、実際のプログラムでの使用方法を調べることができます。

ツールキットに含まれる内容を確認した後は、実際のプログラムを使用してツールキットへの理解を深めましょう。次のセクションでは、2 つの異なるプログラムを詳しく調べます。

シンプルなプログラムを作成する

まず、Notes データ・ディレクトリーのフルパスを出力するシンプルなプログラムから始めます。最初に、プログラムに必要なヘッダー・ファイルを C ライブラリーからインクルードします。

#include <stdio.h> #include <string.h>

次に、Lotus C API for Lotus Notes/Domino からヘッダー・ファイルを追加します。

#include <global.h> #include <osfile.h>

main 関数です。NotesInitExtended() 関数への呼び出しによって、Notes ランタイムを初期化します。main() の代わりに NotesMain() 関数が使用されていない限り、この呼び出しは明示的に行う必要があります。

int main(int argc, char *argv[])
	{
		char       DataDir[256];		
		STATUS   error = NOERROR;       
		WORD	wlength;				

		if (error = NotesInitExtended (argc, argv))
		{
		  printf("\n Unable to initialize Notes.\n");
		  return (1);
		}

最後に、データ・ディレクトリーを取得し、これを出力します。OSGetDataDirectory() は、このプログラムで使用されるメインの Lotus C API 関数です。名前からわかるように、この関数はデータ・ディレクトリーのフルパスを取得します。最後に、NotesTerm() 関数が Notes ランタイムをシャットダウンします。NotesInitExtended() を使用してランタイムを開始した場合のみ、この関数を明示的に呼び出す必要があります。

wlength = OSGetDataDirectory(DataDir);

		if (wlength > 0)
			printf("\n The data directory is %s", DataDir);


		NotesTerm();
		return (0); 
    }

コンパイルとリンク

次に、書き上げたプログラムをコンパイルし、リンクします。これを行う前に、環境が正しくセットアップされていることを確認する必要があります。最も重要なことは、当然ながら、Lotus Notes とそれに対応するバージョンの Lotus C API toolkit for Lotus Notes/Domino がインストールされていることです。また、Microsoft Visual C++ 開発環境、Microsoft C/C++ コンパイラー、およびそれに付随するライブラリーも必要です。さらに、次に示す 3 つの環境変数をセットアップしなければなりません。

  • PATH 変数の値には、Notes プログラム・ディレクトリーと Microsoft C Compiler が置かれているディレクトリーを追加します。
  • INCLUDE 変数には、Lotus C API インストールの Include ディレクトリーと Microsoft C の Include ディレクトリーを追加します。
  • LIB 変数には、Lotus C API インストールの Windows 32 プラットフォーム用の Lib ディレクトリーと Microsoft C の Lib ディレクトリーを追加します。

環境変数をその場で設定したい場合は、バッチファイルを使用します。バッチファイルの例を示します。

@echo off

rem *** コメント:
rem *** C:\Lotus\Notes は Lotus Notes 6.5 用のプログラム・ディレクトリー。
rem *** C:\Program Files\Microsoft Visual Studio\VC98\ は、
rem *** Microsoft Visual C++ がインストールされているディレクトリー。
rem *** c:\notesapi は Lotus C API for Lotus Notes/Domino 6.5 が
rem *** インストールされているディレクトリー。

set Path=.;C:\Program Files\Microsoft Visual Studio\VC98\bin;
C:\Program Files\Microsoft Visual Studio\VC98\..\Common\MSDEV98\bin;
C:\Program Files\Microsoft Visual Studio\VC98\..\Common\Tools;c:\Lotus\Notes

set LIB=C:\Program Files\Microsoft Visual Studio\VC98\lib;
C:\Program Files\Microsoft Visual Studio\VC98\Platformsdk\Lib;
C:\Program Files\Microsoft Visual Studio\VC98\mfc\lib;C:\notesapi\lib\mswin32

Set INCLUDE=.;C:\Program Files\Microsoft Visual Studio\VC98\PlatformSDK\include;
C:\Program Files\Microsoft Visual Studio\VC98\include;
C:\Program Files\Microsoft Visual Studio\VC98\atl\include;
C:\Program Files\Microsoft Visual Studio\VC98\mfc\include;C:\notesapi\include

nmake ツール

バッチファイルを実行すると、プログラムのコンパイルとリンクを行う準備が整います。ここでは、Microsoft Visual C++ インストールに含まれる nmake ツールがたいへん役に立ちます。このツールに MAK ファイルを与えることで、目的のアプリケーションが作成されます。MAK ファイルによって、デリバラブル (deliverable) とその依存関係 (dependency) が指定されます。また、デリバラブルが存在しない場合 (または、デリバラブルが依存関係よりも古い場合) にデリバラブルをビルドするためのコマンドが指定されます。ここでは、作成したプログラムを simple.c という名前にします。simple.exe のビルドに使用できる MAK ファイルのサンプルを次に示します。

# コメント:
# simple.c 用の MAK ファイル  シンプルな Notes API プログラム

!include <ntwin32.mak>

# このプログラムの名前
PROGNAME = simple

# デリバラブルと依存関係

$(PROGNAME).EXE: $(PROGNAME).OBJ
$(PROGNAME).OBJ: $(PROGNAME).C

# プログラムのコンパイル

.C.OBJ:
    $(cc) $(cdebug) $(cflags) $(cpuflags) /DNT $(cvars) $*.c

# プログラムのリンク
           
.OBJ.EXE:
    $(link) $(linkdebug) $(conflags) -out:$@ $** $(conlibs) \
    	notes.lib user32.lib

nmake ツールで利用できるすべてのオプションを調べるには、nmake -help コマンドを使用します。データ・ディレクトリーを出力する simple.exe プログラムのビルドには、次のコマンドを使用します。

nmake /f simple.mak /a
simple.mak は前に作成した MAK ファイルです。/a オプションは、すべてをビルドすることを示します。

NotesMain() 関数

NotesMain() 関数をエントリー・ポイントとして同じプログラムを書くことができます。唯一の違いは、NotesInitExtended() と NotesTerm() を呼び出す必要がない点です。前の例ではこの 2 つの呼び出しが必要でした。例を示します。

/* Lotus C API for Lotus Notes/Domino で NotesMain() をエントリー・ポイントとして使用し、
データ・ディレクトリーを見つけるシンプルなプログラム */

/* 必要なヘッダー・ファイルを C ライブラリからインクルードする */

#include <stdio.h>
#include <string.h>


/* 必要なヘッダー・ファイルを Lotus C API for Lotus Notes/Domino からインクルードする */

#include <global.h>
#include <osfile.h>

/* このファイルで定義された関数 */

void APIErrHandler (STATUS);

/* The NotesMain() function */

STATUS LNPUBLIC NotesMain(int argc, char far *argv[])
{

	/* ローカル変数 */
	char DataDir[256]; /* Lotus Notes のデータ・ディレクトリー */
	STATUS error = NOERROR; /* Lotus Notes/Domino 用のほとんどの Lotus C API 関数で使用される
    リターン型 - global.h で定義済み */
	WORD	wlength; /* 符号なし整数 - global.h で定義済み */

	/* OSGetDataDirectory() 関数からテキスト・バッファーに返されたデータ・ディレクトリーのフルパスを取得する。
    バッファーのアドレスは引数として渡される。関数の戻り値の長さは、返されたバッファーの長さ。 */

	wlength = OSGetDataDirectory(DataDir);

	/* データ・ディレクトリーのパスを出力する。 */
	if (wlength > 0)
		printf("\n The data directory is %s", DataDir);

	return (NOERROR); 
}

この方法を使用する場合は、MAK ファイルの変更も必要です。前に、ブートストラップ・オブジェクトについて触れたことを覚えているでしょうか。ブートストラップ・オブジェクトが必要となるのは、このような状況です。したがって、このプログラムの MAK ファイルは次のようになります。

# コメント:
# simplever2.c 用の MAK ファイル - NotesMain() を使用するシンプルな Notes API プログラム

!include <ntwin32.mak>

# プログラムの名前
PROGNAME = simplever2

# デリバラブルと依存関係

$(PROGNAME).EXE: $(PROGNAME).OBJ
$(PROGNAME).OBJ: $(PROGNAME).C

# プログラムのコンパイル

.C.OBJ:
    $(cc) $(cdebug) $(cflags) $(cpuflags) /DNT $(cvars) $*.c

# プログラムのリンク (ブートストラップ・オブジェクトに注意)
           
.OBJ.EXE:
    $(link) $(linkdebug) $(conflags) -out:$@ $** notes0.obj $(conlibs) \
        notes.lib user32.lib

より複雑な例

もう少し大きなプログラムに取り組みましょう。今回は、シンプルな例よりも多くの Lotus C API を使用します。このプログラムは、ローカルのアドレス帳でユーザー名を検索し、会社の電話番号と住所 (設定されている場合) を返します。たのしそうなプログラムですね。いつものように、必要なヘッダー・ファイルを C ライブラリーからインクルードすることから始めます。次に、Lotus C API ライブラリーからヘッダー・ファイルをインクルードします。

#include <stdio.h>
#include <string.h>

#include <global.h>
#include <nsfdb.h>
#include <nif.h>
#include <osmem.h>
#include <miscerr.h>
#include <osmisc.h>

このプログラムでは、エラー処理用に別の関数を追加します。ここでそのプロトタイプを宣言し、main() 関数から開始します。main() 関数では、もちろん、必要なローカル変数を最初にすべて宣言します。これらの変数の目的については、プログラムをビルドするときに説明します。次に、Notes ランタイムを初期化します。

void APIErrHandler (STATUS);

int main(int argc, char *argv[])
{
	
   char			*dbname = "names.nsf";	   
   char			*viewname = "($users)";				
   char			firstname[256] = "";
   char			lastname[256] = "";
   char			key[256];
   DBHANDLE			dbhandle;           			   
   NOTEHANDLE		notehandle;
   NOTEID			viewid;          			   
   HCOLLECTION		collhandle;      			   
   COLLECTIONPOSITION	collpos;                
   HANDLE			bufferhandle;                  
   NOTEID			*nid;                       
   DWORD			count;                      
   DWORD			matches;                    
   DWORD			whichnote = 0;              
   STATUS			error = NOERROR;             
   WORD			flg;                       
   BOOL			found;                  
   char			*itemname = "";
   char			itemvalue[256];
   WORD			itemlen;


   if (error = NotesInitExtended (argc, argv))
   {
     printf("\n Unable to initialize Notes.\n");
     return (1);
   }

プログラムのコマンドラインは「lookup <firstname> <lastname>」にします。このため、コマンドラインで適切な数の引数が指定されるようにすることが必要です。

   if (argc != 3)
   {       
      printf("The syntax is: lookup <firstname> <lastname>");   
      NotesTerm();
      return (1);
   }  
   else
   {
      strcpy(firstname, argv[1]);
      strcpy(lastname, argv[2]);
      strcpy(key, firstname);      
      strcat(key, " ");
      strcat(key, lastname);
      printf("\nContact information for %s :", key);
      printf("\n--------------------------------------------");
   }

次に、アドレス帳を開き、そのハンドルを取得する必要があります。NSFDbOpen() 関数がこれを行います。

   if (error = NSFDbOpen (dbname, &dbhandle))
   {
      APIErrHandler (error);  
      NotesTerm();
      return (1);
   }

($users) の設計ノート (design note) を読み込む

データベースへのハンドルを取得した後は、NIFFindView() 関数を使用して ($users) ビューの設計ノートを取得します。NIFOpenCollection() 関数は、ビューのノートに基づいて文書コレクションへのハンドルを取得します。いずれかの操作でエラーに遭遇した場合は、データベースを閉じて終了します。

   if (error = NIFFindView (dbhandle, viewname, &viewid))
   {
      NSFDbClose (dbhandle);
      APIErrHandler (error);  
      NotesTerm();
      return (1);
   }

   if (error = NIFOpenCollection(
         dbhandle,      
         dbhandle,      
         viewid,        
         0,             
         NULLHANDLE,    
         &collhandle,   
         NULLHANDLE,    
         NULL,          
         NULLHANDLE,    
         NULLHANDLE))   
   {
      NSFDbClose (dbhandle);
      APIErrHandler (error);  
      NotesTerm();
      return (1);
   }

名前を検索する

コレクション内で、目的の名前を検索します。NIFFindByName() は、一次ソート・キー、つまりビューの最初の列 (ソート済みであること) に基づいてコレクション内を検索します。名前が見つかった場合は、渡された COLLECTIONPOSITION へのポインターにその場所が格納されます。関数がエラーに遭遇した場合は、名前が存在しないか、他の何らかのエラーが発生したものと考えられます。

   error = NIFFindByName (
           collhandle,       
           key,          
           FIND_CASE_INSENSITIVE | FIND_FIRST_EQUAL, 
           &collpos,         
           &matches);      

   if (ERR(error) == ERR_NOT_FOUND) 
   {
      printf ("\nNo such name in the address book.\n");
      NIFCloseCollection (collhandle);
      NSFDbClose (dbhandle);
      NotesTerm();
      return (0); 
   }
   
   if (error)
   {
      NIFCloseCollection (collhandle);
      NSFDbClose (dbhandle);
      APIErrHandler (error);  
      NotesTerm();
      return (1);
   }

得られた COLLECTIONPOSITION を使用し、NIFReadEntries() 関数を呼び出すことによって、目的の文書の NoteID を取得できます。この関数に渡される引数 READ_MASK_NOTEID によって、目的の文書に関する情報が指定されます。この関数は、要求された情報を bufferhandle に置きます。このバッファーへのポインターは引数として渡されます。このコンテキストで必要のない一部の引数 (count や flg など) は無視されます。しかし、バッファーに返される情報がサイズ的に問題となる場合は、NIFReadEntries() への呼び出しをループ内に組み込み、flg 引数の値をテストする必要があります。バッファーに収納しきれないデータがある場合は、flg 引数で SIGNAL_MORE_TO_DO ビットが設定されます。関数のリターン後にバッファーが NULL の場合は、プログラムを終了する必要があります。

   if (error = NIFReadEntries(
             collhandle,         
             &collpos,           
             (WORD) (NAVIGATE_CURRENT),                
             0L, 
             NAVIGATE_NEXT,       
             matches - whichnote, 
             READ_MASK_NOTEID,    
             &bufferhandle,      
             NULL,               
             NULL,               
             &count,        
             &flg))       
   {
         NIFCloseCollection (collhandle);
         NSFDbClose (dbhandle);
         APIErrHandler (error);  
         NotesTerm();
         return (1);
   }

   if (bufferhandle == NULLHANDLE)
   {
         NIFCloseCollection (collhandle);
         NSFDbClose (dbhandle);
         printf ("\nEmpty buffer returned by NIFReadEntries.\n");
         NotesTerm();
         return (0); 
   }

目的とするノートの NoteID が得られたので、これを開きます。最初に、OSLockObject() 関数を使用してメモリー内でバッファーをロックし、そのアドレスを取得します。次に、これを NOTEID としてキャストします。

   nid = (NOTEID *) OSLockObject (bufferhandle);
   
   if (error = NSFNoteOpenExt(
             dbhandle,         
             nid[0],           
             0,        
             &notehandle))       
   {
         OSUnlockObject (bufferhandle);
               OSMemFree (bufferhandle);
         NIFCloseCollection (collhandle);
         NSFDbClose (dbhandle);
         APIErrHandler (error);  
         NotesTerm();
         return (1);
   }

これで、ほとんど完成です。あとは、住所と電話番号が存在するかどうかをチェックし、存在する場合はこれらを出力します。NSFItemIsPresent() を使用してアイテムが存在するかどうかをチェックし、NSFItemGetText() を使用してアイテムの値を取得します。

   found = FALSE;	
   itemname = "MailAddress";
   found = NSFItemIsPresent (notehandle, itemname,
                                  (WORD)strlen (itemname));
   if (found)
   {
      itemlen = NSFItemGetText ( 
                            notehandle, 
                            itemname,
                            itemvalue,
                            sizeof (itemvalue));
      printf("\nMail Address: %s", itemvalue);
  }
  else
  {
      printf("\nNo Mail Address found");
  }


  found = FALSE;	
  itemname = "OfficePhoneNumber";
  found = NSFItemIsPresent (notehandle, itemname,
                                  (WORD)strlen (itemname));
  if (found)
  {
      itemlen = NSFItemGetText ( 
                            notehandle, 
                            itemname,
                            itemvalue,
                            sizeof (itemvalue));
      printf("\nOffice Phone Number: %s", itemvalue);
  }
  else
  {
      printf("\nNo Office Phone Number found");
  }

最後に、バッファーのロックを解除し、そのメモリーを解放します。そして、ノート、コレクション、およびデータベースを閉じます。

  OSUnlockObject (bufferhandle);

  OSMemFree (bufferhandle);

  if (error = NSFNoteClose (notehandle))
  {
      NIFCloseCollection(collhandle);
      NSFDbClose (dbhandle);
      APIErrHandler (error);  
      NotesTerm();
      return (1);
  }
    
  if (error = NIFCloseCollection(collhandle))
  {
      NSFDbClose (dbhandle);
      APIErrHandler (error);  
      NotesTerm();
      return (1);
  }

  if (error = NSFDbClose (dbhandle))
  {     
      APIErrHandler (error);  
      NotesTerm();
      return (1);
  }

  NotesTerm();
  return (0); 
}

パズルの最後のピースは APIErrHandler() 関数です。この関数は、渡されたエラーに対応する文字列を取得し、出力します。

void APIErrHandler (STATUS error)

{
    STATUS  errorid = ERR(error);
    char    errorstring[200];
    WORD    len;

    len = OSLoadString (NULLHANDLE,
                             errorid,
                             errorstring,
                             sizeof(errorstring));

    
    printf ("Encountered this error : %s", errorstring);
}

Lotus C API 関数の名前のパターンに気づいたでしょうか。NSF で始まる名前を持つ関数は、データベース、ノート、またはアイテムを操作します。NIF で始まる関数は、一般的に、ビューとコレクションを扱います。また、オペレーティング・システム・レベルの情報 (メモリー内でのオブジェクトのロックなど) を扱う関数は、OS で始まる名前を持っています。このような名前の付け方の規則は、実行したい内容に適した関数を探すときに特に役立ちます。

この章で記載したプログラム全体は、Sandbox からダウンロードできます。

役に立つ C API オプション

Lotus C API は、クライアント・サイドとサーバー・サイドの双方において、さまざまなコンテキストで役に立ちます。このセクションでは、利用できるいくつかのオプションについて解説します。

設計要素

Lotus C API を使用すると、エージェント、フォーム、ビュー、およびナビゲータなどの設計要素を作成したり、操作したりすることができます。設計要素を作成するときは、NOTE_CLASS_xxx 値が特に重要です。この値によって、作成するノートのタイプが識別されるためです。文書には NOTE_CLASS_DOCUMENT が使用され、フォームには NOTE_CLASS_FORM が使用されます。同様に、ビューには NOTE_CLASS_VIEW が、エージェントとマクロには NOTE_CLASS_FILTER が使用されます。たとえば、ビューの設計ノートを作成するときは、次の関数呼び出しを使用します。

WORD ClassView = NOTE_CLASS_VIEW; NSFNoteCreate(hDB, &hNote); 
NSFNoteSetInfo(hNote, _NOTE_CLASS, &ClassView); 
NSFFormulaCompile() 関数と NSFComputeEvaluate() 関数を使用して、式をコンパイルして評価することもできます。

サーバーのアドイン・タスク

サーバー上で他のタスクと同様に実行されるサーバー・タスクを作成できます。アドイン・タスクを使用して処理を実行し、実行後に終了させることも可能です。しかし、アドイン・タスクは、定期的に実行する処理のために使用することが一般的です。Lotus C API には、アドイン・タスクを構築するための特定の関数が用意されています。プログラムのメイン・エントリー・ポイントは AddInMain() 関数です。AddInIdle() 関数を使用して、プログラム内のメイン・ループを制御します。

AddInDayHasElapsed()、AddInMinutesHaveElapsed()、および AddInSecondsHaveElapsed() は、定期的な処理の実行時間を判断するために使用されます。サーバー・コンソールで load <taskname> コマンドまたは tell <taskname> quit コマンドを使用すると、アドイン・タスクを手動で起動また終了できます。サーバーの起動およびシャットダウンに合わせて、アドイン・タスクを自動的に起動およびシャットダウンするよう設定することもできます。この場合は、サーバーの Notes.ini ファイルで ServerTasks 変数にプログラム名を追加します。

[アクション] メニューのカスタム・プログラム

独自のアクションを Notes Client の [アクション] メニューに追加できます。これを行うには、エントリー・ポイントを次の形式の関数にする必要があります。

NAMRESULT LNCALLBACK FunctionName (WORD wMsg, LONG lParam)

関数には任意の名前を付けられます。この関数は、モジュール定義 (DEF) ファイルの EXPORTS 関数内で、序数の値を 1 として宣言する必要があります。最初の引数で、実行する処理を指定します。2 番目の引数は、処理に固有の情報です。処理は次の値をとることができます。

NAMM_INIT
NAMM_INITMENU
NAMM_COMMAND
NAMM_TERM

NAMM_INIT は、[アクション] メニュー項目が、現在、値を追加できることを示します。NAMM_INITMENU を使用すると、プログラムでメニュー項目を変更できます。たとえば、メニュー項目を有効または無効にするなどです。NAMM_COMMAND は、[アクション] メニュー項目が選択され、それに割り当てられている処理を実行できることを示します。NAMM_TERM は、完了のための処理 (たとえば、メモリーの解放など) を実行するタイミングを与えます。

カレンダーとスケジュール

Lotus C API には、カレンダーとスケジュールの操作を実行する機能があります。たとえば、カレンダーエントリを作成したり、空き時間を検索することができます。会議、予定、確認、およびイベントといったカレンダーエントリを作成することは、NSFNoteCreate() 関数を使用して目的のメール・データベースにノートを作成し、必要なカレンダー・アイテムをノートに追加することにあたります。

SchRetrieve() 関数を使用すると、特定の時刻におけるユーザーのスケジュールを取得できます。スケジュールを取得した後は、SchContainer_GetFirstSchedule() 関数を使用して最初のスケジュール・オブジェクトを取得します。次に、Schedule_ExtractFreeTimeRange() 関数を使用してスケジュール・オブジェクトから空き時間の範囲を取得するか、Schedule_ExtractBusyTimeRange() 関数を使用してスケジュール・オブジェクトからビジータイムの範囲を取得します。

機能の拡張 : Extension Manager

Lotus C API から提供されるサービスの 1 つとして、特に触れておきたいものがあります。それは、Extension Manager です。Extension Manager を使用すると、コールバック・ルーチンを登録することにより、Notes または Domino における特定の内部処理の実行前または実行後に、カスタム・プロセスを実行できます。このプログラムのエントリー・ポイントは、次の形式の関数にする必要があります。

STATUS LNPUBLIC FunctionName(void)
関数には任意の名前を付けられます。この関数は、モジュール定義ファイルの EXPORTS 関数内で、序数の値を 1 として宣言する必要があります。コールバック関数は、次の形式にすることが必要です。

STATUS LNPUBLIC FunctionName(EMRECORD FAR * pExRecord);
コールバック・ルーチンを登録する前に、EMCreateRecursionID() 関数を使用して再帰 ID を取得すると役立ちます。再帰 ID を使用すると、すでに呼び出されているエクステンションがもう一度呼び出されることを防止できるので、この方法が推奨されています。コールバック・ルーチンの登録には EMRegister() 関数を使用します。次の例を用いて説明するとわかりやすいでしょう。

EMRegister (
             EM_NSFDBCLOSE,
             EM_REG_BEFORE,
             (EMHANDLER)gHandlerProc,
             gRecursionID,
             &hHandler);

最初の引数 EM_NSFDBCLOSE は、コールバックを登録したい処理を示します。2 番目の引数 EM_REG_BEFORE は、処理が呼び出される直前にプログラムを実行することを示します。つまり、このプログラムは、データベースを閉じる NSFDBClose() 処理の直後に呼び出されることになります。コールバック・ルーチンを登録できる処理にはいくつかあります。また、各処理を示す値は、どれも EM_ で始まります (利用できる値の詳細ついては、API のリファレンスガイドを参照してください)。3 番目の引数は、呼び出したいカスタム関数を示します。4 番目の引数は再帰 ID で (存在する場合)、最後の引数は関数から返されたハンドルです。このハンドルは、登録を解除するときに必要となります。

プログラムの最後で、EMDeregister() 関数を使用してコールバック・ルーチンの登録を解除します。Lotus Notes/Domino 用に構築したエクステンションを指定するには、サーバーまたはクライアントの Notes.ini ファイルで EXTMGR_ADDINS 変数を使用する必要があります (どちらの Notes.ini ファイルを使用するかは、エクステンションの実行場所によります)。

カレンダープロフィールのトラップ

Extension Manager の使用例として、特定のメールファイルのカレンダープロフィールへの更新をトラップするルーチンを紹介します。このプログラムは、NSFNoteUpdateExtended() 用のコールバック・ルーチンを登録します。このコールバック・ルーチンでは、更新されるノートが目的のメールファイルであるかどうかをチェックし、さらにノートがカレンダープロフィールであるかどうかをチェックします。そうである場合は、日付と時刻のログをログファイルに出力します。プログラムのコンパイルとリンクを行った後、次の形式でこのプログラムをサーバーの Notes.ini ファイルに追加する必要があります。

EXTMGR_ADDINS=<dllname>
このプログラムの全体のコード (MAK ファイルとモジュール定義ファイルを含む) は、Sandbox からダウンロードできます。

まとめ

この記事でカバーした範囲は、Lotus C API for Lotus Notes/Domino が提供する機能の一部のサンプルにすぎません。機能の一部を説明することにより、Notes/Domino ユーザーおよび開発者にとって、この記事がツールキットを理解して活用するための一助となれば幸いです。


ダウンロード可能なリソース


関連トピック

  • developerWorks Japan: Lotus: Lotusの日本の技術情報サイトです
  • この記事で説明したプログラムは Sandbox からダウンロードできます。
  • Lotus C API toolkit for Lotus Notes/Domino は、Toolkits & Drivers ページにアクセスすることによりダウンロードできます。

コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Lotus
ArticleID=340978
ArticleTitle=Lotus Notes/Domino のための C API プログラミング
publish-date=02012005