HEADLINES

■ATOK技術情報
<ATOK12/ATOK11/ATOK10 for Windows
 AMETアプリケーション開発マニュアル>


7.Visual C++ 4.0によるAMETサーバ作成例

Visual C++ 4.0 (VC4)とAppWizardを使ってAMETサーバを作る方法について説明する。

OLEオートメーションサーバの作成方法についてはBooks Online−Visual C++ Books−Tutorials−OLE Automation Server Tutorial のAutoClikが参考になる。

ここでは実際にVC4でAMETサーバを作成し、その手順をまとめた。作成するAMETサーバ(AmetVC)はAMETの基本機能を備えたサーバである。

AmetVCはATOKから起動されると読み、表記、文節情報を表示する。エディットボックスに文字列を入力してSendボタンをクリックすると、その文字列を確定文字列としてATOKに送信し、即座に終了する。

AmetVCはVC4のAppWizardで作成する。その際、画面の設計が簡単になるので、ビュークラスにはCFormViewを使うことにした。

7−1.プロジェクトワークスペースの作成

    手順1.【ファイル−新規作成】で表示される 新規作成ダイアログボックス で プロジェクトワークスペース を選択し、[OK]ボタンをクリックする。

    手順2.新規プロジェクトワークスペースダイアログボックスが表示されるので、タイプ で MFC AppWizard (EXE) を選択し、プロジェクトワークスペース名 に AmetVC と入力して[作成]ボタンをクリックする。

    手順3.ステップ1の 作成するアプリケーションのタイプ で SDI を指定する。

    手順4.ステップ3/6の OLEサポートの選択 で、OLEオートメーション を指定する。

    手順5.ステップ4/6では、ドッキングツールバー、初期ステータスバー、印刷および印刷プレビュー のチェックをはずす。特に最初の2つがチェックされていると、起動時の表示がおかしくなってしまう。

    手順6.ステップ4/6で[高度な設定]ボタンをクリックして、高度なオプションダイアログボックスを開き、ファイルタイプIDボックスに入力されたProg IDを確認する。変更してもよいが、ここではデフォルトのAmetVC.Documentをそのまま使う。

    手順7.ステップ6/6のAppWizardで作成される新規アプリケーションクラス リストボックスで CAmetVCView を選択する。基本クラス が CView になっているので、CFormView に変更する。

    手順8.[終了]をクリックすると、新規プロジェクト情報ダイアログボックスが表示されるので、[OK]をクリックしてソースを生成する。

7−1−1.プロジェクトオプションの変更

AmetVCのプログラム中でRTTIを使用する。RTTIはデフォルトでは無効になっているので、次の手順で有効にする。

    手順1.【ビルド−設定】でプロジェクト設定ダイアログボックスを開く。

    手順2.C/C++タブ を選択し、カテゴリコンボボックスで C++言語 を選択する。

    手順3.ランタイムタイプ情報(RTTI)を行うチェックボックスをクリックし、RTTIを有効にする。

    手順4.[OK]をクリックし、ダイアログボックスを閉じる。

7−2.ダイアログの編集

プログラムのメイン画面はIDD_AMETVC_FORMで与えられるダイアログなので、これを編集する。

プロジェクトワークスペースウィンドウの Resource Viewタブ を選択し、AmetVCリソース−Dialog−IDD_AMETVC_FORM をダブルクリックしてダイアログエディタを起動する。

ダイアログを図2.のように変更する。

図2.AmetVCのダイアログ

それぞれのコントロールのプロパティは次のように設定する。
種類 ID キャプション その他
Static IDC_AMETYOMI Yomi Border
Static IDC_AMETHYOKI Hyoki Border
Static IDC_AMETBYOMI BYomi Border
Static IDC_AMETBHYOKI BHyoki Border
Edit IDC_AMETRESULT    
Button IDC_SENDRESULT Send  

編集が終われば、ダイアログエディタを終了する。

7−3.プロパティ、メソッドの作成

AmetVCは、AMETサーバが持つことのできるすべてのプロパティとメソッドを実装する。

【表示−ClassWizard】を実行し、OLEオートメーションタブ を選択する。クラス名 でCAmetVCDoc クラスを選択すると、[メソッドの追加]、[プロパティの追加]ボタンが有効になる。

7−3−1.プロパティの追加

AmetYomiプロパティを追加するときは次のようにする。プロパティの インプリメント には メンバ変数 と 取得/設定メソッド の2種類を指定できるが、AmetVCではすべてのプロパティを メンバ変数 として実装する。

    手順1.[プロパティの追加]ボタンをクリックしてプロパティの追加ダイアログボックスを開く。

    手順2.外部名 に AmetYomi と入力する。

    手順3.タイプ に CString を指定する。

    手順4.他はデフォルトのままにする。

    手順5.[OK]ボタンをクリックする。

同様に残りのプロパティも追加する。プロパティの属性は次のようになる。
外部名 タイプ 変数名 通知関数
AmetYomi CString m_ametYomi OnAmetYomiChanged
AmetHyoki CString m_ametHyoki OnAmetHyokiChanged
AmetResult CString m_ametResult OnAmetResultChanged
AmetQuit long m_ametQuit OnAmetQuitChanged
AmetBYomiLen long m_ametBYomiLen OnAmetBYomiLenChanged
AmetBHyokiLen long m_ametBHyokiLen OnAmetBHyokiLenChanged

7−3−2.メソッドの追加

AmetStartプロパティを追加するときは次のようにする。

    手順1.[メソッドの追加]ボタンをクリックしてメソッドの追加ダイアログボックスを開く。

    手順2.外部名 に AmetStart と入力する。

    手順3.内部名に AmetStart と入力されるので、そのままにする。

    手順4.戻り値の型に void を指定する。

    手順5.パラメータリスト で引数を指定する。
    a.変数名 の下でクリックすると、引数名を入力できるようになるので、hWnd と入力する。
    b.タイプ の下でクリックして、引数の型を long にする。

    手順6.[OK]ボタンをクリックする。

同様に残りのメソッドも追加する。メソッドの属性は次のようになる。
外部名 内部名 戻り値の型 パラメータリスト
変数名 タイプ
AmetStart AmetStart void hWnd long
AmetSetBYomi AmetSetBYomi void idx long
data long
AmetSetBHyoki AmetSetBHyoki void idx long
data long

7−4.ドキュメントクラスの編集

メソッドの追加が完了したところでClassWizardの[コード編集]をクリックし、ソースの編集画面を表示する。

7−4−1.メンバ変数の追加

最初にClass Wizardで自動的に追加されないメンバ変数を追加する。

m_hAtokWindowを追加するときの手順を次に示す。その前にプロジェクトウィンドウのClass Viewタブをクリックして表示を切り換える。

    手順1.プロジェクトウィンドウの AmetVCクラス−CAmetVCDoc を選択する。

    手順2.マウスの右ボタンを押して表示されるメニューから【変数の追加】を選択するとメンバ変数の追加ダイアログが表示される。

    手順3.変数の型 に HWND と入力する。

    手順4.変数宣言 に m_hAtokWindow と入力する。

    手順5.アクセス は Private を指定する。

    手順6.[OK]をクリックする。

同様に次に示すメンバ変数を追加する。
変数の型 変数宣言 アクセス 説明
HWND m_hAtokWindow Private ATOKウィンドウ
long m_AmetBYomi[100] Private 読み文節情報
long m_AmetBHyoki[100] Private 表記文節情報

7−4−2.メンバ関数の追加

Class Wizardで自動的に追加されないメンバ関数を追加する。

通常のメンバ関数 AmetNotify() を追加するときの手順を次に示す。

    手順1.プロジェクトウィンドウの AmetVCクラス−CAmetVCDoc を選択する。

    手順2.マウスの右ボタンを押して表示されるメニューから【関数の追加】を選択するとメンバ関数の追加ダイアログが表示される。

    手順3.関数型 に void と入力する。

    手順4.関数宣言に AmetNotify(void) と入力する。

    手順5.アクセス は Public を指定する。

    手順6.[OK]をクリックする。

inlineメンバ関数を追加するときは、直接ヘッダーファイルを編集する。その手順を次に示す。
    手順7.プロジェクトウィンドウの AmetVCクラス−CAmetVCDoc を選択する。

    手順8.マウスの右ボタンを押して表示されるメニューから【定義の表示】を選択すると、CAmetVCDocのヘッダーファイルが表示される。

    手順9.CAmetVCDocのクラス定義の最初の部分に 『//アトリビュート』という行があるので、その行以降を次のように変更する。
    先頭に 『 > 』のついた行を追加する。

// アトリビュート
public:
  void AmetNotify(void);
>  CString GetYomi(void) const   {return(m_ametYomi);}
>  CString GetHyoki(void) const  {return(m_ametHyoki);}
>  void  SetResult(const CString str)  {m_ametResult = str;}
>  long  GetYomiLen(void) const {return(m_ametBYomiLen);}
>  long  GetHyokiLen(void) const {return(m_ametBHyokiLen);}
>  long  GetBYomi(int idx) const {return(m_AmetBYomi[idx]);}
>  long  GetBHyoki(int idx) const  {return(m_AmetBHyoki[idx]);}

追加が終われば、ヘッダーファイルを保存する。

ここで追加したメンバ関数について以下にまとめる。
関数型 関数宣言 アクセス 説明
void AmetNotify(void) Pub ATOKにメッセージを送る
CString GetYomi(void) Pub 読み情報の取得
CString GetHyoki(void) Pub 表記情報の取得
void SetResult(const CString str) Pub 確定情報の設定
long GetYomiLen(void) Pub 読み文節情報長取得
long GetHyokiLen(void) Pub 表記文節情報長取得
long GetBYomi(int idx) Pub 読み文節情報取得
long GetBHyoki(int idx) Pub 表記文節情報取得

7−4−3.メンバ関数の編集

追加したメンバ関数を編集する。以下の説明では先頭に『 > 』をつけた行を追加する。以下で説明していないメンバ関数はClassWizardが生成したままで変更しない。

※関数の定義場所への移動方法について

関数を編集するとき、関数の定義されている場所に移動するには、ソースファイル上で捜す以外に、次のような方法もある。

プロジェクトウィンドウで AmetVCクラス−CAmetVCDoc−AmetNotify() をダブルクリックすると、ソースファイルのAmetNotify()が定義されているところに移動することができる。

7−4−4.コンストラクタ

CAmetVCDoc()は、追加したプロパティに関連したメンバ変数とメンバ変数の初期化をするように変更する。
CAmetVCDoc::CAmetVCDoc()
{
>  m_ametYomi = "";
>  m_ametHyoki = "";
>  m_ametResult = "";
>  m_hAtokWindow = 0;
>  m_ametQuit = FALSE;
>  m_ametBYomiLen = 0L;
>  m_ametBHyokiLen = 0L;
>  int i;
>  for(i = 0; i < 100; i++) m_AmetBYomi[i] = 0L;
>  for(i = 0; i < 100; i++) m_AmetBHyoki[i] = 0L;

  EnableAutomation();

  AfxOleLockApp();
}

7−4−5.AmetStart()

AmetStart()では次の処理を追加する。

・引数として渡されたATOKウィンドウのハンドルを保存する。
・ウィンドウを表示する。
・フレームウィンドウのサイズを調整する。
void CAmetVCDoc::AmetStart(long hWnd)
{
>  m_hAtokWindow = (HWND)hWnd;
>  // ウィンドウの表示
>  POSITION  pos = GetFirstViewPosition();
>  CScrollView*  pView = dynamic_cast<CScrollView*>(GetNextView(pos));
>  if(pView != NULL)
>  {
>    CFrameWnd*  pFrameWnd = pView->GetParentFrame();
>    pFrameWnd->ActivateFrame(SW_SHOW);
>    // フレームウィンドウの大きさを調整する
>    // OLEオートメーションで起動されたときだけ有効
>    pView->ResizeParentToFit();
>  }
}

※ウィンドウの表示について

    VC4 + AppWizardで作成したOLEオートメーションサーバは、オートメーションサーバとして起動されたときはウィンドウを表示しないため、自分で表示しなければならない。AMETサーバではAmetStart()がウィンドウの表示をするタイミングとして適切なので、ここでウィンドウの表示をする。
※フレームウィンドウのサイズ調整
    AmetVCはCFormViewクラスの派生クラスをビューとして使っている。このクラスはダイアログをフレームウィンドウのクライアントウィンドウとして使うため、フレームウィンドウのサイズをダイアログのサイズに合せなければならない。

    単独のプログラムの場合は、ビュークラスのOnInitialUpdate()でサイズ調整をするが、OLEオートメーションではその設定が反映されないため、ウィンドウの表示処理と同時にフレームウィンドウのサイズ調整もすることにした。

7−4−6.AmetSetBYomi()、AmetSetBHyoki()

これらの関数は、次のように実装する。
void CAmetVCDoc::AmetSetBYomi(long idx, long data)
{
>  if(idx < 100)  m_AmetBYomi[idx] = data;
}

void CAmetVCDoc::AmetSetBHyoki(long idx, long data)
{
>  if(idx < 100)  m_AmetBHyoki[idx] = data;
}

7−4−7.AmetNotify()

ATOKにWM_AMET_NOTIFYメッセージを送信するための関数。AmetQuitをTRUEにしているので、このメッセージを送ったあとATOKはAmetVCを終了させる。
>const  int    WM_AMET_NOTIFY = WM_USER + 100;

void CAmetDVDoc::AmetNotify(void)
{
>  if(m_hAtokWindow != 0)
>  {
>    m_ametQuit = TRUE;
>    ::PostMessage(m_hAtokWindow, WM_AMET_NOTIFY, 0, 0);
>  }
}

7−5.ビュークラスの編集

ビュークラスはイベントに対応する処理などを追加する。

7−5−1.オーバーライドメンバ関数の追加

上位のクラスで定義されているメンバ関数をオーバーライドする。一例として、OnDraw()を定義する手順を次に示す。

    手順1.ClassWizardを起動し、メッセージマップタブを選択する。

    手順2.クラス名 で CAmetVCView を選択する。

    手順3.オブジェクトIDリストボックスで CAmetVCView を選択する。

    手順4.メッセージリストボックスで OnDrawを選択する。

    手順5.[関数の追加]ボタンをクリックすると、OnDraw()の雛形が生成される。

同様に次に示すオーバーライドメンバ関数を追加する。
名前 説明
OnDraw ビューの再表示。
OnInitialUpdate ビューを最初に表示するときの処理。

7−5−2.イベントハンドラの追加

ボタンが押されたときのイベントハンドラ関数を追加するには、次の手順で行う。

    手順1.ClassWizardを起動し、メッセージマップタブを選択する。

    手順2.クラス名 で CAmetVCView を選択する。

    手順3.オブジェクトIDリストボックスで IDC_SENDRESULT を選択する。

    手順4.メッセージリストボックスで BN_CLICKED を選択する。

    手順5.[関数の追加]ボタンをクリックすると、イベントハンドラ関数の名前を尋ねてくるので、デフォルトの名前(OnSendResult)を変更せずにOKをクリックする。

7−6.メンバ関数の編集

追加したメンバ関数を編集する。以下の説明では先頭に『 > 』をつけた行を追加する。

7−6−1.OnDraw

OnDraw()は、ビューが表示されるときに呼び出される。AMETの呼び出し時に設定された情報をドキュメントから取得してコントロールに表示する。
void CAmetVCView::OnDraw(CDC* pDC)
{
>  CAmetVCDoc*  pDoc = GetDocument();
>  SetDlgItemText(IDC_AMETYOMI, pDoc->GetYomi());
>  SetDlgItemText(IDC_AMETHYOKI, pDoc->GetHyoki());
>  char buf[50];
>  ::wsprintf(buf, "%2d: %2d, %2d, %2d", pDoc->GetYomiLen(),
>    pDoc->GetBYomi(0), pDoc->GetBYomi(1), pDoc->GetBYomi(2));
>  SetDlgItemText(IDC_AMETBYOMI, buf);
>  ::wsprintf(buf, "%2d: %2d, %2d, %2d", pDoc->GetHyokiLen(),
>    pDoc->GetBHyoki(0), pDoc->GetBHyoki(1), pDoc->GetBHyoki(2));
>  SetDlgItemText(IDC_AMETBHYOKI, buf);
}

7−6−2.OnInitalUpdate

CFormViewクラスのウィンドウを表示するとき、自動的にウィンドウのサイズをダイアログのサイズに合せることができる。そのためにOnInitialUpdate()ハンドラを追加する。

この関数は、AmetVCを単独で起動したときに有効であり、ATOKからOLEオートメーションで呼ばれたときは、ここの設定は反映されない。
void CAmetVCView::OnInitialUpdate()
{
  CFormView::OnInitialUpdate();

>  ResizeParentToFit();
}

7−6−3.OnSendResult

Sendボタンが押されたとき、エディットボックスに入力された文字列をATOKに送る処理を追加する。
void CAmetVCView::OnSendresult()
{
>  CString str;
>  GetDlgItemText(IDC_AMETRESULT, str);
>  CAmetVCDoc* pDoc = GetDocument();
>  pDoc->SetResult(str);
>  pDoc->AmetNotify();
}

7−7.ビルドと実行テスト

動作確認とレジストリに登録するため、ビルドして実行する。図2.のような画面が表示されればとりあえずは正常に動作している。
実行形を別のフォルダへ移す場合は、再度レジストリに登録する必要がある。

7−7−1.ProgIDについて

VC4で作成したOLEサーバのProgIDは、AppWizardのステップ4/6で[高度な設定]ボタンを押して開いた ファイルタイプID ボックスに入力された文字列が使われる。AmetVCの場合のProgIDはAmetVC.Documentである。

7−8.ATOKとの連携テスト

ATOKから呼び出せるようにするためにATOKのINIファイル(*6)に次のように登録し、再起動させる。
[AMET2]
名称=AmetVCサーバ
ID=AmetVC.Document
未入力起動=しない

メモ帳などでATOKを起動し、未確定文字列のある状態でShift + F10キーを押してメニューを表示し、AMETメニューを起動する。そこから2番のAMETを選択するとAmetVCが起動し、読みと表記が表示される。エディットボックスに任意の文字列を入力してSendボタンをクリックすると、その文字列が確定文字列としてアプリケーションに送信され、AmetVCは終了する。

    (*6)ATOK12の場合…ATOK12W.INI
      ATOK11の場合…ATOK11W.INI
      ATOK10の場合…ATOK10W.INI

以上


前ページ目 次



return



to topmenu

update 1998.12.2